| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 | //  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
 |