merger_test.cc 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. #include <string>
  6. #include <vector>
  7. #include "table/merging_iterator.h"
  8. #include "test_util/testharness.h"
  9. #include "test_util/testutil.h"
  10. #include "util/random.h"
  11. #include "util/vector_iterator.h"
  12. namespace ROCKSDB_NAMESPACE {
  13. class MergerTest : public testing::Test {
  14. public:
  15. MergerTest()
  16. : icomp_(BytewiseComparator()),
  17. rnd_(3),
  18. merging_iterator_(nullptr),
  19. single_iterator_(nullptr) {}
  20. ~MergerTest() override = default;
  21. std::vector<std::string> GenerateStrings(size_t len, int string_len) {
  22. std::vector<std::string> ret;
  23. for (size_t i = 0; i < len; ++i) {
  24. InternalKey ik(rnd_.HumanReadableString(string_len), 0,
  25. ValueType::kTypeValue);
  26. ret.push_back(ik.Encode().ToString(false));
  27. }
  28. return ret;
  29. }
  30. void AssertEquivalence() {
  31. auto a = merging_iterator_.get();
  32. auto b = single_iterator_.get();
  33. if (!a->Valid()) {
  34. ASSERT_TRUE(!b->Valid());
  35. } else {
  36. ASSERT_TRUE(b->Valid());
  37. ASSERT_EQ(b->key().ToString(), a->key().ToString());
  38. ASSERT_EQ(b->value().ToString(), a->value().ToString());
  39. }
  40. }
  41. void SeekToRandom() {
  42. InternalKey ik(rnd_.HumanReadableString(5), 0, ValueType::kTypeValue);
  43. Seek(ik.Encode().ToString(false));
  44. }
  45. void Seek(std::string target) {
  46. merging_iterator_->Seek(target);
  47. single_iterator_->Seek(target);
  48. }
  49. void SeekToFirst() {
  50. merging_iterator_->SeekToFirst();
  51. single_iterator_->SeekToFirst();
  52. }
  53. void SeekToLast() {
  54. merging_iterator_->SeekToLast();
  55. single_iterator_->SeekToLast();
  56. }
  57. void Next(int times) {
  58. for (int i = 0; i < times && merging_iterator_->Valid(); ++i) {
  59. AssertEquivalence();
  60. merging_iterator_->Next();
  61. single_iterator_->Next();
  62. }
  63. AssertEquivalence();
  64. }
  65. void Prev(int times) {
  66. for (int i = 0; i < times && merging_iterator_->Valid(); ++i) {
  67. AssertEquivalence();
  68. merging_iterator_->Prev();
  69. single_iterator_->Prev();
  70. }
  71. AssertEquivalence();
  72. }
  73. void NextAndPrev(int times) {
  74. for (int i = 0; i < times && merging_iterator_->Valid(); ++i) {
  75. AssertEquivalence();
  76. if (rnd_.OneIn(2)) {
  77. merging_iterator_->Prev();
  78. single_iterator_->Prev();
  79. } else {
  80. merging_iterator_->Next();
  81. single_iterator_->Next();
  82. }
  83. }
  84. AssertEquivalence();
  85. }
  86. void Generate(size_t num_iterators, size_t strings_per_iterator,
  87. int letters_per_string) {
  88. std::vector<InternalIterator*> small_iterators;
  89. for (size_t i = 0; i < num_iterators; ++i) {
  90. auto strings = GenerateStrings(strings_per_iterator, letters_per_string);
  91. small_iterators.push_back(new VectorIterator(strings, strings, &icomp_));
  92. all_keys_.insert(all_keys_.end(), strings.begin(), strings.end());
  93. }
  94. merging_iterator_.reset(
  95. NewMergingIterator(&icomp_, small_iterators.data(),
  96. static_cast<int>(small_iterators.size())));
  97. single_iterator_.reset(new VectorIterator(all_keys_, all_keys_, &icomp_));
  98. }
  99. InternalKeyComparator icomp_;
  100. Random rnd_;
  101. std::unique_ptr<InternalIterator> merging_iterator_;
  102. std::unique_ptr<InternalIterator> single_iterator_;
  103. std::vector<std::string> all_keys_;
  104. };
  105. TEST_F(MergerTest, SeekToRandomNextTest) {
  106. Generate(1000, 50, 50);
  107. for (int i = 0; i < 10; ++i) {
  108. SeekToRandom();
  109. AssertEquivalence();
  110. Next(50000);
  111. }
  112. }
  113. TEST_F(MergerTest, SeekToRandomNextSmallStringsTest) {
  114. Generate(1000, 50, 2);
  115. for (int i = 0; i < 10; ++i) {
  116. SeekToRandom();
  117. AssertEquivalence();
  118. Next(50000);
  119. }
  120. }
  121. TEST_F(MergerTest, SeekToRandomPrevTest) {
  122. Generate(1000, 50, 50);
  123. for (int i = 0; i < 10; ++i) {
  124. SeekToRandom();
  125. AssertEquivalence();
  126. Prev(50000);
  127. }
  128. }
  129. TEST_F(MergerTest, SeekToRandomRandomTest) {
  130. Generate(200, 50, 50);
  131. for (int i = 0; i < 3; ++i) {
  132. SeekToRandom();
  133. AssertEquivalence();
  134. NextAndPrev(5000);
  135. }
  136. }
  137. TEST_F(MergerTest, SeekToFirstTest) {
  138. Generate(1000, 50, 50);
  139. for (int i = 0; i < 10; ++i) {
  140. SeekToFirst();
  141. AssertEquivalence();
  142. Next(50000);
  143. }
  144. }
  145. TEST_F(MergerTest, SeekToLastTest) {
  146. Generate(1000, 50, 50);
  147. for (int i = 0; i < 10; ++i) {
  148. SeekToLast();
  149. AssertEquivalence();
  150. Prev(50000);
  151. }
  152. }
  153. } // namespace ROCKSDB_NAMESPACE
  154. int main(int argc, char** argv) {
  155. ROCKSDB_NAMESPACE::port::InstallStackTraceHandler();
  156. ::testing::InitGoogleTest(&argc, argv);
  157. return RUN_ALL_TESTS();
  158. }