|
|
@ -15,7 +15,6 @@ |
|
|
|
#include <utility> |
|
|
|
#include <utility> |
|
|
|
|
|
|
|
|
|
|
|
#include "db/dbformat.h" |
|
|
|
#include "db/dbformat.h" |
|
|
|
#include "db/db_iter.h" |
|
|
|
|
|
|
|
#include "db/db_impl.h" |
|
|
|
#include "db/db_impl.h" |
|
|
|
#include "db/filename.h" |
|
|
|
#include "db/filename.h" |
|
|
|
#include "db/version_set.h" |
|
|
|
#include "db/version_set.h" |
|
|
@ -1164,952 +1163,6 @@ TEST(DBTest, ReadOnlyDB) { |
|
|
|
delete iter; |
|
|
|
delete iter; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
class TestIterator : public Iterator { |
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
explicit TestIterator(const Comparator* comparator) |
|
|
|
|
|
|
|
: initialized_(false), |
|
|
|
|
|
|
|
valid_(false), |
|
|
|
|
|
|
|
sequence_number_(0), |
|
|
|
|
|
|
|
iter_(0), |
|
|
|
|
|
|
|
cmp(comparator) {} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void AddMerge(std::string key, std::string value) { |
|
|
|
|
|
|
|
Add(key, kTypeMerge, value); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void AddDeletion(std::string key) { Add(key, kTypeDeletion, std::string()); } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void AddPut(std::string key, std::string value) { |
|
|
|
|
|
|
|
Add(key, kTypeValue, value); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Add(std::string key, ValueType type, std::string value) { |
|
|
|
|
|
|
|
valid_ = true; |
|
|
|
|
|
|
|
ParsedInternalKey internal_key(key, sequence_number_++, type); |
|
|
|
|
|
|
|
data_.push_back(std::pair<std::string, std::string>(std::string(), value)); |
|
|
|
|
|
|
|
AppendInternalKey(&data_.back().first, internal_key); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// should be called before operations with iterator
|
|
|
|
|
|
|
|
void Finish() { |
|
|
|
|
|
|
|
initialized_ = true; |
|
|
|
|
|
|
|
std::sort(data_.begin(), data_.end(), |
|
|
|
|
|
|
|
[this](std::pair<std::string, std::string> a, |
|
|
|
|
|
|
|
std::pair<std::string, std::string> b) { |
|
|
|
|
|
|
|
return (cmp.Compare(a.first, b.first) < 0); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
virtual bool Valid() const override { |
|
|
|
|
|
|
|
assert(initialized_); |
|
|
|
|
|
|
|
return valid_; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
virtual void SeekToFirst() override { |
|
|
|
|
|
|
|
assert(initialized_); |
|
|
|
|
|
|
|
valid_ = (data_.size() > 0); |
|
|
|
|
|
|
|
iter_ = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
virtual void SeekToLast() override { |
|
|
|
|
|
|
|
assert(initialized_); |
|
|
|
|
|
|
|
valid_ = (data_.size() > 0); |
|
|
|
|
|
|
|
iter_ = data_.size() - 1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
virtual void Seek(const Slice& target) override { |
|
|
|
|
|
|
|
assert(initialized_); |
|
|
|
|
|
|
|
SeekToFirst(); |
|
|
|
|
|
|
|
if (!valid_) { |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
while (iter_ < data_.size() && |
|
|
|
|
|
|
|
(cmp.Compare(data_[iter_].first, target) < 0)) { |
|
|
|
|
|
|
|
++iter_; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (iter_ == data_.size()) { |
|
|
|
|
|
|
|
valid_ = false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
virtual void Next() override { |
|
|
|
|
|
|
|
assert(initialized_); |
|
|
|
|
|
|
|
if (data_.empty() || (iter_ == data_.size() - 1)) { |
|
|
|
|
|
|
|
valid_ = false; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
++iter_; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
virtual void Prev() override { |
|
|
|
|
|
|
|
assert(initialized_); |
|
|
|
|
|
|
|
if (iter_ == 0) { |
|
|
|
|
|
|
|
valid_ = false; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
--iter_; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
virtual Slice key() const override { |
|
|
|
|
|
|
|
assert(initialized_); |
|
|
|
|
|
|
|
return data_[iter_].first; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
virtual Slice value() const override { |
|
|
|
|
|
|
|
assert(initialized_); |
|
|
|
|
|
|
|
return data_[iter_].second; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
virtual Status status() const override { |
|
|
|
|
|
|
|
assert(initialized_); |
|
|
|
|
|
|
|
return Status::OK(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
|
|
|
bool initialized_; |
|
|
|
|
|
|
|
bool valid_; |
|
|
|
|
|
|
|
size_t sequence_number_; |
|
|
|
|
|
|
|
size_t iter_; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
InternalKeyComparator cmp; |
|
|
|
|
|
|
|
std::vector<std::pair<std::string, std::string>> data_; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TEST(DBTest, DBIteratorPrevNext) { |
|
|
|
|
|
|
|
Options options; |
|
|
|
|
|
|
|
TestIterator internal_iter(BytewiseComparator()); |
|
|
|
|
|
|
|
internal_iter.AddDeletion("a"); |
|
|
|
|
|
|
|
internal_iter.AddDeletion("a"); |
|
|
|
|
|
|
|
internal_iter.AddDeletion("a"); |
|
|
|
|
|
|
|
internal_iter.AddDeletion("a"); |
|
|
|
|
|
|
|
internal_iter.AddPut("a", "val_a"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
internal_iter.AddPut("b", "val_b"); |
|
|
|
|
|
|
|
internal_iter.Finish(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 10); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "b"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "val_b"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "val_a"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db_iter->Next(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "b"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "val_b"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db_iter->Next(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 10); |
|
|
|
|
|
|
|
db_iter->SeekToFirst(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "val_a"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db_iter->Next(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "b"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "val_b"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "val_a"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Options options; |
|
|
|
|
|
|
|
TestIterator internal_iter(BytewiseComparator()); |
|
|
|
|
|
|
|
internal_iter.AddPut("a", "val_a"); |
|
|
|
|
|
|
|
internal_iter.AddPut("b", "val_b"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
internal_iter.AddPut("a", "val_a"); |
|
|
|
|
|
|
|
internal_iter.AddPut("b", "val_b"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
internal_iter.AddPut("a", "val_a"); |
|
|
|
|
|
|
|
internal_iter.AddPut("b", "val_b"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
internal_iter.AddPut("a", "val_a"); |
|
|
|
|
|
|
|
internal_iter.AddPut("b", "val_b"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
internal_iter.AddPut("a", "val_a"); |
|
|
|
|
|
|
|
internal_iter.AddPut("b", "val_b"); |
|
|
|
|
|
|
|
internal_iter.Finish(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 2); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "b"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "val_b"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db_iter->Next(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "b"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "val_b"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Options options; |
|
|
|
|
|
|
|
TestIterator internal_iter(BytewiseComparator()); |
|
|
|
|
|
|
|
internal_iter.AddPut("a", "val_a"); |
|
|
|
|
|
|
|
internal_iter.AddPut("a", "val_a"); |
|
|
|
|
|
|
|
internal_iter.AddPut("a", "val_a"); |
|
|
|
|
|
|
|
internal_iter.AddPut("a", "val_a"); |
|
|
|
|
|
|
|
internal_iter.AddPut("a", "val_a"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
internal_iter.AddPut("b", "val_b"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
internal_iter.AddPut("c", "val_c"); |
|
|
|
|
|
|
|
internal_iter.Finish(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 10); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "c"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "val_c"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "b"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "val_b"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db_iter->Next(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "c"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "val_c"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TEST(DBTest, DBIteratorEmpty) { |
|
|
|
|
|
|
|
Options options = CurrentOptions(); |
|
|
|
|
|
|
|
TestIterator internal_iter(BytewiseComparator()); |
|
|
|
|
|
|
|
internal_iter.Finish(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 0); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 0); |
|
|
|
|
|
|
|
db_iter->SeekToFirst(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TEST(DBTest, DBIteratorUseSkipCountSkips) { |
|
|
|
|
|
|
|
Options options = CurrentOptions(); |
|
|
|
|
|
|
|
options.statistics = rocksdb::CreateDBStatistics(); |
|
|
|
|
|
|
|
options.merge_operator = MergeOperators::CreateFromStringId("stringappend"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TestIterator internal_iter(BytewiseComparator()); |
|
|
|
|
|
|
|
for (size_t i = 0; i < 200; ++i) { |
|
|
|
|
|
|
|
internal_iter.AddPut("a", "a"); |
|
|
|
|
|
|
|
internal_iter.AddPut("b", "b"); |
|
|
|
|
|
|
|
internal_iter.AddPut("c", "c"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
internal_iter.Finish(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 2); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "c"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "c"); |
|
|
|
|
|
|
|
ASSERT_EQ(TestGetTickerCount(options, NUMBER_OF_RESEEKS_IN_ITERATION), 1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "b"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "b"); |
|
|
|
|
|
|
|
ASSERT_EQ(TestGetTickerCount(options, NUMBER_OF_RESEEKS_IN_ITERATION), 2); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(TestGetTickerCount(options, NUMBER_OF_RESEEKS_IN_ITERATION), 3); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(TestGetTickerCount(options, NUMBER_OF_RESEEKS_IN_ITERATION), 3); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TEST(DBTest, DBIteratorUseSkip) { |
|
|
|
|
|
|
|
Options options = CurrentOptions(); |
|
|
|
|
|
|
|
options.merge_operator = MergeOperators::CreateFromStringId("stringappend"); |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
TestIterator internal_iter(BytewiseComparator()); |
|
|
|
|
|
|
|
internal_iter.AddMerge("b", "merge_1"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("a", "merge_2"); |
|
|
|
|
|
|
|
for (size_t i = 0; i < 200; ++i) { |
|
|
|
|
|
|
|
internal_iter.AddPut("c", std::to_string(i)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
internal_iter.Finish(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < 200; ++i) { |
|
|
|
|
|
|
|
options.statistics = rocksdb::CreateDBStatistics(); |
|
|
|
|
|
|
|
auto db_iter = NewDBIterator(env_, options, BytewiseComparator(), |
|
|
|
|
|
|
|
&internal_iter, i + 2); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "c"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), std::to_string(i)); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "b"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_1"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_2"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
TestIterator internal_iter(BytewiseComparator()); |
|
|
|
|
|
|
|
internal_iter.AddMerge("b", "merge_1"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("a", "merge_2"); |
|
|
|
|
|
|
|
for (size_t i = 0; i < 200; ++i) { |
|
|
|
|
|
|
|
internal_iter.AddDeletion("c"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
internal_iter.AddPut("c", "200"); |
|
|
|
|
|
|
|
internal_iter.Finish(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < 200; ++i) { |
|
|
|
|
|
|
|
auto db_iter = NewDBIterator(env_, options, BytewiseComparator(), |
|
|
|
|
|
|
|
&internal_iter, i + 2); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "b"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_1"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_2"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = NewDBIterator(env_, options, BytewiseComparator(), |
|
|
|
|
|
|
|
&internal_iter, 202); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "c"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "200"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "b"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_1"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_2"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
TestIterator internal_iter(BytewiseComparator()); |
|
|
|
|
|
|
|
for (size_t i = 0; i < 200; ++i) { |
|
|
|
|
|
|
|
internal_iter.AddDeletion("c"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
internal_iter.AddPut("c", "200"); |
|
|
|
|
|
|
|
internal_iter.Finish(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < 200; ++i) { |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, i); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db_iter->SeekToFirst(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 200); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "c"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "200"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db_iter->SeekToFirst(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "c"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "200"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db_iter->Next(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
TestIterator internal_iter(BytewiseComparator()); |
|
|
|
|
|
|
|
internal_iter.AddMerge("b", "merge_1"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("a", "merge_2"); |
|
|
|
|
|
|
|
for (size_t i = 0; i < 200; ++i) { |
|
|
|
|
|
|
|
internal_iter.AddPut("d", std::to_string(i)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < 200; ++i) { |
|
|
|
|
|
|
|
internal_iter.AddPut("c", std::to_string(i)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
internal_iter.Finish(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < 200; ++i) { |
|
|
|
|
|
|
|
auto db_iter = NewDBIterator(env_, options, BytewiseComparator(), |
|
|
|
|
|
|
|
&internal_iter, i + 2); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "d"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), std::to_string(i)); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "b"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_1"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_2"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
TestIterator internal_iter(BytewiseComparator()); |
|
|
|
|
|
|
|
internal_iter.AddMerge("b", "b"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("a", "a"); |
|
|
|
|
|
|
|
for (size_t i = 0; i < 200; ++i) { |
|
|
|
|
|
|
|
internal_iter.AddMerge("c", std::to_string(i)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
internal_iter.Finish(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < 200; ++i) { |
|
|
|
|
|
|
|
auto db_iter = NewDBIterator(env_, options, BytewiseComparator(), |
|
|
|
|
|
|
|
&internal_iter, i + 2); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "c"); |
|
|
|
|
|
|
|
std::string merge_result = "0"; |
|
|
|
|
|
|
|
for (size_t j = 1; j <= i; ++j) { |
|
|
|
|
|
|
|
merge_result += "," + std::to_string(j); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), merge_result); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "b"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "b"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "a"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TEST(DBTest, DBIterator) { |
|
|
|
|
|
|
|
Options options = CurrentOptions(); |
|
|
|
|
|
|
|
options.merge_operator = MergeOperators::CreateFromStringId("stringappend"); |
|
|
|
|
|
|
|
TestIterator internal_iter(BytewiseComparator()); |
|
|
|
|
|
|
|
internal_iter.AddPut("a", "0"); |
|
|
|
|
|
|
|
internal_iter.AddPut("b", "0"); |
|
|
|
|
|
|
|
internal_iter.AddDeletion("b"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("a", "1"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("b", "2"); |
|
|
|
|
|
|
|
internal_iter.Finish(); |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 1); |
|
|
|
|
|
|
|
db_iter->SeekToFirst(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "0"); |
|
|
|
|
|
|
|
db_iter->Next(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "b"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 0); |
|
|
|
|
|
|
|
db_iter->SeekToFirst(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "0"); |
|
|
|
|
|
|
|
db_iter->Next(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 2); |
|
|
|
|
|
|
|
db_iter->SeekToFirst(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "0"); |
|
|
|
|
|
|
|
db_iter->Next(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 4); |
|
|
|
|
|
|
|
db_iter->SeekToFirst(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "0,1"); |
|
|
|
|
|
|
|
db_iter->Next(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "b"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "2"); |
|
|
|
|
|
|
|
db_iter->Next(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
TestIterator internal_iter(BytewiseComparator()); |
|
|
|
|
|
|
|
internal_iter.AddMerge("a", "merge_1"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("a", "merge_2"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("a", "merge_3"); |
|
|
|
|
|
|
|
internal_iter.AddPut("a", "put_1"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("a", "merge_4"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("a", "merge_5"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("a", "merge_6"); |
|
|
|
|
|
|
|
internal_iter.Finish(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 0); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_1"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 1); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_1,merge_2"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 2); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_1,merge_2,merge_3"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 3); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "put_1"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 4); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "put_1,merge_4"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 5); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "put_1,merge_4,merge_5"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 6); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "put_1,merge_4,merge_5,merge_6"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
TestIterator internal_iter(BytewiseComparator()); |
|
|
|
|
|
|
|
internal_iter.AddMerge("a", "merge_1"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("a", "merge_2"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("a", "merge_3"); |
|
|
|
|
|
|
|
internal_iter.AddDeletion("a"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("a", "merge_4"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("a", "merge_5"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("a", "merge_6"); |
|
|
|
|
|
|
|
internal_iter.Finish(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 0); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_1"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 1); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_1,merge_2"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 2); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_1,merge_2,merge_3"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 3); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 4); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_4"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 5); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_4,merge_5"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 6); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_4,merge_5,merge_6"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
TestIterator internal_iter(BytewiseComparator()); |
|
|
|
|
|
|
|
internal_iter.AddMerge("a", "merge_1"); |
|
|
|
|
|
|
|
internal_iter.AddPut("b", "val"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("b", "merge_2"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
internal_iter.AddDeletion("b"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("b", "merge_3"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
internal_iter.AddMerge("c", "merge_4"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("c", "merge_5"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
internal_iter.AddDeletion("b"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("b", "merge_6"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("b", "merge_7"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("b", "merge_8"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("b", "merge_9"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("b", "merge_10"); |
|
|
|
|
|
|
|
internal_iter.AddMerge("b", "merge_11"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
internal_iter.AddDeletion("c"); |
|
|
|
|
|
|
|
internal_iter.Finish(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 0); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_1"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 2); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "b"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "val,merge_2"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_1"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 4); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "b"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_3"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_1"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 5); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "c"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_4"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "b"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_3"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_1"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 6); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "c"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_4,merge_5"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "b"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_3"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_1"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 7); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "c"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_4,merge_5"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_1"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 9); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "c"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_4,merge_5"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "b"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_6,merge_7"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_1"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = NewDBIterator(env_, options, BytewiseComparator(), |
|
|
|
|
|
|
|
&internal_iter, 13); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "c"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_4,merge_5"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "b"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), |
|
|
|
|
|
|
|
"merge_6,merge_7,merge_8,merge_9,merge_10,merge_11"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_1"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto db_iter = NewDBIterator(env_, options, BytewiseComparator(), |
|
|
|
|
|
|
|
&internal_iter, 14); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "b"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), |
|
|
|
|
|
|
|
"merge_6,merge_7,merge_8,merge_9,merge_10,merge_11"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "merge_1"); |
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(!db_iter->Valid()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Options options = CurrentOptions(); |
|
|
|
|
|
|
|
TestIterator internal_iter(BytewiseComparator()); |
|
|
|
|
|
|
|
internal_iter.AddDeletion("a"); |
|
|
|
|
|
|
|
internal_iter.AddPut("a", "0"); |
|
|
|
|
|
|
|
internal_iter.AddPut("b", "0"); |
|
|
|
|
|
|
|
internal_iter.Finish(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto db_iter = |
|
|
|
|
|
|
|
NewDBIterator(env_, options, BytewiseComparator(), &internal_iter, 10); |
|
|
|
|
|
|
|
db_iter->SeekToLast(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "b"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "0"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db_iter->Prev(); |
|
|
|
|
|
|
|
ASSERT_TRUE(db_iter->Valid()); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->key().ToString(), "a"); |
|
|
|
|
|
|
|
ASSERT_EQ(db_iter->value().ToString(), "0"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Make sure that when options.block_cache is set, after a new table is
|
|
|
|
// Make sure that when options.block_cache is set, after a new table is
|
|
|
|
// created its index/filter blocks are added to block cache.
|
|
|
|
// created its index/filter blocks are added to block cache.
|
|
|
|
TEST(DBTest, IndexAndFilterBlocksOfNewTableAddedToCache) { |
|
|
|
TEST(DBTest, IndexAndFilterBlocksOfNewTableAddedToCache) { |
|
|
|