range_del_aggregator_test.cc 31 KB

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