WBWI Internal Move implementation from .h into .cpp (#8229)
Summary: Moves some of the structural refactoring from https://github.com/facebook/rocksdb/pull/8135 into this PR. This just cleans up the code by moving implementation out of the .h file and into the .cc file. Should be considered for merge before both https://github.com/facebook/rocksdb/pull/7214 and https://github.com/facebook/rocksdb/pull/8135 Pull Request resolved: https://github.com/facebook/rocksdb/pull/8229 Reviewed By: jay-zhuang Differential Revision: D27999669 Pulled By: mrambacher fbshipit-source-id: 6eccecbf1f11bb9f5a173e86d1e7bc448bc96071
This commit is contained in:
parent
69c986825e
commit
2760c2aef8
@ -19,6 +19,305 @@
|
||||
#include "util/string_util.h"
|
||||
|
||||
namespace ROCKSDB_NAMESPACE {
|
||||
BaseDeltaIterator::BaseDeltaIterator(Iterator* base_iterator,
|
||||
WBWIIterator* delta_iterator,
|
||||
const Comparator* comparator,
|
||||
const ReadOptions* read_options)
|
||||
: forward_(true),
|
||||
current_at_base_(true),
|
||||
equal_keys_(false),
|
||||
status_(Status::OK()),
|
||||
base_iterator_(base_iterator),
|
||||
delta_iterator_(delta_iterator),
|
||||
comparator_(comparator),
|
||||
iterate_upper_bound_(read_options ? read_options->iterate_upper_bound
|
||||
: nullptr) {}
|
||||
|
||||
bool BaseDeltaIterator::Valid() const {
|
||||
return status_.ok() ? (current_at_base_ ? BaseValid() : DeltaValid()) : false;
|
||||
}
|
||||
|
||||
void BaseDeltaIterator::SeekToFirst() {
|
||||
forward_ = true;
|
||||
base_iterator_->SeekToFirst();
|
||||
delta_iterator_->SeekToFirst();
|
||||
UpdateCurrent();
|
||||
}
|
||||
|
||||
void BaseDeltaIterator::SeekToLast() {
|
||||
forward_ = false;
|
||||
base_iterator_->SeekToLast();
|
||||
delta_iterator_->SeekToLast();
|
||||
UpdateCurrent();
|
||||
}
|
||||
|
||||
void BaseDeltaIterator::Seek(const Slice& k) {
|
||||
forward_ = true;
|
||||
base_iterator_->Seek(k);
|
||||
delta_iterator_->Seek(k);
|
||||
UpdateCurrent();
|
||||
}
|
||||
|
||||
void BaseDeltaIterator::SeekForPrev(const Slice& k) {
|
||||
forward_ = false;
|
||||
base_iterator_->SeekForPrev(k);
|
||||
delta_iterator_->SeekForPrev(k);
|
||||
UpdateCurrent();
|
||||
}
|
||||
|
||||
void BaseDeltaIterator::Next() {
|
||||
if (!Valid()) {
|
||||
status_ = Status::NotSupported("Next() on invalid iterator");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!forward_) {
|
||||
// Need to change direction
|
||||
// if our direction was backward and we're not equal, we have two states:
|
||||
// * both iterators are valid: we're already in a good state (current
|
||||
// shows to smaller)
|
||||
// * only one iterator is valid: we need to advance that iterator
|
||||
forward_ = true;
|
||||
equal_keys_ = false;
|
||||
if (!BaseValid()) {
|
||||
assert(DeltaValid());
|
||||
base_iterator_->SeekToFirst();
|
||||
} else if (!DeltaValid()) {
|
||||
delta_iterator_->SeekToFirst();
|
||||
} else if (current_at_base_) {
|
||||
// Change delta from larger than base to smaller
|
||||
AdvanceDelta();
|
||||
} else {
|
||||
// Change base from larger than delta to smaller
|
||||
AdvanceBase();
|
||||
}
|
||||
if (DeltaValid() && BaseValid()) {
|
||||
if (comparator_->Equal(delta_iterator_->Entry().key,
|
||||
base_iterator_->key())) {
|
||||
equal_keys_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Advance();
|
||||
}
|
||||
|
||||
void BaseDeltaIterator::Prev() {
|
||||
if (!Valid()) {
|
||||
status_ = Status::NotSupported("Prev() on invalid iterator");
|
||||
return;
|
||||
}
|
||||
|
||||
if (forward_) {
|
||||
// Need to change direction
|
||||
// if our direction was backward and we're not equal, we have two states:
|
||||
// * both iterators are valid: we're already in a good state (current
|
||||
// shows to smaller)
|
||||
// * only one iterator is valid: we need to advance that iterator
|
||||
forward_ = false;
|
||||
equal_keys_ = false;
|
||||
if (!BaseValid()) {
|
||||
assert(DeltaValid());
|
||||
base_iterator_->SeekToLast();
|
||||
} else if (!DeltaValid()) {
|
||||
delta_iterator_->SeekToLast();
|
||||
} else if (current_at_base_) {
|
||||
// Change delta from less advanced than base to more advanced
|
||||
AdvanceDelta();
|
||||
} else {
|
||||
// Change base from less advanced than delta to more advanced
|
||||
AdvanceBase();
|
||||
}
|
||||
if (DeltaValid() && BaseValid()) {
|
||||
if (comparator_->Equal(delta_iterator_->Entry().key,
|
||||
base_iterator_->key())) {
|
||||
equal_keys_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Advance();
|
||||
}
|
||||
|
||||
Slice BaseDeltaIterator::key() const {
|
||||
return current_at_base_ ? base_iterator_->key()
|
||||
: delta_iterator_->Entry().key;
|
||||
}
|
||||
|
||||
Slice BaseDeltaIterator::value() const {
|
||||
return current_at_base_ ? base_iterator_->value()
|
||||
: delta_iterator_->Entry().value;
|
||||
}
|
||||
|
||||
Status BaseDeltaIterator::status() const {
|
||||
if (!status_.ok()) {
|
||||
return status_;
|
||||
}
|
||||
if (!base_iterator_->status().ok()) {
|
||||
return base_iterator_->status();
|
||||
}
|
||||
return delta_iterator_->status();
|
||||
}
|
||||
|
||||
void BaseDeltaIterator::Invalidate(Status s) { status_ = s; }
|
||||
|
||||
void BaseDeltaIterator::AssertInvariants() {
|
||||
#ifndef NDEBUG
|
||||
bool not_ok = false;
|
||||
if (!base_iterator_->status().ok()) {
|
||||
assert(!base_iterator_->Valid());
|
||||
not_ok = true;
|
||||
}
|
||||
if (!delta_iterator_->status().ok()) {
|
||||
assert(!delta_iterator_->Valid());
|
||||
not_ok = true;
|
||||
}
|
||||
if (not_ok) {
|
||||
assert(!Valid());
|
||||
assert(!status().ok());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Valid()) {
|
||||
return;
|
||||
}
|
||||
if (!BaseValid()) {
|
||||
assert(!current_at_base_ && delta_iterator_->Valid());
|
||||
return;
|
||||
}
|
||||
if (!DeltaValid()) {
|
||||
assert(current_at_base_ && base_iterator_->Valid());
|
||||
return;
|
||||
}
|
||||
// we don't support those yet
|
||||
assert(delta_iterator_->Entry().type != kMergeRecord &&
|
||||
delta_iterator_->Entry().type != kLogDataRecord);
|
||||
int compare =
|
||||
comparator_->Compare(delta_iterator_->Entry().key, base_iterator_->key());
|
||||
if (forward_) {
|
||||
// current_at_base -> compare < 0
|
||||
assert(!current_at_base_ || compare < 0);
|
||||
// !current_at_base -> compare <= 0
|
||||
assert(current_at_base_ && compare >= 0);
|
||||
} else {
|
||||
// current_at_base -> compare > 0
|
||||
assert(!current_at_base_ || compare > 0);
|
||||
// !current_at_base -> compare <= 0
|
||||
assert(current_at_base_ && compare <= 0);
|
||||
}
|
||||
// equal_keys_ <=> compare == 0
|
||||
assert((equal_keys_ || compare != 0) && (!equal_keys_ || compare == 0));
|
||||
#endif
|
||||
}
|
||||
|
||||
void BaseDeltaIterator::Advance() {
|
||||
if (equal_keys_) {
|
||||
assert(BaseValid() && DeltaValid());
|
||||
AdvanceBase();
|
||||
AdvanceDelta();
|
||||
} else {
|
||||
if (current_at_base_) {
|
||||
assert(BaseValid());
|
||||
AdvanceBase();
|
||||
} else {
|
||||
assert(DeltaValid());
|
||||
AdvanceDelta();
|
||||
}
|
||||
}
|
||||
UpdateCurrent();
|
||||
}
|
||||
|
||||
void BaseDeltaIterator::AdvanceDelta() {
|
||||
if (forward_) {
|
||||
delta_iterator_->Next();
|
||||
} else {
|
||||
delta_iterator_->Prev();
|
||||
}
|
||||
}
|
||||
|
||||
void BaseDeltaIterator::AdvanceBase() {
|
||||
if (forward_) {
|
||||
base_iterator_->Next();
|
||||
} else {
|
||||
base_iterator_->Prev();
|
||||
}
|
||||
}
|
||||
|
||||
bool BaseDeltaIterator::BaseValid() const { return base_iterator_->Valid(); }
|
||||
|
||||
bool BaseDeltaIterator::DeltaValid() const { return delta_iterator_->Valid(); }
|
||||
|
||||
void BaseDeltaIterator::UpdateCurrent() {
|
||||
// Suppress false positive clang analyzer warnings.
|
||||
#ifndef __clang_analyzer__
|
||||
status_ = Status::OK();
|
||||
while (true) {
|
||||
WriteEntry delta_entry;
|
||||
if (DeltaValid()) {
|
||||
assert(delta_iterator_->status().ok());
|
||||
delta_entry = delta_iterator_->Entry();
|
||||
} else if (!delta_iterator_->status().ok()) {
|
||||
// Expose the error status and stop.
|
||||
current_at_base_ = false;
|
||||
return;
|
||||
}
|
||||
equal_keys_ = false;
|
||||
if (!BaseValid()) {
|
||||
if (!base_iterator_->status().ok()) {
|
||||
// Expose the error status and stop.
|
||||
current_at_base_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Base has finished.
|
||||
if (!DeltaValid()) {
|
||||
// Finished
|
||||
return;
|
||||
}
|
||||
if (iterate_upper_bound_) {
|
||||
if (comparator_->Compare(delta_entry.key, *iterate_upper_bound_) >= 0) {
|
||||
// out of upper bound -> finished.
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (delta_entry.type == kDeleteRecord ||
|
||||
delta_entry.type == kSingleDeleteRecord) {
|
||||
AdvanceDelta();
|
||||
} else {
|
||||
current_at_base_ = false;
|
||||
return;
|
||||
}
|
||||
} else if (!DeltaValid()) {
|
||||
// Delta has finished.
|
||||
current_at_base_ = true;
|
||||
return;
|
||||
} else {
|
||||
int compare =
|
||||
(forward_ ? 1 : -1) *
|
||||
comparator_->Compare(delta_entry.key, base_iterator_->key());
|
||||
if (compare <= 0) { // delta bigger or equal
|
||||
if (compare == 0) {
|
||||
equal_keys_ = true;
|
||||
}
|
||||
if (delta_entry.type != kDeleteRecord &&
|
||||
delta_entry.type != kSingleDeleteRecord) {
|
||||
current_at_base_ = false;
|
||||
return;
|
||||
}
|
||||
// Delta is less advanced and is delete.
|
||||
AdvanceDelta();
|
||||
if (equal_keys_) {
|
||||
AdvanceBase();
|
||||
}
|
||||
} else {
|
||||
current_at_base_ = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AssertInvariants();
|
||||
#endif // __clang_analyzer__
|
||||
}
|
||||
|
||||
class Env;
|
||||
class Logger;
|
||||
|
@ -35,303 +35,30 @@ class BaseDeltaIterator : public Iterator {
|
||||
public:
|
||||
BaseDeltaIterator(Iterator* base_iterator, WBWIIterator* delta_iterator,
|
||||
const Comparator* comparator,
|
||||
const ReadOptions* read_options = nullptr)
|
||||
: forward_(true),
|
||||
current_at_base_(true),
|
||||
equal_keys_(false),
|
||||
status_(Status::OK()),
|
||||
base_iterator_(base_iterator),
|
||||
delta_iterator_(delta_iterator),
|
||||
comparator_(comparator),
|
||||
iterate_upper_bound_(read_options ? read_options->iterate_upper_bound
|
||||
: nullptr) {}
|
||||
const ReadOptions* read_options = nullptr);
|
||||
|
||||
~BaseDeltaIterator() override {}
|
||||
|
||||
bool Valid() const override {
|
||||
return status_.ok() ? (current_at_base_ ? BaseValid() : DeltaValid())
|
||||
: false;
|
||||
}
|
||||
|
||||
void SeekToFirst() override {
|
||||
forward_ = true;
|
||||
base_iterator_->SeekToFirst();
|
||||
delta_iterator_->SeekToFirst();
|
||||
UpdateCurrent();
|
||||
}
|
||||
|
||||
void SeekToLast() override {
|
||||
forward_ = false;
|
||||
base_iterator_->SeekToLast();
|
||||
delta_iterator_->SeekToLast();
|
||||
UpdateCurrent();
|
||||
}
|
||||
|
||||
void Seek(const Slice& k) override {
|
||||
forward_ = true;
|
||||
base_iterator_->Seek(k);
|
||||
delta_iterator_->Seek(k);
|
||||
UpdateCurrent();
|
||||
}
|
||||
|
||||
void SeekForPrev(const Slice& k) override {
|
||||
forward_ = false;
|
||||
base_iterator_->SeekForPrev(k);
|
||||
delta_iterator_->SeekForPrev(k);
|
||||
UpdateCurrent();
|
||||
}
|
||||
|
||||
void Next() override {
|
||||
if (!Valid()) {
|
||||
status_ = Status::NotSupported("Next() on invalid iterator");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!forward_) {
|
||||
// Need to change direction
|
||||
// if our direction was backward and we're not equal, we have two states:
|
||||
// * both iterators are valid: we're already in a good state (current
|
||||
// shows to smaller)
|
||||
// * only one iterator is valid: we need to advance that iterator
|
||||
forward_ = true;
|
||||
equal_keys_ = false;
|
||||
if (!BaseValid()) {
|
||||
assert(DeltaValid());
|
||||
base_iterator_->SeekToFirst();
|
||||
} else if (!DeltaValid()) {
|
||||
delta_iterator_->SeekToFirst();
|
||||
} else if (current_at_base_) {
|
||||
// Change delta from larger than base to smaller
|
||||
AdvanceDelta();
|
||||
} else {
|
||||
// Change base from larger than delta to smaller
|
||||
AdvanceBase();
|
||||
}
|
||||
if (DeltaValid() && BaseValid()) {
|
||||
if (comparator_->Equal(delta_iterator_->Entry().key,
|
||||
base_iterator_->key())) {
|
||||
equal_keys_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Advance();
|
||||
}
|
||||
|
||||
void Prev() override {
|
||||
if (!Valid()) {
|
||||
status_ = Status::NotSupported("Prev() on invalid iterator");
|
||||
return;
|
||||
}
|
||||
|
||||
if (forward_) {
|
||||
// Need to change direction
|
||||
// if our direction was backward and we're not equal, we have two states:
|
||||
// * both iterators are valid: we're already in a good state (current
|
||||
// shows to smaller)
|
||||
// * only one iterator is valid: we need to advance that iterator
|
||||
forward_ = false;
|
||||
equal_keys_ = false;
|
||||
if (!BaseValid()) {
|
||||
assert(DeltaValid());
|
||||
base_iterator_->SeekToLast();
|
||||
} else if (!DeltaValid()) {
|
||||
delta_iterator_->SeekToLast();
|
||||
} else if (current_at_base_) {
|
||||
// Change delta from less advanced than base to more advanced
|
||||
AdvanceDelta();
|
||||
} else {
|
||||
// Change base from less advanced than delta to more advanced
|
||||
AdvanceBase();
|
||||
}
|
||||
if (DeltaValid() && BaseValid()) {
|
||||
if (comparator_->Equal(delta_iterator_->Entry().key,
|
||||
base_iterator_->key())) {
|
||||
equal_keys_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Advance();
|
||||
}
|
||||
|
||||
Slice key() const override {
|
||||
return current_at_base_ ? base_iterator_->key()
|
||||
: delta_iterator_->Entry().key;
|
||||
}
|
||||
|
||||
Slice value() const override {
|
||||
return current_at_base_ ? base_iterator_->value()
|
||||
: delta_iterator_->Entry().value;
|
||||
}
|
||||
|
||||
Status status() const override {
|
||||
if (!status_.ok()) {
|
||||
return status_;
|
||||
}
|
||||
if (!base_iterator_->status().ok()) {
|
||||
return base_iterator_->status();
|
||||
}
|
||||
return delta_iterator_->status();
|
||||
}
|
||||
|
||||
void Invalidate(Status s) { status_ = s; }
|
||||
bool Valid() const override;
|
||||
void SeekToFirst() override;
|
||||
void SeekToLast() override;
|
||||
void Seek(const Slice& k) override;
|
||||
void SeekForPrev(const Slice& k) override;
|
||||
void Next() override;
|
||||
void Prev() override;
|
||||
Slice key() const override;
|
||||
Slice value() const override;
|
||||
Status status() const override;
|
||||
void Invalidate(Status s);
|
||||
|
||||
private:
|
||||
void AssertInvariants() {
|
||||
#ifndef NDEBUG
|
||||
bool not_ok = false;
|
||||
if (!base_iterator_->status().ok()) {
|
||||
assert(!base_iterator_->Valid());
|
||||
not_ok = true;
|
||||
}
|
||||
if (!delta_iterator_->status().ok()) {
|
||||
assert(!delta_iterator_->Valid());
|
||||
not_ok = true;
|
||||
}
|
||||
if (not_ok) {
|
||||
assert(!Valid());
|
||||
assert(!status().ok());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Valid()) {
|
||||
return;
|
||||
}
|
||||
if (!BaseValid()) {
|
||||
assert(!current_at_base_ && delta_iterator_->Valid());
|
||||
return;
|
||||
}
|
||||
if (!DeltaValid()) {
|
||||
assert(current_at_base_ && base_iterator_->Valid());
|
||||
return;
|
||||
}
|
||||
// we don't support those yet
|
||||
assert(delta_iterator_->Entry().type != kMergeRecord &&
|
||||
delta_iterator_->Entry().type != kLogDataRecord);
|
||||
int compare = comparator_->Compare(delta_iterator_->Entry().key,
|
||||
base_iterator_->key());
|
||||
if (forward_) {
|
||||
// current_at_base -> compare < 0
|
||||
assert(!current_at_base_ || compare < 0);
|
||||
// !current_at_base -> compare <= 0
|
||||
assert(current_at_base_ && compare >= 0);
|
||||
} else {
|
||||
// current_at_base -> compare > 0
|
||||
assert(!current_at_base_ || compare > 0);
|
||||
// !current_at_base -> compare <= 0
|
||||
assert(current_at_base_ && compare <= 0);
|
||||
}
|
||||
// equal_keys_ <=> compare == 0
|
||||
assert((equal_keys_ || compare != 0) && (!equal_keys_ || compare == 0));
|
||||
#endif
|
||||
}
|
||||
|
||||
void Advance() {
|
||||
if (equal_keys_) {
|
||||
assert(BaseValid() && DeltaValid());
|
||||
AdvanceBase();
|
||||
AdvanceDelta();
|
||||
} else {
|
||||
if (current_at_base_) {
|
||||
assert(BaseValid());
|
||||
AdvanceBase();
|
||||
} else {
|
||||
assert(DeltaValid());
|
||||
AdvanceDelta();
|
||||
}
|
||||
}
|
||||
UpdateCurrent();
|
||||
}
|
||||
|
||||
void AdvanceDelta() {
|
||||
if (forward_) {
|
||||
delta_iterator_->Next();
|
||||
} else {
|
||||
delta_iterator_->Prev();
|
||||
}
|
||||
}
|
||||
void AdvanceBase() {
|
||||
if (forward_) {
|
||||
base_iterator_->Next();
|
||||
} else {
|
||||
base_iterator_->Prev();
|
||||
}
|
||||
}
|
||||
bool BaseValid() const { return base_iterator_->Valid(); }
|
||||
bool DeltaValid() const { return delta_iterator_->Valid(); }
|
||||
void UpdateCurrent() {
|
||||
// Suppress false positive clang analyzer warnings.
|
||||
#ifndef __clang_analyzer__
|
||||
status_ = Status::OK();
|
||||
while (true) {
|
||||
WriteEntry delta_entry;
|
||||
if (DeltaValid()) {
|
||||
assert(delta_iterator_->status().ok());
|
||||
delta_entry = delta_iterator_->Entry();
|
||||
} else if (!delta_iterator_->status().ok()) {
|
||||
// Expose the error status and stop.
|
||||
current_at_base_ = false;
|
||||
return;
|
||||
}
|
||||
equal_keys_ = false;
|
||||
if (!BaseValid()) {
|
||||
if (!base_iterator_->status().ok()) {
|
||||
// Expose the error status and stop.
|
||||
current_at_base_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Base has finished.
|
||||
if (!DeltaValid()) {
|
||||
// Finished
|
||||
return;
|
||||
}
|
||||
if (iterate_upper_bound_) {
|
||||
if (comparator_->Compare(delta_entry.key, *iterate_upper_bound_) >=
|
||||
0) {
|
||||
// out of upper bound -> finished.
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (delta_entry.type == kDeleteRecord ||
|
||||
delta_entry.type == kSingleDeleteRecord) {
|
||||
AdvanceDelta();
|
||||
} else {
|
||||
current_at_base_ = false;
|
||||
return;
|
||||
}
|
||||
} else if (!DeltaValid()) {
|
||||
// Delta has finished.
|
||||
current_at_base_ = true;
|
||||
return;
|
||||
} else {
|
||||
int compare =
|
||||
(forward_ ? 1 : -1) *
|
||||
comparator_->Compare(delta_entry.key, base_iterator_->key());
|
||||
if (compare <= 0) { // delta bigger or equal
|
||||
if (compare == 0) {
|
||||
equal_keys_ = true;
|
||||
}
|
||||
if (delta_entry.type != kDeleteRecord &&
|
||||
delta_entry.type != kSingleDeleteRecord) {
|
||||
current_at_base_ = false;
|
||||
return;
|
||||
}
|
||||
// Delta is less advanced and is delete.
|
||||
AdvanceDelta();
|
||||
if (equal_keys_) {
|
||||
AdvanceBase();
|
||||
}
|
||||
} else {
|
||||
current_at_base_ = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AssertInvariants();
|
||||
#endif // __clang_analyzer__
|
||||
}
|
||||
void AssertInvariants();
|
||||
void Advance();
|
||||
void AdvanceDelta();
|
||||
void AdvanceBase();
|
||||
bool BaseValid() const;
|
||||
bool DeltaValid() const;
|
||||
void UpdateCurrent();
|
||||
|
||||
bool forward_;
|
||||
bool current_at_base_;
|
||||
|
Loading…
Reference in New Issue
Block a user