summaryrefslogtreecommitdiffstats
path: root/src/rocksdb/table/iterator_wrapper.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/rocksdb/table/iterator_wrapper.h')
-rw-r--r--src/rocksdb/table/iterator_wrapper.h149
1 files changed, 149 insertions, 0 deletions
diff --git a/src/rocksdb/table/iterator_wrapper.h b/src/rocksdb/table/iterator_wrapper.h
new file mode 100644
index 000000000..c13359e99
--- /dev/null
+++ b/src/rocksdb/table/iterator_wrapper.h
@@ -0,0 +1,149 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+//
+// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file. See the AUTHORS file for names of contributors.
+
+#pragma once
+
+#include <set>
+
+#include "table/internal_iterator.h"
+#include "test_util/sync_point.h"
+
+namespace ROCKSDB_NAMESPACE {
+
+// A internal wrapper class with an interface similar to Iterator that caches
+// the valid() and key() results for an underlying iterator.
+// This can help avoid virtual function calls and also gives better
+// cache locality.
+template <class TValue = Slice>
+class IteratorWrapperBase {
+ public:
+ IteratorWrapperBase() : iter_(nullptr), valid_(false) {}
+ explicit IteratorWrapperBase(InternalIteratorBase<TValue>* _iter)
+ : iter_(nullptr) {
+ Set(_iter);
+ }
+ ~IteratorWrapperBase() {}
+ InternalIteratorBase<TValue>* iter() const { return iter_; }
+
+ // Set the underlying Iterator to _iter and return
+ // previous underlying Iterator.
+ InternalIteratorBase<TValue>* Set(InternalIteratorBase<TValue>* _iter) {
+ InternalIteratorBase<TValue>* old_iter = iter_;
+
+ iter_ = _iter;
+ if (iter_ == nullptr) {
+ valid_ = false;
+ } else {
+ Update();
+ }
+ return old_iter;
+ }
+
+ void DeleteIter(bool is_arena_mode) {
+ if (iter_) {
+ if (!is_arena_mode) {
+ delete iter_;
+ } else {
+ iter_->~InternalIteratorBase<TValue>();
+ }
+ }
+ }
+
+ // Iterator interface methods
+ bool Valid() const { return valid_; }
+ Slice key() const {
+ assert(Valid());
+ return result_.key;
+ }
+ TValue value() const {
+ assert(Valid());
+ return iter_->value();
+ }
+ // Methods below require iter() != nullptr
+ Status status() const {
+ assert(iter_);
+ return iter_->status();
+ }
+ void Next() {
+ assert(iter_);
+ valid_ = iter_->NextAndGetResult(&result_);
+ assert(!valid_ || iter_->status().ok());
+ }
+ void Prev() {
+ assert(iter_);
+ iter_->Prev();
+ Update();
+ }
+ void Seek(const Slice& k) {
+ assert(iter_);
+ iter_->Seek(k);
+ Update();
+ }
+ void SeekForPrev(const Slice& k) {
+ assert(iter_);
+ iter_->SeekForPrev(k);
+ Update();
+ }
+ void SeekToFirst() {
+ assert(iter_);
+ iter_->SeekToFirst();
+ Update();
+ }
+ void SeekToLast() {
+ assert(iter_);
+ iter_->SeekToLast();
+ Update();
+ }
+
+ bool MayBeOutOfLowerBound() {
+ assert(Valid());
+ return iter_->MayBeOutOfLowerBound();
+ }
+
+ bool MayBeOutOfUpperBound() {
+ assert(Valid());
+ return result_.may_be_out_of_upper_bound;
+ }
+
+ void SetPinnedItersMgr(PinnedIteratorsManager* pinned_iters_mgr) {
+ assert(iter_);
+ iter_->SetPinnedItersMgr(pinned_iters_mgr);
+ }
+ bool IsKeyPinned() const {
+ assert(Valid());
+ return iter_->IsKeyPinned();
+ }
+ bool IsValuePinned() const {
+ assert(Valid());
+ return iter_->IsValuePinned();
+ }
+
+ private:
+ void Update() {
+ valid_ = iter_->Valid();
+ if (valid_) {
+ assert(iter_->status().ok());
+ result_.key = iter_->key();
+ result_.may_be_out_of_upper_bound = true;
+ }
+ }
+
+ InternalIteratorBase<TValue>* iter_;
+ IterateResult result_;
+ bool valid_;
+};
+
+using IteratorWrapper = IteratorWrapperBase<Slice>;
+
+class Arena;
+// Return an empty iterator (yields nothing) allocated from arena.
+template <class TValue = Slice>
+extern InternalIteratorBase<TValue>* NewEmptyInternalIterator(Arena* arena);
+
+} // namespace ROCKSDB_NAMESPACE