two_level_iterator.cc 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. //
  6. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  7. // Use of this source code is governed by a BSD-style license that can be
  8. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  9. #include "table/two_level_iterator.h"
  10. #include "db/pinned_iterators_manager.h"
  11. #include "memory/arena.h"
  12. #include "rocksdb/options.h"
  13. #include "rocksdb/table.h"
  14. #include "table/block_based/block.h"
  15. #include "table/format.h"
  16. namespace ROCKSDB_NAMESPACE {
  17. namespace {
  18. class TwoLevelIndexIterator : public InternalIteratorBase<IndexValue> {
  19. public:
  20. explicit TwoLevelIndexIterator(
  21. TwoLevelIteratorState* state,
  22. InternalIteratorBase<IndexValue>* first_level_iter);
  23. ~TwoLevelIndexIterator() override {
  24. first_level_iter_.DeleteIter(false /* is_arena_mode */);
  25. second_level_iter_.DeleteIter(false /* is_arena_mode */);
  26. delete state_;
  27. }
  28. void Seek(const Slice& target) override;
  29. void SeekForPrev(const Slice& target) override;
  30. void SeekToFirst() override;
  31. void SeekToLast() override;
  32. void Next() override;
  33. void Prev() override;
  34. bool Valid() const override { return second_level_iter_.Valid(); }
  35. Slice key() const override {
  36. assert(Valid());
  37. return second_level_iter_.key();
  38. }
  39. IndexValue value() const override {
  40. assert(Valid());
  41. return second_level_iter_.value();
  42. }
  43. Status status() const override {
  44. if (!first_level_iter_.status().ok()) {
  45. assert(second_level_iter_.iter() == nullptr);
  46. return first_level_iter_.status();
  47. } else if (second_level_iter_.iter() != nullptr &&
  48. !second_level_iter_.status().ok()) {
  49. return second_level_iter_.status();
  50. } else {
  51. return status_;
  52. }
  53. }
  54. void SetPinnedItersMgr(
  55. PinnedIteratorsManager* /*pinned_iters_mgr*/) override {}
  56. bool IsKeyPinned() const override { return false; }
  57. bool IsValuePinned() const override { return false; }
  58. private:
  59. void SaveError(const Status& s) {
  60. if (status_.ok() && !s.ok()) status_ = s;
  61. }
  62. void SkipEmptyDataBlocksForward();
  63. void SkipEmptyDataBlocksBackward();
  64. void SetSecondLevelIterator(InternalIteratorBase<IndexValue>* iter);
  65. void InitDataBlock();
  66. TwoLevelIteratorState* state_;
  67. IteratorWrapperBase<IndexValue> first_level_iter_;
  68. IteratorWrapperBase<IndexValue> second_level_iter_; // May be nullptr
  69. Status status_;
  70. // If second_level_iter is non-nullptr, then "data_block_handle_" holds the
  71. // "index_value" passed to block_function_ to create the second_level_iter.
  72. BlockHandle data_block_handle_;
  73. };
  74. TwoLevelIndexIterator::TwoLevelIndexIterator(
  75. TwoLevelIteratorState* state,
  76. InternalIteratorBase<IndexValue>* first_level_iter)
  77. : state_(state), first_level_iter_(first_level_iter) {}
  78. void TwoLevelIndexIterator::Seek(const Slice& target) {
  79. first_level_iter_.Seek(target);
  80. InitDataBlock();
  81. if (second_level_iter_.iter() != nullptr) {
  82. second_level_iter_.Seek(target);
  83. }
  84. SkipEmptyDataBlocksForward();
  85. }
  86. void TwoLevelIndexIterator::SeekForPrev(const Slice& target) {
  87. first_level_iter_.Seek(target);
  88. InitDataBlock();
  89. if (second_level_iter_.iter() != nullptr) {
  90. second_level_iter_.SeekForPrev(target);
  91. }
  92. if (!Valid()) {
  93. if (!first_level_iter_.Valid() && first_level_iter_.status().ok()) {
  94. first_level_iter_.SeekToLast();
  95. InitDataBlock();
  96. if (second_level_iter_.iter() != nullptr) {
  97. second_level_iter_.SeekForPrev(target);
  98. }
  99. }
  100. SkipEmptyDataBlocksBackward();
  101. }
  102. }
  103. void TwoLevelIndexIterator::SeekToFirst() {
  104. first_level_iter_.SeekToFirst();
  105. InitDataBlock();
  106. if (second_level_iter_.iter() != nullptr) {
  107. second_level_iter_.SeekToFirst();
  108. }
  109. SkipEmptyDataBlocksForward();
  110. }
  111. void TwoLevelIndexIterator::SeekToLast() {
  112. first_level_iter_.SeekToLast();
  113. InitDataBlock();
  114. if (second_level_iter_.iter() != nullptr) {
  115. second_level_iter_.SeekToLast();
  116. }
  117. SkipEmptyDataBlocksBackward();
  118. }
  119. void TwoLevelIndexIterator::Next() {
  120. assert(Valid());
  121. second_level_iter_.Next();
  122. SkipEmptyDataBlocksForward();
  123. }
  124. void TwoLevelIndexIterator::Prev() {
  125. assert(Valid());
  126. second_level_iter_.Prev();
  127. SkipEmptyDataBlocksBackward();
  128. }
  129. void TwoLevelIndexIterator::SkipEmptyDataBlocksForward() {
  130. while (second_level_iter_.iter() == nullptr ||
  131. (!second_level_iter_.Valid() && second_level_iter_.status().ok())) {
  132. // Move to next block
  133. if (!first_level_iter_.Valid()) {
  134. SetSecondLevelIterator(nullptr);
  135. return;
  136. }
  137. first_level_iter_.Next();
  138. InitDataBlock();
  139. if (second_level_iter_.iter() != nullptr) {
  140. second_level_iter_.SeekToFirst();
  141. }
  142. }
  143. }
  144. void TwoLevelIndexIterator::SkipEmptyDataBlocksBackward() {
  145. while (second_level_iter_.iter() == nullptr ||
  146. (!second_level_iter_.Valid() && second_level_iter_.status().ok())) {
  147. // Move to next block
  148. if (!first_level_iter_.Valid()) {
  149. SetSecondLevelIterator(nullptr);
  150. return;
  151. }
  152. first_level_iter_.Prev();
  153. InitDataBlock();
  154. if (second_level_iter_.iter() != nullptr) {
  155. second_level_iter_.SeekToLast();
  156. }
  157. }
  158. }
  159. void TwoLevelIndexIterator::SetSecondLevelIterator(
  160. InternalIteratorBase<IndexValue>* iter) {
  161. InternalIteratorBase<IndexValue>* old_iter = second_level_iter_.Set(iter);
  162. delete old_iter;
  163. }
  164. void TwoLevelIndexIterator::InitDataBlock() {
  165. if (!first_level_iter_.Valid()) {
  166. SetSecondLevelIterator(nullptr);
  167. } else {
  168. BlockHandle handle = first_level_iter_.value().handle;
  169. if (second_level_iter_.iter() != nullptr &&
  170. !second_level_iter_.status().IsIncomplete() &&
  171. handle.offset() == data_block_handle_.offset()) {
  172. // second_level_iter is already constructed with this iterator, so
  173. // no need to change anything
  174. } else {
  175. InternalIteratorBase<IndexValue>* iter =
  176. state_->NewSecondaryIterator(handle);
  177. data_block_handle_ = handle;
  178. SetSecondLevelIterator(iter);
  179. }
  180. }
  181. }
  182. } // namespace
  183. InternalIteratorBase<IndexValue>* NewTwoLevelIterator(
  184. TwoLevelIteratorState* state,
  185. InternalIteratorBase<IndexValue>* first_level_iter) {
  186. return new TwoLevelIndexIterator(state, first_level_iter);
  187. }
  188. } // namespace ROCKSDB_NAMESPACE