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 } PrepareValue()73 bool PrepareValue() { 74 assert(Valid()); 75 if (result_.value_prepared) { 76 return true; 77 } 78 if (iter_->PrepareValue()) { 79 result_.value_prepared = true; 80 return true; 81 } 82 83 assert(!iter_->Valid()); 84 valid_ = false; 85 return false; 86 } Next()87 void Next() { 88 assert(iter_); 89 valid_ = iter_->NextAndGetResult(&result_); 90 assert(!valid_ || iter_->status().ok()); 91 } NextAndGetResult(IterateResult * result)92 bool NextAndGetResult(IterateResult* result) { 93 assert(iter_); 94 valid_ = iter_->NextAndGetResult(&result_); 95 *result = result_; 96 assert(!valid_ || iter_->status().ok()); 97 return valid_; 98 } Prev()99 void Prev() { 100 assert(iter_); 101 iter_->Prev(); 102 Update(); 103 } Seek(const Slice & k)104 void Seek(const Slice& k) { 105 assert(iter_); 106 iter_->Seek(k); 107 Update(); 108 } SeekForPrev(const Slice & k)109 void SeekForPrev(const Slice& k) { 110 assert(iter_); 111 iter_->SeekForPrev(k); 112 Update(); 113 } SeekToFirst()114 void SeekToFirst() { 115 assert(iter_); 116 iter_->SeekToFirst(); 117 Update(); 118 } SeekToLast()119 void SeekToLast() { 120 assert(iter_); 121 iter_->SeekToLast(); 122 Update(); 123 } 124 MayBeOutOfLowerBound()125 bool MayBeOutOfLowerBound() { 126 assert(Valid()); 127 return iter_->MayBeOutOfLowerBound(); 128 } 129 UpperBoundCheckResult()130 IterBoundCheck UpperBoundCheckResult() { 131 assert(Valid()); 132 return result_.bound_check_result; 133 } 134 SetPinnedItersMgr(PinnedIteratorsManager * pinned_iters_mgr)135 void SetPinnedItersMgr(PinnedIteratorsManager* pinned_iters_mgr) { 136 assert(iter_); 137 iter_->SetPinnedItersMgr(pinned_iters_mgr); 138 } IsKeyPinned()139 bool IsKeyPinned() const { 140 assert(Valid()); 141 return iter_->IsKeyPinned(); 142 } IsValuePinned()143 bool IsValuePinned() const { 144 assert(Valid()); 145 return iter_->IsValuePinned(); 146 } 147 IsValuePrepared()148 bool IsValuePrepared() const { 149 return result_.value_prepared; 150 } 151 user_key()152 Slice user_key() const { 153 assert(Valid()); 154 return iter_->user_key(); 155 } 156 157 private: Update()158 void Update() { 159 valid_ = iter_->Valid(); 160 if (valid_) { 161 assert(iter_->status().ok()); 162 result_.key = iter_->key(); 163 result_.bound_check_result = IterBoundCheck::kUnknown; 164 result_.value_prepared = false; 165 } 166 } 167 168 InternalIteratorBase<TValue>* iter_; 169 IterateResult result_; 170 bool valid_; 171 }; 172 173 using IteratorWrapper = IteratorWrapperBase<Slice>; 174 175 class Arena; 176 // Return an empty iterator (yields nothing) allocated from arena. 177 template <class TValue = Slice> 178 extern InternalIteratorBase<TValue>* NewEmptyInternalIterator(Arena* arena); 179 180 } // namespace ROCKSDB_NAMESPACE 181