#pragma once
#include <set>
#include "table/internal_iterator.h"
#include "test_util/sync_point.h"
namespace ROCKSDB_NAMESPACE {
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_; }
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>();
}
}
}
bool Valid() const { return valid_; }
Slice key() const {
assert(Valid());
return result_.key;
}
TValue value() const {
assert(Valid());
return iter_->value();
}
Status status() const {
assert(iter_);
return iter_->status();
}
bool PrepareValue() {
assert(Valid());
if (result_.value_prepared) {
return true;
}
if (iter_->PrepareValue()) {
result_.value_prepared = true;
return true;
}
assert(!iter_->Valid());
valid_ = false;
return false;
}
void Next() {
assert(iter_);
valid_ = iter_->NextAndGetResult(&result_);
assert(!valid_ || iter_->status().ok());
}
bool NextAndGetResult(IterateResult* result) {
assert(iter_);
valid_ = iter_->NextAndGetResult(&result_);
*result = result_;
assert(!valid_ || iter_->status().ok());
return valid_;
}
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();
}
IterBoundCheck UpperBoundCheckResult() {
assert(Valid());
return result_.bound_check_result;
}
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();
}
bool IsValuePrepared() const {
return result_.value_prepared;
}
Slice user_key() const {
assert(Valid());
return iter_->user_key();
}
private:
void Update() {
valid_ = iter_->Valid();
if (valid_) {
assert(iter_->status().ok());
result_.key = iter_->key();
result_.bound_check_result = IterBoundCheck::kUnknown;
result_.value_prepared = false;
}
}
InternalIteratorBase<TValue>* iter_;
IterateResult result_;
bool valid_;
};
using IteratorWrapper = IteratorWrapperBase<Slice>;
class Arena;
template <class TValue = Slice>
extern InternalIteratorBase<TValue>* NewEmptyInternalIterator(Arena* arena);
}