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 10 #pragma once 11 12 #include <set> 13 14 #include "table/internal_iterator.h" 15 #include "test_util/sync_point.h" 16 17 namespace ROCKSDB_NAMESPACE { 18 19 // A internal wrapper class with an interface similar to Iterator that caches 20 // the valid() and key() results for an underlying iterator. 21 // This can help avoid virtual function calls and also gives better 22 // cache locality. 23 template <class TValue = Slice> 24 class IteratorWrapperBase { 25 public: IteratorWrapperBase()26 IteratorWrapperBase() : iter_(nullptr), valid_(false) {} IteratorWrapperBase(InternalIteratorBase<TValue> * _iter)27 explicit IteratorWrapperBase(InternalIteratorBase<TValue>* _iter) 28 : iter_(nullptr) { 29 Set(_iter); 30 } ~IteratorWrapperBase()31 ~IteratorWrapperBase() {} iter()32 InternalIteratorBase<TValue>* iter() const { return iter_; } 33 34 // Set the underlying Iterator to _iter and return 35 // previous underlying Iterator. Set(InternalIteratorBase<TValue> * _iter)36 InternalIteratorBase<TValue>* Set(InternalIteratorBase<TValue>* _iter) { 37 InternalIteratorBase<TValue>* old_iter = iter_; 38 39 iter_ = _iter; 40 if (iter_ == nullptr) { 41 valid_ = false; 42 } else { 43 Update(); 44 } 45 return old_iter; 46 } 47 DeleteIter(bool is_arena_mode)48 void DeleteIter(bool is_arena_mode) { 49 if (iter_) { 50 if (!is_arena_mode) { 51 delete iter_; 52 } else { 53 iter_->~InternalIteratorBase<TValue>(); 54 } 55 } 56 } 57 58 // Iterator interface methods Valid()59 bool Valid() const { return valid_; } key()60 Slice key() const { 61 assert(Valid()); 62 return result_.key; 63 } value()64 TValue value() const { 65 assert(Valid()); 66 return iter_->value(); 67 } 68 // Methods below require iter() != nullptr status()69 Status status() const { 70 assert(iter_); 71 return iter_->status(); 72 } Next()73 void Next() { 74 assert(iter_); 75 valid_ = iter_->NextAndGetResult(&result_); 76 assert(!valid_ || iter_->status().ok()); 77 } Prev()78 void Prev() { 79 assert(iter_); 80 iter_->Prev(); 81 Update(); 82 } Seek(const Slice & k)83 void Seek(const Slice& k) { 84 assert(iter_); 85 iter_->Seek(k); 86 Update(); 87 } SeekForPrev(const Slice & k)88 void SeekForPrev(const Slice& k) { 89 assert(iter_); 90 iter_->SeekForPrev(k); 91 Update(); 92 } SeekToFirst()93 void SeekToFirst() { 94 assert(iter_); 95 iter_->SeekToFirst(); 96 Update(); 97 } SeekToLast()98 void SeekToLast() { 99 assert(iter_); 100 iter_->SeekToLast(); 101 Update(); 102 } 103 MayBeOutOfLowerBound()104 bool MayBeOutOfLowerBound() { 105 assert(Valid()); 106 return iter_->MayBeOutOfLowerBound(); 107 } 108 MayBeOutOfUpperBound()109 bool MayBeOutOfUpperBound() { 110 assert(Valid()); 111 return result_.may_be_out_of_upper_bound; 112 } 113 SetPinnedItersMgr(PinnedIteratorsManager * pinned_iters_mgr)114 void SetPinnedItersMgr(PinnedIteratorsManager* pinned_iters_mgr) { 115 assert(iter_); 116 iter_->SetPinnedItersMgr(pinned_iters_mgr); 117 } IsKeyPinned()118 bool IsKeyPinned() const { 119 assert(Valid()); 120 return iter_->IsKeyPinned(); 121 } IsValuePinned()122 bool IsValuePinned() const { 123 assert(Valid()); 124 return iter_->IsValuePinned(); 125 } 126 127 private: Update()128 void Update() { 129 valid_ = iter_->Valid(); 130 if (valid_) { 131 assert(iter_->status().ok()); 132 result_.key = iter_->key(); 133 result_.may_be_out_of_upper_bound = true; 134 } 135 } 136 137 InternalIteratorBase<TValue>* iter_; 138 IterateResult result_; 139 bool valid_; 140 }; 141 142 using IteratorWrapper = IteratorWrapperBase<Slice>; 143 144 class Arena; 145 // Return an empty iterator (yields nothing) allocated from arena. 146 template <class TValue = Slice> 147 extern InternalIteratorBase<TValue>* NewEmptyInternalIterator(Arena* arena); 148 149 } // namespace ROCKSDB_NAMESPACE 150