mirror of
https://github.com/facebook/rocksdb.git
synced 2024-11-27 02:44:18 +00:00
35ad531be3
Summary: Separate a new class InternalIterator from class Iterator, when the look-up is done internally, which also means they operate on key with sequence ID and type. This change will enable potential future optimizations but for now InternalIterator's functions are still the same as Iterator's. At the same time, separate the cleanup function to a separate class and let both of InternalIterator and Iterator inherit from it. Test Plan: Run all existing tests. Reviewers: igor, yhchiang, anthony, kradhakrishnan, IslamAbdelRahman, rven Reviewed By: rven Subscribers: leveldb, dhruba Differential Revision: https://reviews.facebook.net/D48549
170 lines
4.3 KiB
C++
170 lines
4.3 KiB
C++
// Copyright (c) 2013, Facebook, Inc. All rights reserved.
|
|
// This source code is licensed under the BSD-style license found in the
|
|
// LICENSE file in the root directory of this source tree. An additional grant
|
|
// of patent rights can be found in the PATENTS file in the same directory.
|
|
|
|
#include <vector>
|
|
#include <string>
|
|
|
|
#include "table/merger.h"
|
|
#include "util/testharness.h"
|
|
#include "util/testutil.h"
|
|
|
|
namespace rocksdb {
|
|
|
|
class MergerTest : public testing::Test {
|
|
public:
|
|
MergerTest()
|
|
: rnd_(3), merging_iterator_(nullptr), single_iterator_(nullptr) {}
|
|
~MergerTest() = default;
|
|
std::vector<std::string> GenerateStrings(size_t len, int string_len) {
|
|
std::vector<std::string> ret;
|
|
for (size_t i = 0; i < len; ++i) {
|
|
ret.push_back(test::RandomHumanReadableString(&rnd_, string_len));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void AssertEquivalence() {
|
|
auto a = merging_iterator_.get();
|
|
auto b = single_iterator_.get();
|
|
if (!a->Valid()) {
|
|
ASSERT_TRUE(!b->Valid());
|
|
} else {
|
|
ASSERT_TRUE(b->Valid());
|
|
ASSERT_EQ(b->key().ToString(), a->key().ToString());
|
|
ASSERT_EQ(b->value().ToString(), a->value().ToString());
|
|
}
|
|
}
|
|
|
|
void SeekToRandom() { Seek(test::RandomHumanReadableString(&rnd_, 5)); }
|
|
|
|
void Seek(std::string target) {
|
|
merging_iterator_->Seek(target);
|
|
single_iterator_->Seek(target);
|
|
}
|
|
|
|
void SeekToFirst() {
|
|
merging_iterator_->SeekToFirst();
|
|
single_iterator_->SeekToFirst();
|
|
}
|
|
|
|
void SeekToLast() {
|
|
merging_iterator_->SeekToLast();
|
|
single_iterator_->SeekToLast();
|
|
}
|
|
|
|
void Next(int times) {
|
|
for (int i = 0; i < times && merging_iterator_->Valid(); ++i) {
|
|
AssertEquivalence();
|
|
merging_iterator_->Next();
|
|
single_iterator_->Next();
|
|
}
|
|
AssertEquivalence();
|
|
}
|
|
|
|
void Prev(int times) {
|
|
for (int i = 0; i < times && merging_iterator_->Valid(); ++i) {
|
|
AssertEquivalence();
|
|
merging_iterator_->Prev();
|
|
single_iterator_->Prev();
|
|
}
|
|
AssertEquivalence();
|
|
}
|
|
|
|
void NextAndPrev(int times) {
|
|
for (int i = 0; i < times && merging_iterator_->Valid(); ++i) {
|
|
AssertEquivalence();
|
|
if (rnd_.OneIn(2)) {
|
|
merging_iterator_->Prev();
|
|
single_iterator_->Prev();
|
|
} else {
|
|
merging_iterator_->Next();
|
|
single_iterator_->Next();
|
|
}
|
|
}
|
|
AssertEquivalence();
|
|
}
|
|
|
|
void Generate(size_t num_iterators, size_t strings_per_iterator,
|
|
int letters_per_string) {
|
|
std::vector<InternalIterator*> small_iterators;
|
|
for (size_t i = 0; i < num_iterators; ++i) {
|
|
auto strings = GenerateStrings(strings_per_iterator, letters_per_string);
|
|
small_iterators.push_back(new test::VectorIterator(strings));
|
|
all_keys_.insert(all_keys_.end(), strings.begin(), strings.end());
|
|
}
|
|
|
|
merging_iterator_.reset(
|
|
NewMergingIterator(BytewiseComparator(), &small_iterators[0],
|
|
static_cast<int>(small_iterators.size())));
|
|
single_iterator_.reset(new test::VectorIterator(all_keys_));
|
|
}
|
|
|
|
Random rnd_;
|
|
std::unique_ptr<InternalIterator> merging_iterator_;
|
|
std::unique_ptr<InternalIterator> single_iterator_;
|
|
std::vector<std::string> all_keys_;
|
|
};
|
|
|
|
TEST_F(MergerTest, SeekToRandomNextTest) {
|
|
Generate(1000, 50, 50);
|
|
for (int i = 0; i < 10; ++i) {
|
|
SeekToRandom();
|
|
AssertEquivalence();
|
|
Next(50000);
|
|
}
|
|
}
|
|
|
|
TEST_F(MergerTest, SeekToRandomNextSmallStringsTest) {
|
|
Generate(1000, 50, 2);
|
|
for (int i = 0; i < 10; ++i) {
|
|
SeekToRandom();
|
|
AssertEquivalence();
|
|
Next(50000);
|
|
}
|
|
}
|
|
|
|
TEST_F(MergerTest, SeekToRandomPrevTest) {
|
|
Generate(1000, 50, 50);
|
|
for (int i = 0; i < 10; ++i) {
|
|
SeekToRandom();
|
|
AssertEquivalence();
|
|
Prev(50000);
|
|
}
|
|
}
|
|
|
|
TEST_F(MergerTest, SeekToRandomRandomTest) {
|
|
Generate(200, 50, 50);
|
|
for (int i = 0; i < 3; ++i) {
|
|
SeekToRandom();
|
|
AssertEquivalence();
|
|
NextAndPrev(5000);
|
|
}
|
|
}
|
|
|
|
TEST_F(MergerTest, SeekToFirstTest) {
|
|
Generate(1000, 50, 50);
|
|
for (int i = 0; i < 10; ++i) {
|
|
SeekToFirst();
|
|
AssertEquivalence();
|
|
Next(50000);
|
|
}
|
|
}
|
|
|
|
TEST_F(MergerTest, SeekToLastTest) {
|
|
Generate(1000, 50, 50);
|
|
for (int i = 0; i < 10; ++i) {
|
|
SeekToLast();
|
|
AssertEquivalence();
|
|
Prev(50000);
|
|
}
|
|
}
|
|
|
|
} // namespace rocksdb
|
|
|
|
int main(int argc, char** argv) {
|
|
::testing::InitGoogleTest(&argc, argv);
|
|
return RUN_ALL_TESTS();
|
|
}
|