]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/table/iterator_wrapper.h
ff46f2536cbe48e41f49a5edc7ad5205d8c30088
[ceph.git] / ceph / src / rocksdb / table / iterator_wrapper.h
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:
26 IteratorWrapperBase() : iter_(nullptr), valid_(false) {}
27 explicit IteratorWrapperBase(InternalIteratorBase<TValue>* _iter)
28 : iter_(nullptr) {
29 Set(_iter);
30 }
31 ~IteratorWrapperBase() {}
32 InternalIteratorBase<TValue>* iter() const { return iter_; }
33
34 // Set the underlying Iterator to _iter and return
35 // previous underlying Iterator.
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
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
59 bool Valid() const { return valid_; }
60 Slice key() const {
61 assert(Valid());
62 return result_.key;
63 }
64 TValue value() const {
65 assert(Valid());
66 return iter_->value();
67 }
68 // Methods below require iter() != nullptr
69 Status status() const {
70 assert(iter_);
71 return iter_->status();
72 }
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 }
87 void Next() {
88 assert(iter_);
89 valid_ = iter_->NextAndGetResult(&result_);
90 assert(!valid_ || iter_->status().ok());
91 }
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 }
99 void Prev() {
100 assert(iter_);
101 iter_->Prev();
102 Update();
103 }
104 void Seek(const Slice& k) {
105 assert(iter_);
106 iter_->Seek(k);
107 Update();
108 }
109 void SeekForPrev(const Slice& k) {
110 assert(iter_);
111 iter_->SeekForPrev(k);
112 Update();
113 }
114 void SeekToFirst() {
115 assert(iter_);
116 iter_->SeekToFirst();
117 Update();
118 }
119 void SeekToLast() {
120 assert(iter_);
121 iter_->SeekToLast();
122 Update();
123 }
124
125 bool MayBeOutOfLowerBound() {
126 assert(Valid());
127 return iter_->MayBeOutOfLowerBound();
128 }
129
130 IterBoundCheck UpperBoundCheckResult() {
131 assert(Valid());
132 return result_.bound_check_result;
133 }
134
135 void SetPinnedItersMgr(PinnedIteratorsManager* pinned_iters_mgr) {
136 assert(iter_);
137 iter_->SetPinnedItersMgr(pinned_iters_mgr);
138 }
139 bool IsKeyPinned() const {
140 assert(Valid());
141 return iter_->IsKeyPinned();
142 }
143 bool IsValuePinned() const {
144 assert(Valid());
145 return iter_->IsValuePinned();
146 }
147
148 bool IsValuePrepared() const {
149 return result_.value_prepared;
150 }
151
152 Slice user_key() const {
153 assert(Valid());
154 return iter_->user_key();
155 }
156
157 private:
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