range_del_aggregator_test.cc 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. // Copyright (c) 2018-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 "db/range_del_aggregator.h"
  6. #include <memory>
  7. #include <string>
  8. #include <vector>
  9. #include "db/db_test_util.h"
  10. #include "db/dbformat.h"
  11. #include "db/range_tombstone_fragmenter.h"
  12. #include "test_util/testutil.h"
  13. #include "util/vector_iterator.h"
  14. namespace ROCKSDB_NAMESPACE {
  15. class RangeDelAggregatorTest : public testing::Test {};
  16. namespace {
  17. static auto bytewise_icmp = InternalKeyComparator(BytewiseComparator());
  18. std::unique_ptr<InternalIterator> MakeRangeDelIter(
  19. const std::vector<RangeTombstone>& range_dels) {
  20. std::vector<std::string> keys, values;
  21. for (const auto& range_del : range_dels) {
  22. auto key_and_value = range_del.Serialize();
  23. keys.push_back(key_and_value.first.Encode().ToString());
  24. values.push_back(key_and_value.second.ToString());
  25. }
  26. return std::unique_ptr<VectorIterator>(
  27. new VectorIterator(keys, values, &bytewise_icmp));
  28. }
  29. std::vector<std::unique_ptr<FragmentedRangeTombstoneList>>
  30. MakeFragmentedTombstoneLists(
  31. const std::vector<std::vector<RangeTombstone>>& range_dels_list) {
  32. std::vector<std::unique_ptr<FragmentedRangeTombstoneList>> fragment_lists;
  33. for (const auto& range_dels : range_dels_list) {
  34. auto range_del_iter = MakeRangeDelIter(range_dels);
  35. fragment_lists.emplace_back(new FragmentedRangeTombstoneList(
  36. std::move(range_del_iter), bytewise_icmp));
  37. }
  38. return fragment_lists;
  39. }
  40. struct TruncatedIterScanTestCase {
  41. ParsedInternalKey start;
  42. ParsedInternalKey end;
  43. SequenceNumber seq;
  44. };
  45. struct TruncatedIterSeekTestCase {
  46. Slice target;
  47. ParsedInternalKey start;
  48. ParsedInternalKey end;
  49. SequenceNumber seq;
  50. bool invalid;
  51. };
  52. struct ShouldDeleteTestCase {
  53. ParsedInternalKey lookup_key;
  54. bool result;
  55. };
  56. struct IsRangeOverlappedTestCase {
  57. Slice start;
  58. Slice end;
  59. bool result;
  60. };
  61. ParsedInternalKey UncutEndpoint(const Slice& s) {
  62. return ParsedInternalKey(s, kMaxSequenceNumber, kTypeRangeDeletion);
  63. }
  64. ParsedInternalKey InternalValue(const Slice& key, SequenceNumber seq,
  65. ValueType type = kTypeValue) {
  66. return ParsedInternalKey(key, seq, type);
  67. }
  68. void VerifyIterator(
  69. TruncatedRangeDelIterator* iter, const InternalKeyComparator& icmp,
  70. const std::vector<TruncatedIterScanTestCase>& expected_range_dels) {
  71. // Test forward iteration.
  72. iter->SeekToFirst();
  73. for (size_t i = 0; i < expected_range_dels.size(); i++, iter->Next()) {
  74. ASSERT_TRUE(iter->Valid());
  75. EXPECT_EQ(0, icmp.Compare(iter->start_key(), expected_range_dels[i].start));
  76. EXPECT_EQ(0, icmp.Compare(iter->end_key(), expected_range_dels[i].end));
  77. EXPECT_EQ(expected_range_dels[i].seq, iter->seq());
  78. }
  79. EXPECT_FALSE(iter->Valid());
  80. // Test reverse iteration.
  81. iter->SeekToLast();
  82. std::vector<TruncatedIterScanTestCase> reverse_expected_range_dels(
  83. expected_range_dels.rbegin(), expected_range_dels.rend());
  84. for (size_t i = 0; i < reverse_expected_range_dels.size();
  85. i++, iter->Prev()) {
  86. ASSERT_TRUE(iter->Valid());
  87. EXPECT_EQ(0, icmp.Compare(iter->start_key(),
  88. reverse_expected_range_dels[i].start));
  89. EXPECT_EQ(
  90. 0, icmp.Compare(iter->end_key(), reverse_expected_range_dels[i].end));
  91. EXPECT_EQ(reverse_expected_range_dels[i].seq, iter->seq());
  92. }
  93. EXPECT_FALSE(iter->Valid());
  94. }
  95. void VerifySeek(TruncatedRangeDelIterator* iter,
  96. const InternalKeyComparator& icmp,
  97. const std::vector<TruncatedIterSeekTestCase>& test_cases) {
  98. for (const auto& test_case : test_cases) {
  99. iter->Seek(test_case.target);
  100. if (test_case.invalid) {
  101. ASSERT_FALSE(iter->Valid());
  102. } else {
  103. ASSERT_TRUE(iter->Valid());
  104. EXPECT_EQ(0, icmp.Compare(iter->start_key(), test_case.start));
  105. EXPECT_EQ(0, icmp.Compare(iter->end_key(), test_case.end));
  106. EXPECT_EQ(test_case.seq, iter->seq());
  107. }
  108. }
  109. }
  110. void VerifySeekForPrev(
  111. TruncatedRangeDelIterator* iter, const InternalKeyComparator& icmp,
  112. const std::vector<TruncatedIterSeekTestCase>& test_cases) {
  113. for (const auto& test_case : test_cases) {
  114. iter->SeekForPrev(test_case.target);
  115. if (test_case.invalid) {
  116. ASSERT_FALSE(iter->Valid());
  117. } else {
  118. ASSERT_TRUE(iter->Valid());
  119. EXPECT_EQ(0, icmp.Compare(iter->start_key(), test_case.start));
  120. EXPECT_EQ(0, icmp.Compare(iter->end_key(), test_case.end));
  121. EXPECT_EQ(test_case.seq, iter->seq());
  122. }
  123. }
  124. }
  125. void VerifyShouldDelete(RangeDelAggregator* range_del_agg,
  126. const std::vector<ShouldDeleteTestCase>& test_cases) {
  127. for (const auto& test_case : test_cases) {
  128. EXPECT_EQ(
  129. test_case.result,
  130. range_del_agg->ShouldDelete(
  131. test_case.lookup_key, RangeDelPositioningMode::kForwardTraversal));
  132. }
  133. for (auto it = test_cases.rbegin(); it != test_cases.rend(); ++it) {
  134. const auto& test_case = *it;
  135. EXPECT_EQ(
  136. test_case.result,
  137. range_del_agg->ShouldDelete(
  138. test_case.lookup_key, RangeDelPositioningMode::kBackwardTraversal));
  139. }
  140. }
  141. void VerifyIsRangeOverlapped(
  142. ReadRangeDelAggregator* range_del_agg,
  143. const std::vector<IsRangeOverlappedTestCase>& test_cases) {
  144. for (const auto& test_case : test_cases) {
  145. EXPECT_EQ(test_case.result,
  146. range_del_agg->IsRangeOverlapped(test_case.start, test_case.end));
  147. }
  148. }
  149. void CheckIterPosition(const RangeTombstone& tombstone,
  150. const FragmentedRangeTombstoneIterator* iter) {
  151. // Test InternalIterator interface.
  152. EXPECT_EQ(tombstone.start_key_, ExtractUserKey(iter->key()));
  153. EXPECT_EQ(tombstone.end_key_, iter->value());
  154. EXPECT_EQ(tombstone.seq_, iter->seq());
  155. // Test FragmentedRangeTombstoneIterator interface.
  156. EXPECT_EQ(tombstone.start_key_, iter->start_key());
  157. EXPECT_EQ(tombstone.end_key_, iter->end_key());
  158. EXPECT_EQ(tombstone.seq_, GetInternalKeySeqno(iter->key()));
  159. }
  160. void VerifyFragmentedRangeDels(
  161. FragmentedRangeTombstoneIterator* iter,
  162. const std::vector<RangeTombstone>& expected_tombstones) {
  163. iter->SeekToFirst();
  164. for (size_t i = 0; i < expected_tombstones.size(); i++, iter->Next()) {
  165. ASSERT_TRUE(iter->Valid());
  166. CheckIterPosition(expected_tombstones[i], iter);
  167. }
  168. EXPECT_FALSE(iter->Valid());
  169. }
  170. } // anonymous namespace
  171. TEST_F(RangeDelAggregatorTest, EmptyTruncatedIter) {
  172. auto range_del_iter = MakeRangeDelIter({});
  173. FragmentedRangeTombstoneList fragment_list(std::move(range_del_iter),
  174. bytewise_icmp);
  175. std::unique_ptr<FragmentedRangeTombstoneIterator> input_iter(
  176. new FragmentedRangeTombstoneIterator(&fragment_list, bytewise_icmp,
  177. kMaxSequenceNumber));
  178. TruncatedRangeDelIterator iter(std::move(input_iter), &bytewise_icmp, nullptr,
  179. nullptr);
  180. iter.SeekToFirst();
  181. ASSERT_FALSE(iter.Valid());
  182. iter.SeekToLast();
  183. ASSERT_FALSE(iter.Valid());
  184. }
  185. TEST_F(RangeDelAggregatorTest, UntruncatedIter) {
  186. auto range_del_iter =
  187. MakeRangeDelIter({{"a", "e", 10}, {"e", "g", 8}, {"j", "n", 4}});
  188. FragmentedRangeTombstoneList fragment_list(std::move(range_del_iter),
  189. bytewise_icmp);
  190. std::unique_ptr<FragmentedRangeTombstoneIterator> input_iter(
  191. new FragmentedRangeTombstoneIterator(&fragment_list, bytewise_icmp,
  192. kMaxSequenceNumber));
  193. TruncatedRangeDelIterator iter(std::move(input_iter), &bytewise_icmp, nullptr,
  194. nullptr);
  195. VerifyIterator(
  196. &iter, bytewise_icmp,
  197. {{InternalValue("a", 10, kTypeRangeDeletion), UncutEndpoint("e"), 10},
  198. {InternalValue("e", 8, kTypeRangeDeletion), UncutEndpoint("g"), 8},
  199. {InternalValue("j", 4, kTypeRangeDeletion), UncutEndpoint("n"), 4}});
  200. VerifySeek(
  201. &iter, bytewise_icmp,
  202. {{"d", InternalValue("a", 10, kTypeRangeDeletion), UncutEndpoint("e"),
  203. 10},
  204. {"e", InternalValue("e", 8, kTypeRangeDeletion), UncutEndpoint("g"), 8},
  205. {"ia", InternalValue("j", 4, kTypeRangeDeletion), UncutEndpoint("n"), 4},
  206. {"n", InternalValue("", 0, kTypeRangeDeletion), UncutEndpoint(""), 0,
  207. true /* invalid */},
  208. {"", InternalValue("a", 10, kTypeRangeDeletion), UncutEndpoint("e"),
  209. 10}});
  210. VerifySeekForPrev(
  211. &iter, bytewise_icmp,
  212. {{"d", InternalValue("a", 10, kTypeRangeDeletion), UncutEndpoint("e"),
  213. 10},
  214. {"e", InternalValue("e", 8, kTypeRangeDeletion), UncutEndpoint("g"), 8},
  215. {"ia", InternalValue("e", 8, kTypeRangeDeletion), UncutEndpoint("g"), 8},
  216. {"n", InternalValue("j", 4, kTypeRangeDeletion), UncutEndpoint("n"), 4},
  217. {"", InternalValue("", 0, kTypeRangeDeletion), UncutEndpoint(""), 0,
  218. true /* invalid */}});
  219. }
  220. TEST_F(RangeDelAggregatorTest, UntruncatedIterWithSnapshot) {
  221. auto range_del_iter =
  222. MakeRangeDelIter({{"a", "e", 10}, {"e", "g", 8}, {"j", "n", 4}});
  223. FragmentedRangeTombstoneList fragment_list(std::move(range_del_iter),
  224. bytewise_icmp);
  225. std::unique_ptr<FragmentedRangeTombstoneIterator> input_iter(
  226. new FragmentedRangeTombstoneIterator(&fragment_list, bytewise_icmp,
  227. 9 /* snapshot */));
  228. TruncatedRangeDelIterator iter(std::move(input_iter), &bytewise_icmp, nullptr,
  229. nullptr);
  230. VerifyIterator(
  231. &iter, bytewise_icmp,
  232. {{InternalValue("e", 8, kTypeRangeDeletion), UncutEndpoint("g"), 8},
  233. {InternalValue("j", 4, kTypeRangeDeletion), UncutEndpoint("n"), 4}});
  234. VerifySeek(
  235. &iter, bytewise_icmp,
  236. {{"d", InternalValue("e", 8, kTypeRangeDeletion), UncutEndpoint("g"), 8},
  237. {"e", InternalValue("e", 8, kTypeRangeDeletion), UncutEndpoint("g"), 8},
  238. {"ia", InternalValue("j", 4, kTypeRangeDeletion), UncutEndpoint("n"), 4},
  239. {"n", InternalValue("", 0, kTypeRangeDeletion), UncutEndpoint(""), 0,
  240. true /* invalid */},
  241. {"", InternalValue("e", 8, kTypeRangeDeletion), UncutEndpoint("g"), 8}});
  242. VerifySeekForPrev(
  243. &iter, bytewise_icmp,
  244. {{"d", InternalValue("", 0, kTypeRangeDeletion), UncutEndpoint(""), 0,
  245. true /* invalid */},
  246. {"e", InternalValue("e", 8, kTypeRangeDeletion), UncutEndpoint("g"), 8},
  247. {"ia", InternalValue("e", 8, kTypeRangeDeletion), UncutEndpoint("g"), 8},
  248. {"n", InternalValue("j", 4, kTypeRangeDeletion), UncutEndpoint("n"), 4},
  249. {"", InternalValue("", 0, kTypeRangeDeletion), UncutEndpoint(""), 0,
  250. true /* invalid */}});
  251. }
  252. TEST_F(RangeDelAggregatorTest, TruncatedIterPartiallyCutTombstones) {
  253. auto range_del_iter =
  254. MakeRangeDelIter({{"a", "e", 10}, {"e", "g", 8}, {"j", "n", 4}});
  255. FragmentedRangeTombstoneList fragment_list(std::move(range_del_iter),
  256. bytewise_icmp);
  257. std::unique_ptr<FragmentedRangeTombstoneIterator> input_iter(
  258. new FragmentedRangeTombstoneIterator(&fragment_list, bytewise_icmp,
  259. kMaxSequenceNumber));
  260. InternalKey smallest("d", 7, kTypeValue);
  261. InternalKey largest("m", 9, kTypeValue);
  262. TruncatedRangeDelIterator iter(std::move(input_iter), &bytewise_icmp,
  263. &smallest, &largest);
  264. VerifyIterator(
  265. &iter, bytewise_icmp,
  266. {{InternalValue("d", 7, kTypeMaxValid), UncutEndpoint("e"), 10},
  267. {InternalValue("e", 8, kTypeRangeDeletion), UncutEndpoint("g"), 8},
  268. {InternalValue("j", 4, kTypeRangeDeletion),
  269. InternalValue("m", 8, kTypeMaxValid), 4}});
  270. VerifySeek(
  271. &iter, bytewise_icmp,
  272. {{"d", InternalValue("d", 7, kTypeMaxValid), UncutEndpoint("e"), 10},
  273. {"e", InternalValue("e", 8, kTypeRangeDeletion), UncutEndpoint("g"), 8},
  274. {"ia", InternalValue("j", 4, kTypeRangeDeletion),
  275. InternalValue("m", 8, kTypeMaxValid), 4, false /* invalid */},
  276. {"n", InternalValue("", 0, kTypeRangeDeletion), UncutEndpoint(""), 0,
  277. true /* invalid */},
  278. {"", InternalValue("d", 7, kTypeMaxValid), UncutEndpoint("e"), 10}});
  279. VerifySeekForPrev(
  280. &iter, bytewise_icmp,
  281. {{"d", InternalValue("d", 7, kTypeMaxValid), UncutEndpoint("e"), 10},
  282. {"e", InternalValue("e", 8, kTypeRangeDeletion), UncutEndpoint("g"), 8},
  283. {"ia", InternalValue("e", 8, kTypeRangeDeletion), UncutEndpoint("g"), 8},
  284. {"n", InternalValue("j", 4, kTypeRangeDeletion),
  285. InternalValue("m", 8, kTypeMaxValid), 4, false /* invalid */},
  286. {"", InternalValue("", 0, kTypeRangeDeletion), UncutEndpoint(""), 0,
  287. true /* invalid */}});
  288. }
  289. TEST_F(RangeDelAggregatorTest, TruncatedIterFullyCutTombstones) {
  290. auto range_del_iter =
  291. MakeRangeDelIter({{"a", "e", 10}, {"e", "g", 8}, {"j", "n", 4}});
  292. FragmentedRangeTombstoneList fragment_list(std::move(range_del_iter),
  293. bytewise_icmp);
  294. std::unique_ptr<FragmentedRangeTombstoneIterator> input_iter(
  295. new FragmentedRangeTombstoneIterator(&fragment_list, bytewise_icmp,
  296. kMaxSequenceNumber));
  297. InternalKey smallest("f", 7, kTypeValue);
  298. InternalKey largest("i", 9, kTypeValue);
  299. TruncatedRangeDelIterator iter(std::move(input_iter), &bytewise_icmp,
  300. &smallest, &largest);
  301. VerifyIterator(
  302. &iter, bytewise_icmp,
  303. {{InternalValue("f", 7, kTypeMaxValid), UncutEndpoint("g"), 8}});
  304. VerifySeek(
  305. &iter, bytewise_icmp,
  306. {{"d", InternalValue("f", 7, kTypeMaxValid), UncutEndpoint("g"), 8},
  307. {"f", InternalValue("f", 7, kTypeMaxValid), UncutEndpoint("g"), 8},
  308. {"j", InternalValue("", 0, kTypeRangeDeletion), UncutEndpoint(""), 0,
  309. true /* invalid */}});
  310. VerifySeekForPrev(
  311. &iter, bytewise_icmp,
  312. {{"d", InternalValue("", 0, kTypeRangeDeletion), UncutEndpoint(""), 0,
  313. true /* invalid */},
  314. {"f", InternalValue("f", 7, kTypeMaxValid), UncutEndpoint("g"), 8},
  315. {"j", InternalValue("f", 7, kTypeMaxValid), UncutEndpoint("g"), 8}});
  316. }
  317. TEST_F(RangeDelAggregatorTest, SingleIterInAggregator) {
  318. auto range_del_iter = MakeRangeDelIter({{"a", "e", 10}, {"c", "g", 8}});
  319. FragmentedRangeTombstoneList fragment_list(std::move(range_del_iter),
  320. bytewise_icmp);
  321. std::unique_ptr<FragmentedRangeTombstoneIterator> input_iter(
  322. new FragmentedRangeTombstoneIterator(&fragment_list, bytewise_icmp,
  323. kMaxSequenceNumber));
  324. ReadRangeDelAggregator range_del_agg(&bytewise_icmp, kMaxSequenceNumber);
  325. range_del_agg.AddTombstones(std::move(input_iter));
  326. VerifyShouldDelete(&range_del_agg, {{InternalValue("a", 19), false},
  327. {InternalValue("b", 9), true},
  328. {InternalValue("d", 9), true},
  329. {InternalValue("e", 7), true},
  330. {InternalValue("g", 7), false}});
  331. VerifyIsRangeOverlapped(&range_del_agg, {{"", "_", false},
  332. {"_", "a", true},
  333. {"a", "c", true},
  334. {"d", "f", true},
  335. {"g", "l", false}});
  336. }
  337. TEST_F(RangeDelAggregatorTest, MultipleItersInAggregator) {
  338. auto fragment_lists = MakeFragmentedTombstoneLists(
  339. {{{"a", "e", 10}, {"c", "g", 8}},
  340. {{"a", "b", 20}, {"h", "i", 25}, {"ii", "j", 15}}});
  341. ReadRangeDelAggregator range_del_agg(&bytewise_icmp, kMaxSequenceNumber);
  342. for (const auto& fragment_list : fragment_lists) {
  343. std::unique_ptr<FragmentedRangeTombstoneIterator> input_iter(
  344. new FragmentedRangeTombstoneIterator(fragment_list.get(), bytewise_icmp,
  345. kMaxSequenceNumber));
  346. range_del_agg.AddTombstones(std::move(input_iter));
  347. }
  348. VerifyShouldDelete(&range_del_agg, {{InternalValue("a", 19), true},
  349. {InternalValue("b", 19), false},
  350. {InternalValue("b", 9), true},
  351. {InternalValue("d", 9), true},
  352. {InternalValue("e", 7), true},
  353. {InternalValue("g", 7), false},
  354. {InternalValue("h", 24), true},
  355. {InternalValue("i", 24), false},
  356. {InternalValue("ii", 14), true},
  357. {InternalValue("j", 14), false}});
  358. VerifyIsRangeOverlapped(&range_del_agg, {{"", "_", false},
  359. {"_", "a", true},
  360. {"a", "c", true},
  361. {"d", "f", true},
  362. {"g", "l", true},
  363. {"x", "y", false}});
  364. }
  365. TEST_F(RangeDelAggregatorTest, MultipleItersInAggregatorWithUpperBound) {
  366. auto fragment_lists = MakeFragmentedTombstoneLists(
  367. {{{"a", "e", 10}, {"c", "g", 8}},
  368. {{"a", "b", 20}, {"h", "i", 25}, {"ii", "j", 15}}});
  369. ReadRangeDelAggregator range_del_agg(&bytewise_icmp, 19);
  370. for (const auto& fragment_list : fragment_lists) {
  371. std::unique_ptr<FragmentedRangeTombstoneIterator> input_iter(
  372. new FragmentedRangeTombstoneIterator(fragment_list.get(), bytewise_icmp,
  373. 19 /* snapshot */));
  374. range_del_agg.AddTombstones(std::move(input_iter));
  375. }
  376. VerifyShouldDelete(&range_del_agg, {{InternalValue("a", 19), false},
  377. {InternalValue("a", 9), true},
  378. {InternalValue("b", 9), true},
  379. {InternalValue("d", 9), true},
  380. {InternalValue("e", 7), true},
  381. {InternalValue("g", 7), false},
  382. {InternalValue("h", 24), false},
  383. {InternalValue("i", 24), false},
  384. {InternalValue("ii", 14), true},
  385. {InternalValue("j", 14), false}});
  386. VerifyIsRangeOverlapped(&range_del_agg, {{"", "_", false},
  387. {"_", "a", true},
  388. {"a", "c", true},
  389. {"d", "f", true},
  390. {"g", "l", true},
  391. {"x", "y", false}});
  392. }
  393. TEST_F(RangeDelAggregatorTest, MultipleTruncatedItersInAggregator) {
  394. auto fragment_lists = MakeFragmentedTombstoneLists(
  395. {{{"a", "z", 10}}, {{"a", "z", 10}}, {{"a", "z", 10}}});
  396. std::vector<std::pair<InternalKey, InternalKey>> iter_bounds = {
  397. {InternalKey("a", 4, kTypeValue),
  398. InternalKey("m", kMaxSequenceNumber, kTypeRangeDeletion)},
  399. {InternalKey("m", 20, kTypeValue),
  400. InternalKey("x", kMaxSequenceNumber, kTypeRangeDeletion)},
  401. {InternalKey("x", 5, kTypeValue), InternalKey("zz", 30, kTypeValue)}};
  402. ReadRangeDelAggregator range_del_agg(&bytewise_icmp, 19);
  403. for (size_t i = 0; i < fragment_lists.size(); i++) {
  404. const auto& fragment_list = fragment_lists[i];
  405. const auto& bounds = iter_bounds[i];
  406. std::unique_ptr<FragmentedRangeTombstoneIterator> input_iter(
  407. new FragmentedRangeTombstoneIterator(fragment_list.get(), bytewise_icmp,
  408. 19 /* snapshot */));
  409. range_del_agg.AddTombstones(std::move(input_iter), &bounds.first,
  410. &bounds.second);
  411. }
  412. VerifyShouldDelete(&range_del_agg, {{InternalValue("a", 10), false},
  413. {InternalValue("a", 9), false},
  414. {InternalValue("a", 4), true},
  415. {InternalValue("m", 10), false},
  416. {InternalValue("m", 9), true},
  417. {InternalValue("x", 10), false},
  418. {InternalValue("x", 9), false},
  419. {InternalValue("x", 5), true},
  420. {InternalValue("z", 9), false}});
  421. VerifyIsRangeOverlapped(&range_del_agg, {{"", "_", false},
  422. {"_", "a", true},
  423. {"a", "n", true},
  424. {"l", "x", true},
  425. {"w", "z", true},
  426. {"zzz", "zz", false},
  427. {"zz", "zzz", false}});
  428. }
  429. TEST_F(RangeDelAggregatorTest, MultipleTruncatedItersInAggregatorSameLevel) {
  430. auto fragment_lists = MakeFragmentedTombstoneLists(
  431. {{{"a", "z", 10}}, {{"a", "z", 10}}, {{"a", "z", 10}}});
  432. std::vector<std::pair<InternalKey, InternalKey>> iter_bounds = {
  433. {InternalKey("a", 4, kTypeValue),
  434. InternalKey("m", kMaxSequenceNumber, kTypeRangeDeletion)},
  435. {InternalKey("m", 20, kTypeValue),
  436. InternalKey("x", kMaxSequenceNumber, kTypeRangeDeletion)},
  437. {InternalKey("x", 5, kTypeValue), InternalKey("zz", 30, kTypeValue)}};
  438. ReadRangeDelAggregator range_del_agg(&bytewise_icmp, 19);
  439. auto add_iter_to_agg = [&](size_t i) {
  440. std::unique_ptr<FragmentedRangeTombstoneIterator> input_iter(
  441. new FragmentedRangeTombstoneIterator(fragment_lists[i].get(),
  442. bytewise_icmp, 19 /* snapshot */));
  443. range_del_agg.AddTombstones(std::move(input_iter), &iter_bounds[i].first,
  444. &iter_bounds[i].second);
  445. };
  446. add_iter_to_agg(0);
  447. VerifyShouldDelete(&range_del_agg, {{InternalValue("a", 10), false},
  448. {InternalValue("a", 9), false},
  449. {InternalValue("a", 4), true}});
  450. add_iter_to_agg(1);
  451. VerifyShouldDelete(&range_del_agg, {{InternalValue("m", 10), false},
  452. {InternalValue("m", 9), true}});
  453. add_iter_to_agg(2);
  454. VerifyShouldDelete(&range_del_agg, {{InternalValue("x", 10), false},
  455. {InternalValue("x", 9), false},
  456. {InternalValue("x", 5), true},
  457. {InternalValue("z", 9), false}});
  458. VerifyIsRangeOverlapped(&range_del_agg, {{"", "_", false},
  459. {"_", "a", true},
  460. {"a", "n", true},
  461. {"l", "x", true},
  462. {"w", "z", true},
  463. {"zzz", "zz", false},
  464. {"zz", "zzz", false}});
  465. }
  466. TEST_F(RangeDelAggregatorTest, CompactionAggregatorNoSnapshots) {
  467. auto fragment_lists = MakeFragmentedTombstoneLists(
  468. {{{"a", "e", 10}, {"c", "g", 8}},
  469. {{"a", "b", 20}, {"h", "i", 25}, {"ii", "j", 15}}});
  470. std::vector<SequenceNumber> snapshots;
  471. CompactionRangeDelAggregator range_del_agg(&bytewise_icmp, snapshots);
  472. for (const auto& fragment_list : fragment_lists) {
  473. std::unique_ptr<FragmentedRangeTombstoneIterator> input_iter(
  474. new FragmentedRangeTombstoneIterator(fragment_list.get(), bytewise_icmp,
  475. kMaxSequenceNumber));
  476. range_del_agg.AddTombstones(std::move(input_iter));
  477. }
  478. VerifyShouldDelete(&range_del_agg, {{InternalValue("a", 19), true},
  479. {InternalValue("b", 19), false},
  480. {InternalValue("b", 9), true},
  481. {InternalValue("d", 9), true},
  482. {InternalValue("e", 7), true},
  483. {InternalValue("g", 7), false},
  484. {InternalValue("h", 24), true},
  485. {InternalValue("i", 24), false},
  486. {InternalValue("ii", 14), true},
  487. {InternalValue("j", 14), false}});
  488. auto range_del_compaction_iter = range_del_agg.NewIterator();
  489. VerifyFragmentedRangeDels(range_del_compaction_iter.get(), {{"a", "b", 20},
  490. {"b", "c", 10},
  491. {"c", "e", 10},
  492. {"e", "g", 8},
  493. {"h", "i", 25},
  494. {"ii", "j", 15}});
  495. }
  496. TEST_F(RangeDelAggregatorTest, CompactionAggregatorWithSnapshots) {
  497. auto fragment_lists = MakeFragmentedTombstoneLists(
  498. {{{"a", "e", 10}, {"c", "g", 8}},
  499. {{"a", "b", 20}, {"h", "i", 25}, {"ii", "j", 15}}});
  500. std::vector<SequenceNumber> snapshots{9, 19};
  501. CompactionRangeDelAggregator range_del_agg(&bytewise_icmp, snapshots);
  502. for (const auto& fragment_list : fragment_lists) {
  503. std::unique_ptr<FragmentedRangeTombstoneIterator> input_iter(
  504. new FragmentedRangeTombstoneIterator(fragment_list.get(), bytewise_icmp,
  505. kMaxSequenceNumber));
  506. range_del_agg.AddTombstones(std::move(input_iter));
  507. }
  508. VerifyShouldDelete(
  509. &range_del_agg,
  510. {
  511. {InternalValue("a", 19), false}, // [10, 19]
  512. {InternalValue("a", 9), false}, // [0, 9]
  513. {InternalValue("b", 9), false}, // [0, 9]
  514. {InternalValue("d", 9), false}, // [0, 9]
  515. {InternalValue("d", 7), true}, // [0, 9]
  516. {InternalValue("e", 7), true}, // [0, 9]
  517. {InternalValue("g", 7), false}, // [0, 9]
  518. {InternalValue("h", 24), true}, // [20, kMaxSequenceNumber]
  519. {InternalValue("i", 24), false}, // [20, kMaxSequenceNumber]
  520. {InternalValue("ii", 14), true}, // [10, 19]
  521. {InternalValue("j", 14), false} // [10, 19]
  522. });
  523. auto range_del_compaction_iter = range_del_agg.NewIterator();
  524. VerifyFragmentedRangeDels(range_del_compaction_iter.get(), {{"a", "b", 20},
  525. {"a", "b", 10},
  526. {"b", "c", 10},
  527. {"c", "e", 10},
  528. {"c", "e", 8},
  529. {"e", "g", 8},
  530. {"h", "i", 25},
  531. {"ii", "j", 15}});
  532. }
  533. TEST_F(RangeDelAggregatorTest, CompactionAggregatorEmptyIteratorLeft) {
  534. auto fragment_lists = MakeFragmentedTombstoneLists(
  535. {{{"a", "e", 10}, {"c", "g", 8}},
  536. {{"a", "b", 20}, {"h", "i", 25}, {"ii", "j", 15}}});
  537. std::vector<SequenceNumber> snapshots{9, 19};
  538. CompactionRangeDelAggregator range_del_agg(&bytewise_icmp, snapshots);
  539. for (const auto& fragment_list : fragment_lists) {
  540. std::unique_ptr<FragmentedRangeTombstoneIterator> input_iter(
  541. new FragmentedRangeTombstoneIterator(fragment_list.get(), bytewise_icmp,
  542. kMaxSequenceNumber));
  543. range_del_agg.AddTombstones(std::move(input_iter));
  544. }
  545. Slice start("_");
  546. Slice end("__");
  547. }
  548. TEST_F(RangeDelAggregatorTest, CompactionAggregatorEmptyIteratorRight) {
  549. auto fragment_lists = MakeFragmentedTombstoneLists(
  550. {{{"a", "e", 10}, {"c", "g", 8}},
  551. {{"a", "b", 20}, {"h", "i", 25}, {"ii", "j", 15}}});
  552. std::vector<SequenceNumber> snapshots{9, 19};
  553. CompactionRangeDelAggregator range_del_agg(&bytewise_icmp, snapshots);
  554. for (const auto& fragment_list : fragment_lists) {
  555. std::unique_ptr<FragmentedRangeTombstoneIterator> input_iter(
  556. new FragmentedRangeTombstoneIterator(fragment_list.get(), bytewise_icmp,
  557. kMaxSequenceNumber));
  558. range_del_agg.AddTombstones(std::move(input_iter));
  559. }
  560. InternalKey start_buf("p", 0, kTypeRangeDeletion);
  561. InternalKey end_buf("q", 0, kTypeRangeDeletion);
  562. Slice start = start_buf.Encode();
  563. Slice end = end_buf.Encode();
  564. auto range_del_compaction_iter = range_del_agg.NewIterator(&start, &end);
  565. VerifyFragmentedRangeDels(range_del_compaction_iter.get(), {});
  566. }
  567. TEST_F(RangeDelAggregatorTest, CompactionAggregatorBoundedIterator) {
  568. auto fragment_lists = MakeFragmentedTombstoneLists(
  569. {{{"a", "e", 10}, {"c", "g", 8}},
  570. {{"a", "b", 20}, {"h", "i", 25}, {"ii", "j", 15}}});
  571. std::vector<SequenceNumber> snapshots{9, 19};
  572. CompactionRangeDelAggregator range_del_agg(&bytewise_icmp, snapshots);
  573. for (const auto& fragment_list : fragment_lists) {
  574. std::unique_ptr<FragmentedRangeTombstoneIterator> input_iter(
  575. new FragmentedRangeTombstoneIterator(fragment_list.get(), bytewise_icmp,
  576. kMaxSequenceNumber));
  577. range_del_agg.AddTombstones(std::move(input_iter));
  578. }
  579. InternalKey start_buf("bb", 0, kTypeRangeDeletion);
  580. InternalKey end_buf("e", 9, kTypeRangeDeletion);
  581. Slice start = start_buf.Encode();
  582. Slice end = end_buf.Encode();
  583. auto range_del_compaction_iter = range_del_agg.NewIterator(&start, &end);
  584. VerifyFragmentedRangeDels(range_del_compaction_iter.get(),
  585. {{"a", "c", 10}, {"c", "e", 10}, {"c", "e", 8}});
  586. }
  587. TEST_F(RangeDelAggregatorTest,
  588. CompactionAggregatorBoundedIteratorExtraFragments) {
  589. auto fragment_lists = MakeFragmentedTombstoneLists(
  590. {{{"a", "d", 10}, {"c", "g", 8}},
  591. {{"b", "c", 20}, {"d", "f", 30}, {"h", "i", 25}, {"ii", "j", 15}}});
  592. std::vector<SequenceNumber> snapshots{9, 19};
  593. CompactionRangeDelAggregator range_del_agg(&bytewise_icmp, snapshots);
  594. for (const auto& fragment_list : fragment_lists) {
  595. std::unique_ptr<FragmentedRangeTombstoneIterator> input_iter(
  596. new FragmentedRangeTombstoneIterator(fragment_list.get(), bytewise_icmp,
  597. kMaxSequenceNumber));
  598. range_del_agg.AddTombstones(std::move(input_iter));
  599. }
  600. InternalKey start_buf("bb", 0, kTypeRangeDeletion);
  601. InternalKey end_buf("e", 0, kTypeRangeDeletion);
  602. Slice start = start_buf.Encode();
  603. Slice end = end_buf.Encode();
  604. auto range_del_compaction_iter = range_del_agg.NewIterator(&start, &end);
  605. VerifyFragmentedRangeDels(range_del_compaction_iter.get(), {{"a", "b", 10},
  606. {"b", "c", 20},
  607. {"b", "c", 10},
  608. {"c", "d", 10},
  609. {"c", "d", 8},
  610. {"d", "f", 30},
  611. {"d", "f", 8},
  612. {"f", "g", 8}});
  613. }
  614. } // namespace ROCKSDB_NAMESPACE
  615. int main(int argc, char** argv) {
  616. ROCKSDB_NAMESPACE::port::InstallStackTraceHandler();
  617. ::testing::InitGoogleTest(&argc, argv);
  618. return RUN_ALL_TESTS();
  619. }