iterator_wrapper.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  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. #pragma once
  10. #include <set>
  11. #include "table/internal_iterator.h"
  12. #include "test_util/sync_point.h"
  13. namespace ROCKSDB_NAMESPACE {
  14. // A internal wrapper class with an interface similar to Iterator that caches
  15. // the valid() and key() results for an underlying iterator.
  16. // This can help avoid virtual function calls and also gives better
  17. // cache locality.
  18. template <class TValue = Slice>
  19. class IteratorWrapperBase {
  20. public:
  21. IteratorWrapperBase() : iter_(nullptr), valid_(false) {}
  22. explicit IteratorWrapperBase(InternalIteratorBase<TValue>* _iter)
  23. : iter_(nullptr) {
  24. Set(_iter);
  25. }
  26. ~IteratorWrapperBase() {}
  27. InternalIteratorBase<TValue>* iter() const { return iter_; }
  28. void SetRangeDelReadSeqno(SequenceNumber read_seqno) {
  29. if (iter_) {
  30. iter_->SetRangeDelReadSeqno(read_seqno);
  31. }
  32. }
  33. // Set the underlying Iterator to _iter and return
  34. // previous underlying Iterator.
  35. InternalIteratorBase<TValue>* Set(InternalIteratorBase<TValue>* _iter) {
  36. InternalIteratorBase<TValue>* old_iter = iter_;
  37. iter_ = _iter;
  38. if (iter_ == nullptr) {
  39. valid_ = false;
  40. } else {
  41. Update();
  42. }
  43. return old_iter;
  44. }
  45. void DeleteIter(bool is_arena_mode) {
  46. if (iter_) {
  47. #ifdef ROCKSDB_ASSERT_STATUS_CHECKED
  48. if (!status_checked_after_invalid_) {
  49. // If this assertion fails, it is likely that you did not check
  50. // iterator status after Valid() returns false.
  51. fprintf(stderr,
  52. "Failed to check status after Valid() returned false from this "
  53. "iterator.\n");
  54. port::PrintStack();
  55. std::abort();
  56. }
  57. #endif
  58. if (!is_arena_mode) {
  59. delete iter_;
  60. } else {
  61. iter_->~InternalIteratorBase<TValue>();
  62. }
  63. }
  64. }
  65. // Iterator interface methods
  66. bool Valid() const {
  67. #ifdef ROCKSDB_ASSERT_STATUS_CHECKED
  68. status_checked_after_invalid_ = valid_;
  69. #endif
  70. return valid_;
  71. }
  72. Slice key() const {
  73. assert(Valid());
  74. return result_.key;
  75. }
  76. uint64_t write_unix_time() const {
  77. assert(Valid());
  78. return iter_->write_unix_time();
  79. }
  80. TValue value() const {
  81. assert(Valid());
  82. return iter_->value();
  83. }
  84. // Methods below require iter() != nullptr
  85. Status status() const {
  86. #ifdef ROCKSDB_ASSERT_STATUS_CHECKED
  87. status_checked_after_invalid_ = true;
  88. #endif
  89. assert(iter_);
  90. return iter_->status();
  91. }
  92. bool PrepareValue() {
  93. assert(Valid());
  94. if (result_.value_prepared) {
  95. return true;
  96. }
  97. if (iter_->PrepareValue()) {
  98. result_.value_prepared = true;
  99. result_.key = iter_->key();
  100. return true;
  101. }
  102. assert(!iter_->Valid());
  103. valid_ = false;
  104. return false;
  105. }
  106. void Next() {
  107. assert(iter_);
  108. valid_ = iter_->NextAndGetResult(&result_);
  109. assert(!valid_ || iter_->status().ok());
  110. }
  111. bool NextAndGetResult(IterateResult* result) {
  112. assert(iter_);
  113. valid_ = iter_->NextAndGetResult(&result_);
  114. *result = result_;
  115. assert(!valid_ || iter_->status().ok());
  116. return valid_;
  117. }
  118. void Prev() {
  119. assert(iter_);
  120. iter_->Prev();
  121. Update();
  122. }
  123. void Seek(const Slice& k) {
  124. assert(iter_);
  125. iter_->Seek(k);
  126. Update();
  127. }
  128. void SeekForPrev(const Slice& k) {
  129. assert(iter_);
  130. iter_->SeekForPrev(k);
  131. Update();
  132. }
  133. void SeekToFirst() {
  134. assert(iter_);
  135. iter_->SeekToFirst();
  136. Update();
  137. }
  138. void SeekToLast() {
  139. assert(iter_);
  140. iter_->SeekToLast();
  141. Update();
  142. }
  143. bool MayBeOutOfLowerBound() {
  144. assert(Valid());
  145. return iter_->MayBeOutOfLowerBound();
  146. }
  147. IterBoundCheck UpperBoundCheckResult() {
  148. assert(Valid());
  149. return result_.bound_check_result;
  150. }
  151. void SetPinnedItersMgr(PinnedIteratorsManager* pinned_iters_mgr) {
  152. assert(iter_);
  153. iter_->SetPinnedItersMgr(pinned_iters_mgr);
  154. }
  155. bool IsKeyPinned() const {
  156. assert(Valid());
  157. return iter_->IsKeyPinned();
  158. }
  159. bool IsValuePinned() const {
  160. assert(Valid());
  161. return iter_->IsValuePinned();
  162. }
  163. bool IsValuePrepared() const { return result_.value_prepared; }
  164. Slice user_key() const {
  165. assert(Valid());
  166. return iter_->user_key();
  167. }
  168. void UpdateReadaheadState(InternalIteratorBase<TValue>* old_iter) {
  169. if (old_iter && iter_) {
  170. ReadaheadFileInfo readahead_file_info;
  171. old_iter->GetReadaheadState(&readahead_file_info);
  172. iter_->SetReadaheadState(&readahead_file_info);
  173. }
  174. }
  175. bool IsDeleteRangeSentinelKey() const {
  176. return iter_->IsDeleteRangeSentinelKey();
  177. }
  178. // scan_opts lifetime is guaranteed until the iterator is destructed, or
  179. // Prepare() is called with a new scan_opts
  180. void Prepare(const MultiScanArgs* scan_opts) {
  181. if (iter_) {
  182. iter_->Prepare(scan_opts);
  183. }
  184. }
  185. private:
  186. void Update() {
  187. valid_ = iter_->Valid();
  188. if (valid_) {
  189. assert(iter_->status().ok());
  190. result_.key = iter_->key();
  191. result_.bound_check_result = IterBoundCheck::kUnknown;
  192. result_.value_prepared = false;
  193. }
  194. }
  195. InternalIteratorBase<TValue>* iter_;
  196. IterateResult result_;
  197. bool valid_;
  198. #ifdef ROCKSDB_ASSERT_STATUS_CHECKED
  199. mutable bool status_checked_after_invalid_ = true;
  200. #endif
  201. };
  202. using IteratorWrapper = IteratorWrapperBase<Slice>;
  203. class Arena;
  204. // Return an empty iterator (yields nothing) allocated from arena.
  205. template <class TValue = Slice>
  206. InternalIteratorBase<TValue>* NewEmptyInternalIterator(Arena* arena);
  207. } // namespace ROCKSDB_NAMESPACE