comparator_db_test.cc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  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 <array>
  6. #include <map>
  7. #include <string>
  8. #include "memtable/stl_wrappers.h"
  9. #include "rocksdb/db.h"
  10. #include "rocksdb/env.h"
  11. #include "test_util/testharness.h"
  12. #include "test_util/testutil.h"
  13. #include "util/hash.h"
  14. #include "util/kv_map.h"
  15. #include "util/string_util.h"
  16. #include "utilities/merge_operators.h"
  17. using std::unique_ptr;
  18. namespace ROCKSDB_NAMESPACE {
  19. namespace {
  20. static const Comparator* kTestComparator = nullptr;
  21. class KVIter : public Iterator {
  22. public:
  23. explicit KVIter(const stl_wrappers::KVMap* map)
  24. : map_(map), iter_(map_->end()) {}
  25. bool Valid() const override { return iter_ != map_->end(); }
  26. void SeekToFirst() override { iter_ = map_->begin(); }
  27. void SeekToLast() override {
  28. if (map_->empty()) {
  29. iter_ = map_->end();
  30. } else {
  31. iter_ = map_->find(map_->rbegin()->first);
  32. }
  33. }
  34. void Seek(const Slice& k) override {
  35. iter_ = map_->lower_bound(k.ToString());
  36. }
  37. void SeekForPrev(const Slice& k) override {
  38. iter_ = map_->upper_bound(k.ToString());
  39. Prev();
  40. }
  41. void Next() override { ++iter_; }
  42. void Prev() override {
  43. if (iter_ == map_->begin()) {
  44. iter_ = map_->end();
  45. return;
  46. }
  47. --iter_;
  48. }
  49. Slice key() const override { return iter_->first; }
  50. Slice value() const override { return iter_->second; }
  51. Status status() const override { return Status::OK(); }
  52. private:
  53. const stl_wrappers::KVMap* const map_;
  54. stl_wrappers::KVMap::const_iterator iter_;
  55. };
  56. void AssertItersEqual(Iterator* iter1, Iterator* iter2) {
  57. ASSERT_EQ(iter1->Valid(), iter2->Valid());
  58. if (iter1->Valid()) {
  59. ASSERT_EQ(iter1->key().ToString(), iter2->key().ToString());
  60. ASSERT_EQ(iter1->value().ToString(), iter2->value().ToString());
  61. }
  62. }
  63. // Measuring operations on DB (expect to be empty).
  64. // source_strings are candidate keys
  65. void DoRandomIteraratorTest(DB* db, std::vector<std::string> source_strings,
  66. Random* rnd, int num_writes, int num_iter_ops,
  67. int num_trigger_flush) {
  68. stl_wrappers::KVMap map((stl_wrappers::LessOfComparator(kTestComparator)));
  69. for (int i = 0; i < num_writes; i++) {
  70. if (num_trigger_flush > 0 && i != 0 && i % num_trigger_flush == 0) {
  71. db->Flush(FlushOptions());
  72. }
  73. int type = rnd->Uniform(2);
  74. int index = rnd->Uniform(static_cast<int>(source_strings.size()));
  75. auto& key = source_strings[index];
  76. switch (type) {
  77. case 0:
  78. // put
  79. map[key] = key;
  80. ASSERT_OK(db->Put(WriteOptions(), key, key));
  81. break;
  82. case 1:
  83. // delete
  84. if (map.find(key) != map.end()) {
  85. map.erase(key);
  86. }
  87. ASSERT_OK(db->Delete(WriteOptions(), key));
  88. break;
  89. default:
  90. assert(false);
  91. }
  92. }
  93. std::unique_ptr<Iterator> iter(db->NewIterator(ReadOptions()));
  94. std::unique_ptr<Iterator> result_iter(new KVIter(&map));
  95. bool is_valid = false;
  96. for (int i = 0; i < num_iter_ops; i++) {
  97. // Random walk and make sure iter and result_iter returns the
  98. // same key and value
  99. int type = rnd->Uniform(6);
  100. ASSERT_OK(iter->status());
  101. switch (type) {
  102. case 0:
  103. // Seek to First
  104. iter->SeekToFirst();
  105. result_iter->SeekToFirst();
  106. break;
  107. case 1:
  108. // Seek to last
  109. iter->SeekToLast();
  110. result_iter->SeekToLast();
  111. break;
  112. case 2: {
  113. // Seek to random key
  114. auto key_idx = rnd->Uniform(static_cast<int>(source_strings.size()));
  115. auto key = source_strings[key_idx];
  116. iter->Seek(key);
  117. result_iter->Seek(key);
  118. break;
  119. }
  120. case 3:
  121. // Next
  122. if (is_valid) {
  123. iter->Next();
  124. result_iter->Next();
  125. } else {
  126. continue;
  127. }
  128. break;
  129. case 4:
  130. // Prev
  131. if (is_valid) {
  132. iter->Prev();
  133. result_iter->Prev();
  134. } else {
  135. continue;
  136. }
  137. break;
  138. default: {
  139. assert(type == 5);
  140. auto key_idx = rnd->Uniform(static_cast<int>(source_strings.size()));
  141. auto key = source_strings[key_idx];
  142. std::string result;
  143. auto status = db->Get(ReadOptions(), key, &result);
  144. if (map.find(key) == map.end()) {
  145. ASSERT_TRUE(status.IsNotFound());
  146. } else {
  147. ASSERT_EQ(map[key], result);
  148. }
  149. break;
  150. }
  151. }
  152. AssertItersEqual(iter.get(), result_iter.get());
  153. is_valid = iter->Valid();
  154. }
  155. }
  156. class DoubleComparator : public Comparator {
  157. public:
  158. DoubleComparator() {}
  159. const char* Name() const override { return "DoubleComparator"; }
  160. int Compare(const Slice& a, const Slice& b) const override {
  161. #ifndef CYGWIN
  162. double da = std::stod(a.ToString());
  163. double db = std::stod(b.ToString());
  164. #else
  165. double da = std::strtod(a.ToString().c_str(), 0 /* endptr */);
  166. double db = std::strtod(a.ToString().c_str(), 0 /* endptr */);
  167. #endif
  168. if (da == db) {
  169. return a.compare(b);
  170. } else if (da > db) {
  171. return 1;
  172. } else {
  173. return -1;
  174. }
  175. }
  176. void FindShortestSeparator(std::string* /*start*/,
  177. const Slice& /*limit*/) const override {}
  178. void FindShortSuccessor(std::string* /*key*/) const override {}
  179. };
  180. class HashComparator : public Comparator {
  181. public:
  182. HashComparator() {}
  183. const char* Name() const override { return "HashComparator"; }
  184. int Compare(const Slice& a, const Slice& b) const override {
  185. uint32_t ha = Hash(a.data(), a.size(), 66);
  186. uint32_t hb = Hash(b.data(), b.size(), 66);
  187. if (ha == hb) {
  188. return a.compare(b);
  189. } else if (ha > hb) {
  190. return 1;
  191. } else {
  192. return -1;
  193. }
  194. }
  195. void FindShortestSeparator(std::string* /*start*/,
  196. const Slice& /*limit*/) const override {}
  197. void FindShortSuccessor(std::string* /*key*/) const override {}
  198. };
  199. class TwoStrComparator : public Comparator {
  200. public:
  201. TwoStrComparator() {}
  202. const char* Name() const override { return "TwoStrComparator"; }
  203. int Compare(const Slice& a, const Slice& b) const override {
  204. assert(a.size() >= 2);
  205. assert(b.size() >= 2);
  206. size_t size_a1 = static_cast<size_t>(a[0]);
  207. size_t size_b1 = static_cast<size_t>(b[0]);
  208. size_t size_a2 = static_cast<size_t>(a[1]);
  209. size_t size_b2 = static_cast<size_t>(b[1]);
  210. assert(size_a1 + size_a2 + 2 == a.size());
  211. assert(size_b1 + size_b2 + 2 == b.size());
  212. Slice a1 = Slice(a.data() + 2, size_a1);
  213. Slice b1 = Slice(b.data() + 2, size_b1);
  214. Slice a2 = Slice(a.data() + 2 + size_a1, size_a2);
  215. Slice b2 = Slice(b.data() + 2 + size_b1, size_b2);
  216. if (a1 != b1) {
  217. return a1.compare(b1);
  218. }
  219. return a2.compare(b2);
  220. }
  221. void FindShortestSeparator(std::string* /*start*/,
  222. const Slice& /*limit*/) const override {}
  223. void FindShortSuccessor(std::string* /*key*/) const override {}
  224. };
  225. } // namespace
  226. class ComparatorDBTest
  227. : public testing::Test,
  228. virtual public ::testing::WithParamInterface<uint32_t> {
  229. private:
  230. std::string dbname_;
  231. Env* env_;
  232. DB* db_;
  233. Options last_options_;
  234. std::unique_ptr<const Comparator> comparator_guard;
  235. public:
  236. ComparatorDBTest() : env_(Env::Default()), db_(nullptr) {
  237. kTestComparator = BytewiseComparator();
  238. dbname_ = test::PerThreadDBPath("comparator_db_test");
  239. BlockBasedTableOptions toptions;
  240. toptions.format_version = GetParam();
  241. last_options_.table_factory.reset(
  242. ROCKSDB_NAMESPACE::NewBlockBasedTableFactory(toptions));
  243. EXPECT_OK(DestroyDB(dbname_, last_options_));
  244. }
  245. ~ComparatorDBTest() override {
  246. delete db_;
  247. EXPECT_OK(DestroyDB(dbname_, last_options_));
  248. kTestComparator = BytewiseComparator();
  249. }
  250. DB* GetDB() { return db_; }
  251. void SetOwnedComparator(const Comparator* cmp, bool owner = true) {
  252. if (owner) {
  253. comparator_guard.reset(cmp);
  254. } else {
  255. comparator_guard.reset();
  256. }
  257. kTestComparator = cmp;
  258. last_options_.comparator = cmp;
  259. }
  260. // Return the current option configuration.
  261. Options* GetOptions() { return &last_options_; }
  262. void DestroyAndReopen() {
  263. // Destroy using last options
  264. Destroy();
  265. ASSERT_OK(TryReopen());
  266. }
  267. void Destroy() {
  268. delete db_;
  269. db_ = nullptr;
  270. ASSERT_OK(DestroyDB(dbname_, last_options_));
  271. }
  272. Status TryReopen() {
  273. delete db_;
  274. db_ = nullptr;
  275. last_options_.create_if_missing = true;
  276. return DB::Open(last_options_, dbname_, &db_);
  277. }
  278. };
  279. INSTANTIATE_TEST_CASE_P(FormatDef, ComparatorDBTest,
  280. testing::Values(test::kDefaultFormatVersion));
  281. INSTANTIATE_TEST_CASE_P(FormatLatest, ComparatorDBTest,
  282. testing::Values(test::kLatestFormatVersion));
  283. TEST_P(ComparatorDBTest, Bytewise) {
  284. for (int rand_seed = 301; rand_seed < 306; rand_seed++) {
  285. DestroyAndReopen();
  286. Random rnd(rand_seed);
  287. DoRandomIteraratorTest(GetDB(),
  288. {"a", "b", "c", "d", "e", "f", "g", "h", "i"}, &rnd,
  289. 8, 100, 3);
  290. }
  291. }
  292. TEST_P(ComparatorDBTest, SimpleSuffixReverseComparator) {
  293. SetOwnedComparator(new test::SimpleSuffixReverseComparator());
  294. for (int rnd_seed = 301; rnd_seed < 316; rnd_seed++) {
  295. Options* opt = GetOptions();
  296. opt->comparator = kTestComparator;
  297. DestroyAndReopen();
  298. Random rnd(rnd_seed);
  299. std::vector<std::string> source_strings;
  300. std::vector<std::string> source_prefixes;
  301. // Randomly generate 5 prefixes
  302. for (int i = 0; i < 5; i++) {
  303. source_prefixes.push_back(test::RandomHumanReadableString(&rnd, 8));
  304. }
  305. for (int j = 0; j < 20; j++) {
  306. int prefix_index = rnd.Uniform(static_cast<int>(source_prefixes.size()));
  307. std::string key = source_prefixes[prefix_index] +
  308. test::RandomHumanReadableString(&rnd, rnd.Uniform(8));
  309. source_strings.push_back(key);
  310. }
  311. DoRandomIteraratorTest(GetDB(), source_strings, &rnd, 30, 600, 66);
  312. }
  313. }
  314. TEST_P(ComparatorDBTest, Uint64Comparator) {
  315. SetOwnedComparator(test::Uint64Comparator(), false /* owner */);
  316. for (int rnd_seed = 301; rnd_seed < 316; rnd_seed++) {
  317. Options* opt = GetOptions();
  318. opt->comparator = kTestComparator;
  319. DestroyAndReopen();
  320. Random rnd(rnd_seed);
  321. Random64 rnd64(rnd_seed);
  322. std::vector<std::string> source_strings;
  323. // Randomly generate source keys
  324. for (int i = 0; i < 100; i++) {
  325. uint64_t r = rnd64.Next();
  326. std::string str;
  327. str.resize(8);
  328. memcpy(&str[0], static_cast<void*>(&r), 8);
  329. source_strings.push_back(str);
  330. }
  331. DoRandomIteraratorTest(GetDB(), source_strings, &rnd, 200, 1000, 66);
  332. }
  333. }
  334. TEST_P(ComparatorDBTest, DoubleComparator) {
  335. SetOwnedComparator(new DoubleComparator());
  336. for (int rnd_seed = 301; rnd_seed < 316; rnd_seed++) {
  337. Options* opt = GetOptions();
  338. opt->comparator = kTestComparator;
  339. DestroyAndReopen();
  340. Random rnd(rnd_seed);
  341. std::vector<std::string> source_strings;
  342. // Randomly generate source keys
  343. for (int i = 0; i < 100; i++) {
  344. uint32_t r = rnd.Next();
  345. uint32_t divide_order = rnd.Uniform(8);
  346. double to_divide = 1.0;
  347. for (uint32_t j = 0; j < divide_order; j++) {
  348. to_divide *= 10.0;
  349. }
  350. source_strings.push_back(ToString(r / to_divide));
  351. }
  352. DoRandomIteraratorTest(GetDB(), source_strings, &rnd, 200, 1000, 66);
  353. }
  354. }
  355. TEST_P(ComparatorDBTest, HashComparator) {
  356. SetOwnedComparator(new HashComparator());
  357. for (int rnd_seed = 301; rnd_seed < 316; rnd_seed++) {
  358. Options* opt = GetOptions();
  359. opt->comparator = kTestComparator;
  360. DestroyAndReopen();
  361. Random rnd(rnd_seed);
  362. std::vector<std::string> source_strings;
  363. // Randomly generate source keys
  364. for (int i = 0; i < 100; i++) {
  365. source_strings.push_back(test::RandomKey(&rnd, 8));
  366. }
  367. DoRandomIteraratorTest(GetDB(), source_strings, &rnd, 200, 1000, 66);
  368. }
  369. }
  370. TEST_P(ComparatorDBTest, TwoStrComparator) {
  371. SetOwnedComparator(new TwoStrComparator());
  372. for (int rnd_seed = 301; rnd_seed < 316; rnd_seed++) {
  373. Options* opt = GetOptions();
  374. opt->comparator = kTestComparator;
  375. DestroyAndReopen();
  376. Random rnd(rnd_seed);
  377. std::vector<std::string> source_strings;
  378. // Randomly generate source keys
  379. for (int i = 0; i < 100; i++) {
  380. std::string str;
  381. uint32_t size1 = rnd.Uniform(8);
  382. uint32_t size2 = rnd.Uniform(8);
  383. str.append(1, static_cast<char>(size1));
  384. str.append(1, static_cast<char>(size2));
  385. str.append(test::RandomKey(&rnd, size1));
  386. str.append(test::RandomKey(&rnd, size2));
  387. source_strings.push_back(str);
  388. }
  389. DoRandomIteraratorTest(GetDB(), source_strings, &rnd, 200, 1000, 66);
  390. }
  391. }
  392. TEST_P(ComparatorDBTest, IsSameLengthImmediateSuccessor) {
  393. {
  394. // different length
  395. Slice s("abcxy");
  396. Slice t("abcxyz");
  397. ASSERT_FALSE(BytewiseComparator()->IsSameLengthImmediateSuccessor(s, t));
  398. }
  399. {
  400. Slice s("abcxyz");
  401. Slice t("abcxy");
  402. ASSERT_FALSE(BytewiseComparator()->IsSameLengthImmediateSuccessor(s, t));
  403. }
  404. {
  405. // not last byte different
  406. Slice s("abc1xyz");
  407. Slice t("abc2xyz");
  408. ASSERT_FALSE(BytewiseComparator()->IsSameLengthImmediateSuccessor(s, t));
  409. }
  410. {
  411. // same string
  412. Slice s("abcxyz");
  413. Slice t("abcxyz");
  414. ASSERT_FALSE(BytewiseComparator()->IsSameLengthImmediateSuccessor(s, t));
  415. }
  416. {
  417. Slice s("abcxy");
  418. Slice t("abcxz");
  419. ASSERT_TRUE(BytewiseComparator()->IsSameLengthImmediateSuccessor(s, t));
  420. }
  421. {
  422. Slice s("abcxz");
  423. Slice t("abcxy");
  424. ASSERT_FALSE(BytewiseComparator()->IsSameLengthImmediateSuccessor(s, t));
  425. }
  426. {
  427. const char s_array[] = "\x50\x8a\xac";
  428. const char t_array[] = "\x50\x8a\xad";
  429. Slice s(s_array);
  430. Slice t(t_array);
  431. ASSERT_TRUE(BytewiseComparator()->IsSameLengthImmediateSuccessor(s, t));
  432. }
  433. {
  434. const char s_array[] = "\x50\x8a\xff";
  435. const char t_array[] = "\x50\x8b\x00";
  436. Slice s(s_array, 3);
  437. Slice t(t_array, 3);
  438. ASSERT_TRUE(BytewiseComparator()->IsSameLengthImmediateSuccessor(s, t));
  439. }
  440. {
  441. const char s_array[] = "\x50\x8a\xff\xff";
  442. const char t_array[] = "\x50\x8b\x00\x00";
  443. Slice s(s_array, 4);
  444. Slice t(t_array, 4);
  445. ASSERT_TRUE(BytewiseComparator()->IsSameLengthImmediateSuccessor(s, t));
  446. }
  447. {
  448. const char s_array[] = "\x50\x8a\xff\xff";
  449. const char t_array[] = "\x50\x8b\x00\x01";
  450. Slice s(s_array, 4);
  451. Slice t(t_array, 4);
  452. ASSERT_FALSE(BytewiseComparator()->IsSameLengthImmediateSuccessor(s, t));
  453. }
  454. }
  455. TEST_P(ComparatorDBTest, FindShortestSeparator) {
  456. std::string s1 = "abc1xyz";
  457. std::string s2 = "abc3xy";
  458. BytewiseComparator()->FindShortestSeparator(&s1, s2);
  459. ASSERT_EQ("abc2", s1);
  460. s1 = "abc5xyztt";
  461. ReverseBytewiseComparator()->FindShortestSeparator(&s1, s2);
  462. ASSERT_EQ("abc5", s1);
  463. s1 = "abc3";
  464. s2 = "abc2xy";
  465. ReverseBytewiseComparator()->FindShortestSeparator(&s1, s2);
  466. ASSERT_EQ("abc3", s1);
  467. s1 = "abc3xyz";
  468. s2 = "abc2xy";
  469. ReverseBytewiseComparator()->FindShortestSeparator(&s1, s2);
  470. ASSERT_EQ("abc3", s1);
  471. s1 = "abc3xyz";
  472. s2 = "abc2";
  473. ReverseBytewiseComparator()->FindShortestSeparator(&s1, s2);
  474. ASSERT_EQ("abc3", s1);
  475. std::string old_s1 = s1 = "abc2xy";
  476. s2 = "abc2";
  477. ReverseBytewiseComparator()->FindShortestSeparator(&s1, s2);
  478. ASSERT_TRUE(old_s1 >= s1);
  479. ASSERT_TRUE(s1 > s2);
  480. }
  481. TEST_P(ComparatorDBTest, SeparatorSuccessorRandomizeTest) {
  482. // Char list for boundary cases.
  483. std::array<unsigned char, 6> char_list{{0, 1, 2, 253, 254, 255}};
  484. Random rnd(301);
  485. for (int attempts = 0; attempts < 1000; attempts++) {
  486. uint32_t size1 = rnd.Skewed(4);
  487. uint32_t size2;
  488. if (rnd.OneIn(2)) {
  489. // size2 to be random size
  490. size2 = rnd.Skewed(4);
  491. } else {
  492. // size1 is within [-2, +2] of size1
  493. int diff = static_cast<int>(rnd.Uniform(5)) - 2;
  494. int tmp_size2 = static_cast<int>(size1) + diff;
  495. if (tmp_size2 < 0) {
  496. tmp_size2 = 0;
  497. }
  498. size2 = static_cast<uint32_t>(tmp_size2);
  499. }
  500. std::string s1;
  501. std::string s2;
  502. for (uint32_t i = 0; i < size1; i++) {
  503. if (rnd.OneIn(2)) {
  504. // Use random byte
  505. s1 += static_cast<char>(rnd.Uniform(256));
  506. } else {
  507. // Use one byte in char_list
  508. char c = static_cast<char>(char_list[rnd.Uniform(sizeof(char_list))]);
  509. s1 += c;
  510. }
  511. }
  512. // First set s2 to be the same as s1, and then modify s2.
  513. s2 = s1;
  514. s2.resize(size2);
  515. // We start from the back of the string
  516. if (size2 > 0) {
  517. uint32_t pos = size2 - 1;
  518. do {
  519. if (pos >= size1 || rnd.OneIn(4)) {
  520. // For 1/4 chance, use random byte
  521. s2[pos] = static_cast<char>(rnd.Uniform(256));
  522. } else if (rnd.OneIn(4)) {
  523. // In 1/4 chance, stop here.
  524. break;
  525. } else {
  526. // Create a char within [-2, +2] of the matching char of s1.
  527. int diff = static_cast<int>(rnd.Uniform(5)) - 2;
  528. // char may be signed or unsigned based on platform.
  529. int s1_char = static_cast<int>(static_cast<unsigned char>(s1[pos]));
  530. int s2_char = s1_char + diff;
  531. if (s2_char < 0) {
  532. s2_char = 0;
  533. }
  534. if (s2_char > 255) {
  535. s2_char = 255;
  536. }
  537. s2[pos] = static_cast<char>(s2_char);
  538. }
  539. } while (pos-- != 0);
  540. }
  541. // Test separators
  542. for (int rev = 0; rev < 2; rev++) {
  543. if (rev == 1) {
  544. // switch s1 and s2
  545. std::string t = s1;
  546. s1 = s2;
  547. s2 = t;
  548. }
  549. std::string separator = s1;
  550. BytewiseComparator()->FindShortestSeparator(&separator, s2);
  551. std::string rev_separator = s1;
  552. ReverseBytewiseComparator()->FindShortestSeparator(&rev_separator, s2);
  553. if (s1 == s2) {
  554. ASSERT_EQ(s1, separator);
  555. ASSERT_EQ(s2, rev_separator);
  556. } else if (s1 < s2) {
  557. ASSERT_TRUE(s1 <= separator);
  558. ASSERT_TRUE(s2 > separator);
  559. ASSERT_LE(separator.size(), std::max(s1.size(), s2.size()));
  560. ASSERT_EQ(s1, rev_separator);
  561. } else {
  562. ASSERT_TRUE(s1 >= rev_separator);
  563. ASSERT_TRUE(s2 < rev_separator);
  564. ASSERT_LE(rev_separator.size(), std::max(s1.size(), s2.size()));
  565. ASSERT_EQ(s1, separator);
  566. }
  567. }
  568. // Test successors
  569. std::string succ = s1;
  570. BytewiseComparator()->FindShortSuccessor(&succ);
  571. ASSERT_TRUE(succ >= s1);
  572. succ = s1;
  573. ReverseBytewiseComparator()->FindShortSuccessor(&succ);
  574. ASSERT_TRUE(succ <= s1);
  575. }
  576. }
  577. } // namespace ROCKSDB_NAMESPACE
  578. int main(int argc, char** argv) {
  579. ::testing::InitGoogleTest(&argc, argv);
  580. return RUN_ALL_TESTS();
  581. }