multi_cf_iterator_test.cc 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173
  1. // Copyright (c) Meta Platforms, Inc. and affiliates.
  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/db_test_util.h"
  6. #include "rocksdb/attribute_groups.h"
  7. namespace ROCKSDB_NAMESPACE {
  8. class CoalescingIteratorTest : public DBTestBase {
  9. public:
  10. CoalescingIteratorTest()
  11. : DBTestBase("coalescing_iterator_test", /*env_do_fsync=*/true) {}
  12. // Verify Iteration of CoalescingIterator
  13. // by SeekToFirst() + Next() and SeekToLast() + Prev()
  14. void VerifyCoalescingIterator(const std::vector<ColumnFamilyHandle*>& cfhs,
  15. const std::vector<Slice>& expected_keys,
  16. const std::vector<Slice>& expected_values,
  17. const std::optional<std::vector<WideColumns>>&
  18. expected_wide_columns = std::nullopt,
  19. const Slice* lower_bound = nullptr,
  20. const Slice* upper_bound = nullptr,
  21. bool allow_unprepared_value = false) {
  22. const size_t num_keys = expected_keys.size();
  23. ReadOptions read_options;
  24. read_options.iterate_lower_bound = lower_bound;
  25. read_options.iterate_upper_bound = upper_bound;
  26. read_options.allow_unprepared_value = allow_unprepared_value;
  27. std::unique_ptr<Iterator> iter =
  28. db_->NewCoalescingIterator(read_options, cfhs);
  29. auto check_iter_entry = [&](size_t idx) {
  30. ASSERT_EQ(iter->key(), expected_keys[idx]);
  31. if (allow_unprepared_value) {
  32. ASSERT_TRUE(iter->value().empty());
  33. ASSERT_TRUE(iter->PrepareValue());
  34. ASSERT_TRUE(iter->Valid());
  35. }
  36. ASSERT_EQ(iter->value(), expected_values[idx]);
  37. if (expected_wide_columns.has_value()) {
  38. ASSERT_EQ(iter->columns(), expected_wide_columns.value()[idx]);
  39. }
  40. };
  41. {
  42. size_t i = 0;
  43. for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
  44. check_iter_entry(i);
  45. ++i;
  46. }
  47. ASSERT_EQ(num_keys, i);
  48. ASSERT_OK(iter->status());
  49. }
  50. {
  51. size_t i = 0;
  52. for (iter->SeekToLast(); iter->Valid(); iter->Prev()) {
  53. check_iter_entry(num_keys - 1 - i);
  54. ++i;
  55. }
  56. ASSERT_EQ(num_keys, i);
  57. ASSERT_OK(iter->status());
  58. }
  59. }
  60. void VerifyExpectedKeys(ColumnFamilyHandle* cfh,
  61. const std::vector<Slice>& expected_keys) {
  62. std::unique_ptr<Iterator> iter(db_->NewIterator(ReadOptions(), cfh));
  63. size_t i = 0;
  64. for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
  65. ASSERT_EQ(iter->key(), expected_keys[i]);
  66. ++i;
  67. }
  68. ASSERT_EQ(i, expected_keys.size());
  69. ASSERT_OK(iter->status());
  70. }
  71. };
  72. TEST_F(CoalescingIteratorTest, InvalidArguments) {
  73. Options options = GetDefaultOptions();
  74. {
  75. CreateAndReopenWithCF({"cf_1", "cf_2", "cf_3"}, options);
  76. // Invalid - No CF is provided
  77. std::unique_ptr<Iterator> iter_with_no_cf =
  78. db_->NewCoalescingIterator(ReadOptions(), {});
  79. ASSERT_NOK(iter_with_no_cf->status());
  80. ASSERT_TRUE(iter_with_no_cf->status().IsInvalidArgument());
  81. }
  82. }
  83. TEST_F(CoalescingIteratorTest, SimpleValues) {
  84. Options options = GetDefaultOptions();
  85. {
  86. // Case 1: Unique key per CF
  87. CreateAndReopenWithCF({"cf_1", "cf_2", "cf_3"}, options);
  88. ASSERT_OK(Put(0, "key_1", "key_1_cf_0_val"));
  89. ASSERT_OK(Put(1, "key_2", "key_2_cf_1_val"));
  90. ASSERT_OK(Put(2, "key_3", "key_3_cf_2_val"));
  91. ASSERT_OK(Put(3, "key_4", "key_4_cf_3_val"));
  92. std::vector<Slice> expected_keys = {"key_1", "key_2", "key_3", "key_4"};
  93. std::vector<Slice> expected_values = {"key_1_cf_0_val", "key_2_cf_1_val",
  94. "key_3_cf_2_val", "key_4_cf_3_val"};
  95. // Test for iteration over CF default->1->2->3
  96. std::vector<ColumnFamilyHandle*> cfhs_order_0_1_2_3 = {
  97. handles_[0], handles_[1], handles_[2], handles_[3]};
  98. VerifyCoalescingIterator(cfhs_order_0_1_2_3, expected_keys,
  99. expected_values);
  100. // Test for iteration over CF 3->1->default_cf->2
  101. std::vector<ColumnFamilyHandle*> cfhs_order_3_1_0_2 = {
  102. handles_[3], handles_[1], handles_[0], handles_[2]};
  103. // Iteration order and the return values should be the same since keys are
  104. // unique per CF
  105. VerifyCoalescingIterator(cfhs_order_3_1_0_2, expected_keys,
  106. expected_values);
  107. // Verify Seek()
  108. {
  109. std::unique_ptr<Iterator> iter =
  110. db_->NewCoalescingIterator(ReadOptions(), cfhs_order_0_1_2_3);
  111. iter->Seek("");
  112. ASSERT_EQ(IterStatus(iter.get()), "key_1->key_1_cf_0_val");
  113. iter->Seek("key_1");
  114. ASSERT_EQ(IterStatus(iter.get()), "key_1->key_1_cf_0_val");
  115. iter->Seek("key_2");
  116. ASSERT_EQ(IterStatus(iter.get()), "key_2->key_2_cf_1_val");
  117. iter->Next();
  118. ASSERT_EQ(IterStatus(iter.get()), "key_3->key_3_cf_2_val");
  119. iter->Seek("key_x");
  120. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  121. }
  122. // Verify SeekForPrev()
  123. {
  124. std::unique_ptr<Iterator> iter =
  125. db_->NewCoalescingIterator(ReadOptions(), cfhs_order_0_1_2_3);
  126. iter->SeekForPrev("");
  127. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  128. iter->SeekForPrev("key_1");
  129. ASSERT_EQ(IterStatus(iter.get()), "key_1->key_1_cf_0_val");
  130. iter->Next();
  131. ASSERT_EQ(IterStatus(iter.get()), "key_2->key_2_cf_1_val");
  132. iter->SeekForPrev("key_x");
  133. ASSERT_EQ(IterStatus(iter.get()), "key_4->key_4_cf_3_val");
  134. iter->Prev();
  135. ASSERT_EQ(IterStatus(iter.get()), "key_3->key_3_cf_2_val");
  136. iter->Next();
  137. ASSERT_EQ(IterStatus(iter.get()), "key_4->key_4_cf_3_val");
  138. iter->Next();
  139. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  140. }
  141. }
  142. {
  143. // Case 2: Same key in multiple CFs
  144. options = CurrentOptions(options);
  145. DestroyAndReopen(options);
  146. CreateAndReopenWithCF({"cf_1", "cf_2", "cf_3"}, options);
  147. ASSERT_OK(Put(0, "key_1", "key_1_cf_0_val"));
  148. ASSERT_OK(Put(3, "key_1", "key_1_cf_3_val"));
  149. ASSERT_OK(Put(1, "key_2", "key_2_cf_1_val"));
  150. ASSERT_OK(Put(2, "key_2", "key_2_cf_2_val"));
  151. ASSERT_OK(Put(0, "key_3", "key_3_cf_0_val"));
  152. ASSERT_OK(Put(1, "key_3", "key_3_cf_1_val"));
  153. ASSERT_OK(Put(3, "key_3", "key_3_cf_3_val"));
  154. std::vector<Slice> expected_keys = {"key_1", "key_2", "key_3"};
  155. // Test for iteration over CFs default->1->2->3
  156. std::vector<ColumnFamilyHandle*> cfhs_order_0_1_2_3 = {
  157. handles_[0], handles_[1], handles_[2], handles_[3]};
  158. std::vector<Slice> expected_values = {"key_1_cf_3_val", "key_2_cf_2_val",
  159. "key_3_cf_3_val"};
  160. VerifyCoalescingIterator(cfhs_order_0_1_2_3, expected_keys,
  161. expected_values);
  162. // Test for iteration over CFs 3->2->default_cf->1
  163. std::vector<ColumnFamilyHandle*> cfhs_order_3_2_0_1 = {
  164. handles_[3], handles_[2], handles_[0], handles_[1]};
  165. expected_values = {"key_1_cf_0_val", "key_2_cf_1_val", "key_3_cf_1_val"};
  166. VerifyCoalescingIterator(cfhs_order_3_2_0_1, expected_keys,
  167. expected_values);
  168. // Verify Seek()
  169. {
  170. std::unique_ptr<Iterator> iter =
  171. db_->NewCoalescingIterator(ReadOptions(), cfhs_order_3_2_0_1);
  172. iter->Seek("");
  173. ASSERT_EQ(IterStatus(iter.get()), "key_1->key_1_cf_0_val");
  174. iter->Seek("key_1");
  175. ASSERT_EQ(IterStatus(iter.get()), "key_1->key_1_cf_0_val");
  176. iter->Seek("key_2");
  177. ASSERT_EQ(IterStatus(iter.get()), "key_2->key_2_cf_1_val");
  178. iter->Next();
  179. ASSERT_EQ(IterStatus(iter.get()), "key_3->key_3_cf_1_val");
  180. iter->Seek("key_x");
  181. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  182. }
  183. // Verify SeekForPrev()
  184. {
  185. std::unique_ptr<Iterator> iter =
  186. db_->NewCoalescingIterator(ReadOptions(), cfhs_order_3_2_0_1);
  187. iter->SeekForPrev("");
  188. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  189. iter->SeekForPrev("key_1");
  190. ASSERT_EQ(IterStatus(iter.get()), "key_1->key_1_cf_0_val");
  191. iter->Next();
  192. ASSERT_EQ(IterStatus(iter.get()), "key_2->key_2_cf_1_val");
  193. iter->SeekForPrev("key_x");
  194. ASSERT_EQ(IterStatus(iter.get()), "key_3->key_3_cf_1_val");
  195. iter->Next();
  196. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  197. }
  198. }
  199. }
  200. TEST_F(CoalescingIteratorTest, LowerAndUpperBounds) {
  201. Options options = GetDefaultOptions();
  202. {
  203. // Case 1: Unique key per CF
  204. CreateAndReopenWithCF({"cf_1", "cf_2", "cf_3"}, options);
  205. ASSERT_OK(Put(0, "key_1", "key_1_cf_0_val"));
  206. ASSERT_OK(Put(1, "key_2", "key_2_cf_1_val"));
  207. ASSERT_OK(Put(2, "key_3", "key_3_cf_2_val"));
  208. ASSERT_OK(Put(3, "key_4", "key_4_cf_3_val"));
  209. std::vector<ColumnFamilyHandle*> cfhs_order_0_1_2_3 = {
  210. handles_[0], handles_[1], handles_[2], handles_[3]};
  211. // with lower_bound
  212. {
  213. // lower_bound is inclusive
  214. Slice lb = Slice("key_2");
  215. std::vector<Slice> expected_keys = {"key_2", "key_3", "key_4"};
  216. std::vector<Slice> expected_values = {"key_2_cf_1_val", "key_3_cf_2_val",
  217. "key_4_cf_3_val"};
  218. VerifyCoalescingIterator(cfhs_order_0_1_2_3, expected_keys,
  219. expected_values, std::nullopt, &lb);
  220. }
  221. // with upper_bound
  222. {
  223. // upper_bound is exclusive
  224. Slice ub = Slice("key_3");
  225. std::vector<Slice> expected_keys = {"key_1", "key_2"};
  226. std::vector<Slice> expected_values = {"key_1_cf_0_val", "key_2_cf_1_val"};
  227. VerifyCoalescingIterator(cfhs_order_0_1_2_3, expected_keys,
  228. expected_values, std::nullopt, nullptr, &ub);
  229. }
  230. // with lower and upper bound
  231. {
  232. Slice lb = Slice("key_2");
  233. Slice ub = Slice("key_4");
  234. std::vector<Slice> expected_keys = {"key_2", "key_3"};
  235. std::vector<Slice> expected_values = {"key_2_cf_1_val", "key_3_cf_2_val"};
  236. VerifyCoalescingIterator(cfhs_order_0_1_2_3, expected_keys,
  237. expected_values, std::nullopt, &lb, &ub);
  238. }
  239. {
  240. Slice lb = Slice("key_2");
  241. Slice ub = Slice("key_4");
  242. ReadOptions read_options;
  243. read_options.iterate_lower_bound = &lb;
  244. read_options.iterate_upper_bound = &ub;
  245. // Verify Seek() with bounds
  246. {
  247. std::unique_ptr<Iterator> iter =
  248. db_->NewCoalescingIterator(read_options, cfhs_order_0_1_2_3);
  249. iter->Seek("");
  250. ASSERT_EQ(IterStatus(iter.get()), "key_2->key_2_cf_1_val");
  251. iter->Next();
  252. ASSERT_EQ(IterStatus(iter.get()), "key_3->key_3_cf_2_val");
  253. iter->Seek("key_x");
  254. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  255. }
  256. // Verify SeekForPrev() with bounds
  257. {
  258. std::unique_ptr<Iterator> iter =
  259. db_->NewCoalescingIterator(read_options, cfhs_order_0_1_2_3);
  260. iter->SeekForPrev("");
  261. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  262. iter->SeekForPrev("key_1");
  263. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  264. iter->SeekForPrev("key_2");
  265. ASSERT_EQ(IterStatus(iter.get()), "key_2->key_2_cf_1_val");
  266. iter->Next();
  267. ASSERT_EQ(IterStatus(iter.get()), "key_3->key_3_cf_2_val");
  268. iter->SeekForPrev("key_x");
  269. ASSERT_EQ(IterStatus(iter.get()), "key_3->key_3_cf_2_val");
  270. iter->Prev();
  271. ASSERT_EQ(IterStatus(iter.get()), "key_2->key_2_cf_1_val");
  272. iter->Next();
  273. ASSERT_EQ(IterStatus(iter.get()), "key_3->key_3_cf_2_val");
  274. iter->Next();
  275. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  276. }
  277. }
  278. }
  279. {
  280. // Case 2: Same key in multiple CFs
  281. options = CurrentOptions(options);
  282. DestroyAndReopen(options);
  283. CreateAndReopenWithCF({"cf_1", "cf_2", "cf_3"}, options);
  284. ASSERT_OK(Put(0, "key_1", "key_1_cf_0_val"));
  285. ASSERT_OK(Put(3, "key_1", "key_1_cf_3_val"));
  286. ASSERT_OK(Put(1, "key_2", "key_2_cf_1_val"));
  287. ASSERT_OK(Put(2, "key_2", "key_2_cf_2_val"));
  288. ASSERT_OK(Put(0, "key_3", "key_3_cf_0_val"));
  289. ASSERT_OK(Put(1, "key_3", "key_3_cf_1_val"));
  290. ASSERT_OK(Put(3, "key_3", "key_3_cf_3_val"));
  291. // Test for iteration over CFs default->1->2->3
  292. std::vector<ColumnFamilyHandle*> cfhs_order_0_1_2_3 = {
  293. handles_[0], handles_[1], handles_[2], handles_[3]};
  294. // with lower_bound
  295. {
  296. // lower_bound is inclusive
  297. Slice lb = Slice("key_2");
  298. std::vector<Slice> expected_keys = {"key_2", "key_3"};
  299. std::vector<Slice> expected_values = {"key_2_cf_2_val", "key_3_cf_3_val"};
  300. VerifyCoalescingIterator(cfhs_order_0_1_2_3, expected_keys,
  301. expected_values, std::nullopt, &lb);
  302. }
  303. // with upper_bound
  304. {
  305. // upper_bound is exclusive
  306. Slice ub = Slice("key_3");
  307. std::vector<Slice> expected_keys = {"key_1", "key_2"};
  308. std::vector<Slice> expected_values = {"key_1_cf_3_val", "key_2_cf_2_val"};
  309. VerifyCoalescingIterator(cfhs_order_0_1_2_3, expected_keys,
  310. expected_values, std::nullopt, nullptr, &ub);
  311. }
  312. // with lower and upper bound
  313. {
  314. Slice lb = Slice("key_2");
  315. Slice ub = Slice("key_3");
  316. std::vector<Slice> expected_keys = {"key_2"};
  317. std::vector<Slice> expected_values = {"key_2_cf_2_val"};
  318. VerifyCoalescingIterator(cfhs_order_0_1_2_3, expected_keys,
  319. expected_values, std::nullopt, &lb, &ub);
  320. }
  321. // Test for iteration over CFs 3->2->default_cf->1
  322. std::vector<ColumnFamilyHandle*> cfhs_order_3_2_0_1 = {
  323. handles_[3], handles_[2], handles_[0], handles_[1]};
  324. {
  325. // lower_bound is inclusive
  326. Slice lb = Slice("key_2");
  327. std::vector<Slice> expected_keys = {"key_2", "key_3"};
  328. std::vector<Slice> expected_values = {"key_2_cf_1_val", "key_3_cf_1_val"};
  329. VerifyCoalescingIterator(cfhs_order_3_2_0_1, expected_keys,
  330. expected_values, std::nullopt, &lb);
  331. }
  332. // with upper_bound
  333. {
  334. // upper_bound is exclusive
  335. Slice ub = Slice("key_3");
  336. std::vector<Slice> expected_keys = {"key_1", "key_2"};
  337. std::vector<Slice> expected_values = {"key_1_cf_0_val", "key_2_cf_1_val"};
  338. VerifyCoalescingIterator(cfhs_order_3_2_0_1, expected_keys,
  339. expected_values, std::nullopt, nullptr, &ub);
  340. }
  341. // with lower and upper bound
  342. {
  343. Slice lb = Slice("key_2");
  344. Slice ub = Slice("key_3");
  345. std::vector<Slice> expected_keys = {"key_2"};
  346. std::vector<Slice> expected_values = {"key_2_cf_1_val"};
  347. VerifyCoalescingIterator(cfhs_order_3_2_0_1, expected_keys,
  348. expected_values, std::nullopt, &lb, &ub);
  349. }
  350. {
  351. Slice lb = Slice("key_2");
  352. Slice ub = Slice("key_3");
  353. ReadOptions read_options;
  354. read_options.iterate_lower_bound = &lb;
  355. read_options.iterate_upper_bound = &ub;
  356. // Verify Seek() with bounds
  357. {
  358. std::unique_ptr<Iterator> iter =
  359. db_->NewCoalescingIterator(read_options, cfhs_order_3_2_0_1);
  360. iter->Seek("");
  361. ASSERT_EQ(IterStatus(iter.get()), "key_2->key_2_cf_1_val");
  362. iter->Next();
  363. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  364. iter->Seek("key_x");
  365. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  366. }
  367. // Verify SeekForPrev() with bounds
  368. {
  369. std::unique_ptr<Iterator> iter =
  370. db_->NewCoalescingIterator(read_options, cfhs_order_3_2_0_1);
  371. iter->SeekForPrev("");
  372. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  373. iter->SeekForPrev("key_1");
  374. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  375. iter->SeekForPrev("key_2");
  376. ASSERT_EQ(IterStatus(iter.get()), "key_2->key_2_cf_1_val");
  377. iter->SeekForPrev("key_x");
  378. ASSERT_EQ(IterStatus(iter.get()), "key_2->key_2_cf_1_val");
  379. iter->Next();
  380. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  381. }
  382. }
  383. }
  384. }
  385. TEST_F(CoalescingIteratorTest, ConsistentViewExplicitSnapshot) {
  386. Options options = GetDefaultOptions();
  387. options.atomic_flush = true;
  388. CreateAndReopenWithCF({"cf_1", "cf_2", "cf_3"}, options);
  389. for (int i = 0; i < 4; ++i) {
  390. ASSERT_OK(Put(i, "cf" + std::to_string(i) + "_key",
  391. "cf" + std::to_string(i) + "_val"));
  392. }
  393. ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->LoadDependency(
  394. {{"DBImpl::BGWorkFlush:done",
  395. "DBImpl::MultiCFSnapshot::BeforeCheckingSnapshot"}});
  396. bool flushed = false;
  397. ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
  398. "DBImpl::MultiCFSnapshot::AfterRefSV", [&](void* /*arg*/) {
  399. if (!flushed) {
  400. for (int i = 0; i < 4; ++i) {
  401. ASSERT_OK(Put(i, "cf" + std::to_string(i) + "_key",
  402. "cf" + std::to_string(i) + "_val_new"));
  403. }
  404. ASSERT_OK(Flush());
  405. flushed = true;
  406. }
  407. });
  408. ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
  409. std::vector<ColumnFamilyHandle*> cfhs_order_0_1_2_3 = {
  410. handles_[0], handles_[1], handles_[2], handles_[3]};
  411. ReadOptions read_options;
  412. const Snapshot* snapshot = db_->GetSnapshot();
  413. read_options.snapshot = snapshot;
  414. // Verify Seek()
  415. {
  416. std::unique_ptr<Iterator> iter =
  417. db_->NewCoalescingIterator(read_options, cfhs_order_0_1_2_3);
  418. iter->Seek("");
  419. ASSERT_EQ(IterStatus(iter.get()), "cf0_key->cf0_val");
  420. iter->Next();
  421. ASSERT_EQ(IterStatus(iter.get()), "cf1_key->cf1_val");
  422. }
  423. // Verify SeekForPrev()
  424. {
  425. std::unique_ptr<Iterator> iter =
  426. db_->NewCoalescingIterator(read_options, cfhs_order_0_1_2_3);
  427. iter->SeekForPrev("");
  428. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  429. iter->SeekForPrev("cf2_key");
  430. ASSERT_EQ(IterStatus(iter.get()), "cf2_key->cf2_val");
  431. iter->Prev();
  432. ASSERT_EQ(IterStatus(iter.get()), "cf1_key->cf1_val");
  433. }
  434. db_->ReleaseSnapshot(snapshot);
  435. }
  436. TEST_F(CoalescingIteratorTest, ConsistentViewImplicitSnapshot) {
  437. Options options = GetDefaultOptions();
  438. CreateAndReopenWithCF({"cf_1", "cf_2", "cf_3"}, options);
  439. for (int i = 0; i < 4; ++i) {
  440. ASSERT_OK(Put(i, "cf" + std::to_string(i) + "_key",
  441. "cf" + std::to_string(i) + "_val"));
  442. }
  443. ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->LoadDependency(
  444. {{"DBImpl::BGWorkFlush:done",
  445. "DBImpl::MultiCFSnapshot::BeforeCheckingSnapshot"}});
  446. bool flushed = false;
  447. ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
  448. "DBImpl::MultiCFSnapshot::AfterRefSV", [&](void* /*arg*/) {
  449. if (!flushed) {
  450. for (int i = 0; i < 4; ++i) {
  451. ASSERT_OK(Put(i, "cf" + std::to_string(i) + "_key",
  452. "cf" + std::to_string(i) + "_val_new"));
  453. }
  454. ASSERT_OK(Flush(1));
  455. flushed = true;
  456. }
  457. });
  458. ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
  459. std::vector<ColumnFamilyHandle*> cfhs_order_0_1_2_3 = {
  460. handles_[0], handles_[1], handles_[2], handles_[3]};
  461. // Verify Seek()
  462. {
  463. std::unique_ptr<Iterator> iter =
  464. db_->NewCoalescingIterator(ReadOptions(), cfhs_order_0_1_2_3);
  465. iter->Seek("cf2_key");
  466. ASSERT_EQ(IterStatus(iter.get()), "cf2_key->cf2_val_new");
  467. iter->Next();
  468. ASSERT_EQ(IterStatus(iter.get()), "cf3_key->cf3_val_new");
  469. }
  470. // Verify SeekForPrev()
  471. {
  472. std::unique_ptr<Iterator> iter =
  473. db_->NewCoalescingIterator(ReadOptions(), cfhs_order_0_1_2_3);
  474. iter->SeekForPrev("");
  475. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  476. iter->SeekForPrev("cf1_key");
  477. ASSERT_EQ(IterStatus(iter.get()), "cf1_key->cf1_val_new");
  478. iter->Prev();
  479. ASSERT_EQ(IterStatus(iter.get()), "cf0_key->cf0_val_new");
  480. }
  481. }
  482. TEST_F(CoalescingIteratorTest, EmptyCfs) {
  483. Options options = GetDefaultOptions();
  484. {
  485. // Case 1: No keys in any of the CFs
  486. CreateAndReopenWithCF({"cf_1", "cf_2", "cf_3"}, options);
  487. std::unique_ptr<Iterator> iter =
  488. db_->NewCoalescingIterator(ReadOptions(), handles_);
  489. iter->SeekToFirst();
  490. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  491. iter->SeekToLast();
  492. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  493. iter->Seek("foo");
  494. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  495. iter->SeekForPrev("foo");
  496. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  497. ASSERT_OK(iter->status());
  498. }
  499. {
  500. // Case 2: A single key exists in only one of the CF. Rest CFs are empty.
  501. ASSERT_OK(Put(1, "key_1", "key_1_cf_1_val"));
  502. std::unique_ptr<Iterator> iter =
  503. db_->NewCoalescingIterator(ReadOptions(), handles_);
  504. iter->SeekToFirst();
  505. ASSERT_EQ(IterStatus(iter.get()), "key_1->key_1_cf_1_val");
  506. iter->Next();
  507. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  508. iter->SeekToLast();
  509. ASSERT_EQ(IterStatus(iter.get()), "key_1->key_1_cf_1_val");
  510. iter->Prev();
  511. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  512. }
  513. {
  514. // Case 3: same key exists in all of the CFs except one (cf_2)
  515. ASSERT_OK(Put(0, "key_1", "key_1_cf_0_val"));
  516. ASSERT_OK(Put(3, "key_1", "key_1_cf_3_val"));
  517. // handles_ are in the order of 0->1->2->3
  518. std::unique_ptr<Iterator> iter =
  519. db_->NewCoalescingIterator(ReadOptions(), handles_);
  520. iter->SeekToFirst();
  521. ASSERT_EQ(IterStatus(iter.get()), "key_1->key_1_cf_3_val");
  522. iter->Next();
  523. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  524. iter->SeekToLast();
  525. ASSERT_EQ(IterStatus(iter.get()), "key_1->key_1_cf_3_val");
  526. iter->Prev();
  527. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  528. }
  529. }
  530. TEST_F(CoalescingIteratorTest, WideColumns) {
  531. // Set up the DB and Column Families
  532. Options options = GetDefaultOptions();
  533. CreateAndReopenWithCF({"cf_1", "cf_2", "cf_3"}, options);
  534. constexpr char key_1[] = "key_1";
  535. WideColumns key_1_columns_in_cf_2{
  536. {kDefaultWideColumnName, "cf_2_col_val_0_key_1"},
  537. {"cf_2_col_name_1", "cf_2_col_val_1_key_1"},
  538. {"cf_2_col_name_2", "cf_2_col_val_2_key_1"},
  539. {"cf_overlap_col_name", "cf_2_overlap_value_key_1"}};
  540. WideColumns key_1_columns_in_cf_3{
  541. {"cf_3_col_name_1", "cf_3_col_val_1_key_1"},
  542. {"cf_3_col_name_2", "cf_3_col_val_2_key_1"},
  543. {"cf_3_col_name_3", "cf_3_col_val_3_key_1"},
  544. {"cf_overlap_col_name", "cf_3_overlap_value_key_1"}};
  545. WideColumns key_1_expected_columns_cfh_order_2_3{
  546. {kDefaultWideColumnName, "cf_2_col_val_0_key_1"},
  547. {"cf_2_col_name_1", "cf_2_col_val_1_key_1"},
  548. {"cf_2_col_name_2", "cf_2_col_val_2_key_1"},
  549. {"cf_3_col_name_1", "cf_3_col_val_1_key_1"},
  550. {"cf_3_col_name_2", "cf_3_col_val_2_key_1"},
  551. {"cf_3_col_name_3", "cf_3_col_val_3_key_1"},
  552. {"cf_overlap_col_name", "cf_3_overlap_value_key_1"}};
  553. WideColumns key_1_expected_columns_cfh_order_3_2{
  554. {kDefaultWideColumnName, "cf_2_col_val_0_key_1"},
  555. {"cf_2_col_name_1", "cf_2_col_val_1_key_1"},
  556. {"cf_2_col_name_2", "cf_2_col_val_2_key_1"},
  557. {"cf_3_col_name_1", "cf_3_col_val_1_key_1"},
  558. {"cf_3_col_name_2", "cf_3_col_val_2_key_1"},
  559. {"cf_3_col_name_3", "cf_3_col_val_3_key_1"},
  560. {"cf_overlap_col_name", "cf_2_overlap_value_key_1"}};
  561. constexpr char key_2[] = "key_2";
  562. WideColumns key_2_columns_in_cf_1{
  563. {"cf_overlap_col_name", "cf_1_overlap_value_key_2"}};
  564. WideColumns key_2_columns_in_cf_2{
  565. {"cf_2_col_name_1", "cf_2_col_val_1_key_2"},
  566. {"cf_2_col_name_2", "cf_2_col_val_2_key_2"},
  567. {"cf_overlap_col_name", "cf_2_overlap_value_key_2"}};
  568. WideColumns key_2_expected_columns_cfh_order_1_2{
  569. {"cf_2_col_name_1", "cf_2_col_val_1_key_2"},
  570. {"cf_2_col_name_2", "cf_2_col_val_2_key_2"},
  571. {"cf_overlap_col_name", "cf_2_overlap_value_key_2"}};
  572. WideColumns key_2_expected_columns_cfh_order_2_1{
  573. {"cf_2_col_name_1", "cf_2_col_val_1_key_2"},
  574. {"cf_2_col_name_2", "cf_2_col_val_2_key_2"},
  575. {"cf_overlap_col_name", "cf_1_overlap_value_key_2"}};
  576. constexpr char key_3[] = "key_3";
  577. WideColumns key_3_columns_in_cf_1{
  578. {"cf_1_col_name_1", "cf_1_col_val_1_key_3"}};
  579. WideColumns key_3_columns_in_cf_3{
  580. {"cf_3_col_name_1", "cf_3_col_val_1_key_3"}};
  581. WideColumns key_3_expected_columns{
  582. {"cf_1_col_name_1", "cf_1_col_val_1_key_3"},
  583. {"cf_3_col_name_1", "cf_3_col_val_1_key_3"},
  584. };
  585. constexpr char key_4[] = "key_4";
  586. WideColumns key_4_columns_in_cf_0{
  587. {"cf_0_col_name_1", "cf_0_col_val_1_key_4"}};
  588. WideColumns key_4_columns_in_cf_2{
  589. {"cf_2_col_name_1", "cf_2_col_val_1_key_4"}};
  590. WideColumns key_4_expected_columns{
  591. {"cf_0_col_name_1", "cf_0_col_val_1_key_4"},
  592. {"cf_2_col_name_1", "cf_2_col_val_1_key_4"},
  593. };
  594. // Use AttributeGroup PutEntity API to insert them together
  595. AttributeGroups key_1_attribute_groups{
  596. AttributeGroup(handles_[2], key_1_columns_in_cf_2),
  597. AttributeGroup(handles_[3], key_1_columns_in_cf_3)};
  598. AttributeGroups key_2_attribute_groups{
  599. AttributeGroup(handles_[1], key_2_columns_in_cf_1),
  600. AttributeGroup(handles_[2], key_2_columns_in_cf_2)};
  601. AttributeGroups key_3_attribute_groups{
  602. AttributeGroup(handles_[1], key_3_columns_in_cf_1),
  603. AttributeGroup(handles_[3], key_3_columns_in_cf_3)};
  604. AttributeGroups key_4_attribute_groups{
  605. AttributeGroup(handles_[0], key_4_columns_in_cf_0),
  606. AttributeGroup(handles_[2], key_4_columns_in_cf_2)};
  607. ASSERT_OK(db_->PutEntity(WriteOptions(), key_1, key_1_attribute_groups));
  608. ASSERT_OK(db_->PutEntity(WriteOptions(), key_2, key_2_attribute_groups));
  609. ASSERT_OK(db_->PutEntity(WriteOptions(), key_3, key_3_attribute_groups));
  610. ASSERT_OK(db_->PutEntity(WriteOptions(), key_4, key_4_attribute_groups));
  611. // Keys should be returned in order regardless of cfh order
  612. std::vector<Slice> expected_keys = {key_1, key_2, key_3, key_4};
  613. // Since value for kDefaultWideColumnName only exists for key_1, rest will
  614. // return empty value after coalesced
  615. std::vector<Slice> expected_values = {"cf_2_col_val_0_key_1", "", "", ""};
  616. // Test for iteration over CF default->1->2->3
  617. {
  618. std::vector<ColumnFamilyHandle*> cfhs_order_0_1_2_3 = {
  619. handles_[0], handles_[1], handles_[2], handles_[3]};
  620. // Coalesced columns
  621. std::vector<WideColumns> expected_wide_columns_0_1_2_3 = {
  622. key_1_expected_columns_cfh_order_2_3,
  623. key_2_expected_columns_cfh_order_1_2, key_3_expected_columns,
  624. key_4_expected_columns};
  625. VerifyCoalescingIterator(cfhs_order_0_1_2_3, expected_keys, expected_values,
  626. expected_wide_columns_0_1_2_3);
  627. }
  628. // Test for iteration over CF 3->2->default->1
  629. {
  630. std::vector<ColumnFamilyHandle*> cfhs_order_3_2_0_1 = {
  631. handles_[3], handles_[2], handles_[0], handles_[1]};
  632. // Coalesced columns
  633. std::vector<WideColumns> expected_wide_columns_3_2_0_1 = {
  634. key_1_expected_columns_cfh_order_3_2,
  635. key_2_expected_columns_cfh_order_2_1, key_3_expected_columns,
  636. key_4_expected_columns};
  637. VerifyCoalescingIterator(cfhs_order_3_2_0_1, expected_keys, expected_values,
  638. expected_wide_columns_3_2_0_1);
  639. }
  640. }
  641. TEST_F(CoalescingIteratorTest, DifferentComparatorsInMultiCFs) {
  642. // This test creates two column families with two different comparators.
  643. // Attempting to create the CoalescingIterator should fail.
  644. Options options = GetDefaultOptions();
  645. options.create_if_missing = true;
  646. DestroyAndReopen(options);
  647. options.comparator = BytewiseComparator();
  648. CreateColumnFamilies({"cf_forward"}, options);
  649. options.comparator = ReverseBytewiseComparator();
  650. CreateColumnFamilies({"cf_reverse"}, options);
  651. ASSERT_OK(Put(0, "key_1", "value_1"));
  652. ASSERT_OK(Put(0, "key_2", "value_2"));
  653. ASSERT_OK(Put(0, "key_3", "value_3"));
  654. ASSERT_OK(Put(1, "key_1", "value_1"));
  655. ASSERT_OK(Put(1, "key_2", "value_2"));
  656. ASSERT_OK(Put(1, "key_3", "value_3"));
  657. VerifyExpectedKeys(handles_[0], {"key_1", "key_2", "key_3"});
  658. VerifyExpectedKeys(handles_[1], {"key_3", "key_2", "key_1"});
  659. std::unique_ptr<Iterator> iter =
  660. db_->NewCoalescingIterator(ReadOptions(), handles_);
  661. ASSERT_NOK(iter->status());
  662. ASSERT_TRUE(iter->status().IsInvalidArgument());
  663. }
  664. TEST_F(CoalescingIteratorTest, CustomComparatorsInMultiCFs) {
  665. // This test creates two column families with the same custom test
  666. // comparators (but instantiated independently). Attempting to create the
  667. // CoalescingIterator should not fail.
  668. Options options = GetDefaultOptions();
  669. options.create_if_missing = true;
  670. DestroyAndReopen(options);
  671. static auto comparator_1 =
  672. std::make_unique<test::SimpleSuffixReverseComparator>(
  673. test::SimpleSuffixReverseComparator());
  674. static auto comparator_2 =
  675. std::make_unique<test::SimpleSuffixReverseComparator>(
  676. test::SimpleSuffixReverseComparator());
  677. ASSERT_NE(comparator_1, comparator_2);
  678. options.comparator = comparator_1.get();
  679. CreateColumnFamilies({"cf_1"}, options);
  680. options.comparator = comparator_2.get();
  681. CreateColumnFamilies({"cf_2"}, options);
  682. ASSERT_OK(Put(0, "key_001_001", "value_0_3"));
  683. ASSERT_OK(Put(0, "key_001_002", "value_0_2"));
  684. ASSERT_OK(Put(0, "key_001_003", "value_0_1"));
  685. ASSERT_OK(Put(0, "key_002_001", "value_0_6"));
  686. ASSERT_OK(Put(0, "key_002_002", "value_0_5"));
  687. ASSERT_OK(Put(0, "key_002_003", "value_0_4"));
  688. ASSERT_OK(Put(1, "key_001_001", "value_1_3"));
  689. ASSERT_OK(Put(1, "key_001_002", "value_1_2"));
  690. ASSERT_OK(Put(1, "key_001_003", "value_1_1"));
  691. ASSERT_OK(Put(1, "key_003_004", "value_1_6"));
  692. ASSERT_OK(Put(1, "key_003_005", "value_1_5"));
  693. ASSERT_OK(Put(1, "key_003_006", "value_1_4"));
  694. VerifyExpectedKeys(
  695. handles_[0], {"key_001_003", "key_001_002", "key_001_001", "key_002_003",
  696. "key_002_002", "key_002_001"});
  697. VerifyExpectedKeys(
  698. handles_[1], {"key_001_003", "key_001_002", "key_001_001", "key_003_006",
  699. "key_003_005", "key_003_004"});
  700. std::vector<Slice> expected_keys = {
  701. "key_001_003", "key_001_002", "key_001_001", "key_002_003", "key_002_002",
  702. "key_002_001", "key_003_006", "key_003_005", "key_003_004"};
  703. std::vector<Slice> expected_values = {"value_1_1", "value_1_2", "value_1_3",
  704. "value_0_4", "value_0_5", "value_0_6",
  705. "value_1_4", "value_1_5", "value_1_6"};
  706. std::unique_ptr<Iterator> iter =
  707. db_->NewCoalescingIterator(ReadOptions(), handles_);
  708. size_t i = 0;
  709. for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
  710. ASSERT_EQ(expected_keys[i], iter->key());
  711. ASSERT_EQ(expected_values[i], iter->value());
  712. ++i;
  713. }
  714. ASSERT_EQ(expected_keys.size(), i);
  715. ASSERT_OK(iter->status());
  716. }
  717. TEST_F(CoalescingIteratorTest, AllowUnpreparedValue) {
  718. Options options = GetDefaultOptions();
  719. options.enable_blob_files = true;
  720. CreateAndReopenWithCF({"cf_1", "cf_2", "cf_3"}, options);
  721. ASSERT_OK(Put(0, "key_1", "key_1_cf_0_val"));
  722. ASSERT_OK(Put(3, "key_1", "key_1_cf_3_val"));
  723. ASSERT_OK(Put(1, "key_2", "key_2_cf_1_val"));
  724. ASSERT_OK(Put(2, "key_2", "key_2_cf_2_val"));
  725. ASSERT_OK(Put(0, "key_3", "key_3_cf_0_val"));
  726. ASSERT_OK(Put(1, "key_3", "key_3_cf_1_val"));
  727. ASSERT_OK(Put(3, "key_3", "key_3_cf_3_val"));
  728. ASSERT_OK(Flush());
  729. std::vector<ColumnFamilyHandle*> cfhs_order_3_2_0_1{handles_[3], handles_[2],
  730. handles_[0], handles_[1]};
  731. std::vector<Slice> expected_keys{"key_1", "key_2", "key_3"};
  732. std::vector<Slice> expected_values{"key_1_cf_0_val", "key_2_cf_1_val",
  733. "key_3_cf_1_val"};
  734. VerifyCoalescingIterator(cfhs_order_3_2_0_1, expected_keys, expected_values,
  735. /* expected_wide_columns */ std::nullopt,
  736. /* lower_bound */ nullptr, /* upper_bound */ nullptr,
  737. /* allow_unprepared_value */ true);
  738. ReadOptions read_options;
  739. read_options.allow_unprepared_value = true;
  740. {
  741. std::unique_ptr<Iterator> iter =
  742. db_->NewCoalescingIterator(read_options, cfhs_order_3_2_0_1);
  743. iter->Seek("");
  744. ASSERT_EQ(IterStatus(iter.get()), "key_1->");
  745. ASSERT_TRUE(iter->PrepareValue());
  746. ASSERT_EQ(IterStatus(iter.get()), "key_1->key_1_cf_0_val");
  747. iter->Seek("key_1");
  748. ASSERT_EQ(IterStatus(iter.get()), "key_1->");
  749. ASSERT_TRUE(iter->PrepareValue());
  750. ASSERT_EQ(IterStatus(iter.get()), "key_1->key_1_cf_0_val");
  751. iter->Seek("key_2");
  752. ASSERT_EQ(IterStatus(iter.get()), "key_2->");
  753. ASSERT_TRUE(iter->PrepareValue());
  754. ASSERT_EQ(IterStatus(iter.get()), "key_2->key_2_cf_1_val");
  755. iter->Next();
  756. ASSERT_EQ(IterStatus(iter.get()), "key_3->");
  757. ASSERT_TRUE(iter->PrepareValue());
  758. ASSERT_EQ(IterStatus(iter.get()), "key_3->key_3_cf_1_val");
  759. iter->Seek("key_x");
  760. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  761. }
  762. {
  763. std::unique_ptr<Iterator> iter =
  764. db_->NewCoalescingIterator(read_options, cfhs_order_3_2_0_1);
  765. iter->SeekForPrev("");
  766. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  767. iter->SeekForPrev("key_1");
  768. ASSERT_EQ(IterStatus(iter.get()), "key_1->");
  769. ASSERT_TRUE(iter->PrepareValue());
  770. ASSERT_EQ(IterStatus(iter.get()), "key_1->key_1_cf_0_val");
  771. iter->Next();
  772. ASSERT_EQ(IterStatus(iter.get()), "key_2->");
  773. ASSERT_TRUE(iter->PrepareValue());
  774. ASSERT_EQ(IterStatus(iter.get()), "key_2->key_2_cf_1_val");
  775. iter->SeekForPrev("key_x");
  776. ASSERT_EQ(IterStatus(iter.get()), "key_3->");
  777. ASSERT_TRUE(iter->PrepareValue());
  778. ASSERT_EQ(IterStatus(iter.get()), "key_3->key_3_cf_1_val");
  779. iter->Next();
  780. ASSERT_EQ(IterStatus(iter.get()), "(invalid)");
  781. }
  782. }
  783. TEST_F(CoalescingIteratorTest, AllowUnpreparedValue_Corruption) {
  784. Options options = GetDefaultOptions();
  785. options.enable_blob_files = true;
  786. CreateAndReopenWithCF({"cf_1", "cf_2", "cf_3"}, options);
  787. ASSERT_OK(Put(0, "key_1", "key_1_cf_0_val"));
  788. ASSERT_OK(Put(3, "key_1", "key_1_cf_3_val"));
  789. ASSERT_OK(Put(1, "key_2", "key_2_cf_1_val"));
  790. ASSERT_OK(Put(2, "key_2", "key_2_cf_2_val"));
  791. ASSERT_OK(Put(0, "key_3", "key_3_cf_0_val"));
  792. ASSERT_OK(Put(1, "key_3", "key_3_cf_1_val"));
  793. ASSERT_OK(Put(3, "key_3", "key_3_cf_3_val"));
  794. ASSERT_OK(Flush());
  795. ReadOptions read_options;
  796. read_options.allow_unprepared_value = true;
  797. std::vector<ColumnFamilyHandle*> cfhs_order_3_2_0_1{handles_[3], handles_[2],
  798. handles_[0], handles_[1]};
  799. std::unique_ptr<Iterator> iter =
  800. db_->NewCoalescingIterator(read_options, cfhs_order_3_2_0_1);
  801. iter->SeekToFirst();
  802. ASSERT_TRUE(iter->Valid());
  803. ASSERT_OK(iter->status());
  804. ASSERT_EQ(iter->key(), "key_1");
  805. ASSERT_TRUE(iter->value().empty());
  806. SyncPoint::GetInstance()->SetCallBack(
  807. "BlobFileReader::GetBlob:TamperWithResult", [](void* arg) {
  808. Slice* const blob_index = static_cast<Slice*>(arg);
  809. assert(blob_index);
  810. assert(!blob_index->empty());
  811. blob_index->remove_prefix(1);
  812. });
  813. SyncPoint::GetInstance()->EnableProcessing();
  814. ASSERT_FALSE(iter->PrepareValue());
  815. ASSERT_FALSE(iter->Valid());
  816. ASSERT_TRUE(iter->status().IsCorruption());
  817. SyncPoint::GetInstance()->DisableProcessing();
  818. SyncPoint::GetInstance()->ClearAllCallBacks();
  819. }
  820. class AttributeGroupIteratorTest : public DBTestBase {
  821. public:
  822. AttributeGroupIteratorTest()
  823. : DBTestBase("attribute_group_iterator_test", /*env_do_fsync=*/true) {}
  824. void VerifyAttributeGroupIterator(
  825. const std::vector<ColumnFamilyHandle*>& cfhs,
  826. const std::vector<Slice>& expected_keys,
  827. const std::vector<IteratorAttributeGroups>& expected_attribute_groups,
  828. const Slice* lower_bound = nullptr, const Slice* upper_bound = nullptr,
  829. bool allow_unprepared_value = false) {
  830. const size_t num_keys = expected_keys.size();
  831. ReadOptions read_options;
  832. read_options.iterate_lower_bound = lower_bound;
  833. read_options.iterate_upper_bound = upper_bound;
  834. read_options.allow_unprepared_value = allow_unprepared_value;
  835. std::unique_ptr<AttributeGroupIterator> iter =
  836. db_->NewAttributeGroupIterator(read_options, cfhs);
  837. auto check_iter_entry = [&](size_t idx) {
  838. ASSERT_EQ(iter->key(), expected_keys[idx]);
  839. if (allow_unprepared_value) {
  840. ASSERT_TRUE(iter->attribute_groups().empty());
  841. ASSERT_TRUE(iter->PrepareValue());
  842. ASSERT_TRUE(iter->Valid());
  843. }
  844. ASSERT_EQ(iter->attribute_groups(), expected_attribute_groups[idx]);
  845. };
  846. {
  847. size_t i = 0;
  848. for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
  849. check_iter_entry(i);
  850. ++i;
  851. }
  852. ASSERT_EQ(i, num_keys);
  853. ASSERT_OK(iter->status());
  854. }
  855. {
  856. size_t i = 0;
  857. for (iter->SeekToLast(); iter->Valid(); iter->Prev()) {
  858. check_iter_entry(num_keys - 1 - i);
  859. ++i;
  860. }
  861. ASSERT_EQ(i, num_keys);
  862. ASSERT_OK(iter->status());
  863. }
  864. }
  865. };
  866. TEST_F(AttributeGroupIteratorTest, IterateAttributeGroups) {
  867. // Set up the DB and Column Families
  868. Options options = GetDefaultOptions();
  869. CreateAndReopenWithCF({"cf_1", "cf_2", "cf_3"}, options);
  870. constexpr char key_1[] = "key_1";
  871. WideColumns key_1_columns_in_cf_2{
  872. {kDefaultWideColumnName, "cf_2_col_val_0_key_1"},
  873. {"cf_2_col_name_1", "cf_2_col_val_1_key_1"},
  874. {"cf_2_col_name_2", "cf_2_col_val_2_key_1"}};
  875. WideColumns key_1_columns_in_cf_3{
  876. {"cf_3_col_name_1", "cf_3_col_val_1_key_1"},
  877. {"cf_3_col_name_2", "cf_3_col_val_2_key_1"},
  878. {"cf_3_col_name_3", "cf_3_col_val_3_key_1"}};
  879. constexpr char key_2[] = "key_2";
  880. WideColumns key_2_columns_in_cf_1{
  881. {"cf_1_col_name_1", "cf_1_col_val_1_key_2"}};
  882. WideColumns key_2_columns_in_cf_2{
  883. {"cf_2_col_name_1", "cf_2_col_val_1_key_2"},
  884. {"cf_2_col_name_2", "cf_2_col_val_2_key_2"}};
  885. constexpr char key_3[] = "key_3";
  886. WideColumns key_3_columns_in_cf_1{
  887. {"cf_1_col_name_1", "cf_1_col_val_1_key_3"}};
  888. WideColumns key_3_columns_in_cf_3{
  889. {"cf_3_col_name_1", "cf_3_col_val_1_key_3"}};
  890. constexpr char key_4[] = "key_4";
  891. WideColumns key_4_columns_in_cf_0{
  892. {"cf_0_col_name_1", "cf_0_col_val_1_key_4"}};
  893. WideColumns key_4_columns_in_cf_2{
  894. {"cf_2_col_name_1", "cf_2_col_val_1_key_4"}};
  895. AttributeGroups key_1_attribute_groups{
  896. AttributeGroup(handles_[2], key_1_columns_in_cf_2),
  897. AttributeGroup(handles_[3], key_1_columns_in_cf_3)};
  898. AttributeGroups key_2_attribute_groups{
  899. AttributeGroup(handles_[1], key_2_columns_in_cf_1),
  900. AttributeGroup(handles_[2], key_2_columns_in_cf_2)};
  901. AttributeGroups key_3_attribute_groups{
  902. AttributeGroup(handles_[1], key_3_columns_in_cf_1),
  903. AttributeGroup(handles_[3], key_3_columns_in_cf_3)};
  904. AttributeGroups key_4_attribute_groups{
  905. AttributeGroup(handles_[0], key_4_columns_in_cf_0),
  906. AttributeGroup(handles_[2], key_4_columns_in_cf_2)};
  907. ASSERT_OK(db_->PutEntity(WriteOptions(), key_1, key_1_attribute_groups));
  908. ASSERT_OK(db_->PutEntity(WriteOptions(), key_2, key_2_attribute_groups));
  909. ASSERT_OK(db_->PutEntity(WriteOptions(), key_3, key_3_attribute_groups));
  910. ASSERT_OK(db_->PutEntity(WriteOptions(), key_4, key_4_attribute_groups));
  911. IteratorAttributeGroups key_1_expected_attribute_groups{
  912. IteratorAttributeGroup(key_1_attribute_groups[0]),
  913. IteratorAttributeGroup(key_1_attribute_groups[1])};
  914. IteratorAttributeGroups key_2_expected_attribute_groups{
  915. IteratorAttributeGroup(key_2_attribute_groups[0]),
  916. IteratorAttributeGroup(key_2_attribute_groups[1])};
  917. IteratorAttributeGroups key_3_expected_attribute_groups{
  918. IteratorAttributeGroup(key_3_attribute_groups[0]),
  919. IteratorAttributeGroup(key_3_attribute_groups[1])};
  920. IteratorAttributeGroups key_4_expected_attribute_groups{
  921. IteratorAttributeGroup(key_4_attribute_groups[0]),
  922. IteratorAttributeGroup(key_4_attribute_groups[1])};
  923. // Test for iteration over CF default->1->2->3
  924. std::vector<ColumnFamilyHandle*> cfhs_order_0_1_2_3 = {
  925. handles_[0], handles_[1], handles_[2], handles_[3]};
  926. {
  927. std::vector<Slice> expected_keys = {key_1, key_2, key_3, key_4};
  928. std::vector<IteratorAttributeGroups> expected_attribute_groups{
  929. key_1_expected_attribute_groups, key_2_expected_attribute_groups,
  930. key_3_expected_attribute_groups, key_4_expected_attribute_groups};
  931. VerifyAttributeGroupIterator(cfhs_order_0_1_2_3, expected_keys,
  932. expected_attribute_groups);
  933. }
  934. Slice lb = Slice("key_2");
  935. Slice ub = Slice("key_4");
  936. // Test for lower bound only
  937. {
  938. std::vector<Slice> expected_keys = {key_2, key_3, key_4};
  939. std::vector<IteratorAttributeGroups> expected_attribute_groups{
  940. key_2_expected_attribute_groups, key_3_expected_attribute_groups,
  941. key_4_expected_attribute_groups};
  942. VerifyAttributeGroupIterator(cfhs_order_0_1_2_3, expected_keys,
  943. expected_attribute_groups, &lb);
  944. }
  945. // Test for upper bound only
  946. {
  947. std::vector<Slice> expected_keys = {key_1, key_2, key_3};
  948. std::vector<IteratorAttributeGroups> expected_attribute_groups{
  949. key_1_expected_attribute_groups, key_2_expected_attribute_groups,
  950. key_3_expected_attribute_groups};
  951. VerifyAttributeGroupIterator(cfhs_order_0_1_2_3, expected_keys,
  952. expected_attribute_groups, nullptr, &ub);
  953. }
  954. // Test for lower and upper bound
  955. {
  956. std::vector<Slice> expected_keys = {key_2, key_3};
  957. std::vector<IteratorAttributeGroups> expected_attribute_groups{
  958. key_2_expected_attribute_groups, key_3_expected_attribute_groups};
  959. VerifyAttributeGroupIterator(cfhs_order_0_1_2_3, expected_keys,
  960. expected_attribute_groups, &lb, &ub);
  961. }
  962. }
  963. TEST_F(AttributeGroupIteratorTest, AllowUnpreparedValue) {
  964. Options options = GetDefaultOptions();
  965. CreateAndReopenWithCF({"cf_1", "cf_2", "cf_3"}, options);
  966. constexpr char key_1[] = "key_1";
  967. WideColumns key_1_columns_in_cf_2{
  968. {kDefaultWideColumnName, "cf_2_col_val_0_key_1"},
  969. {"cf_2_col_name_1", "cf_2_col_val_1_key_1"},
  970. {"cf_2_col_name_2", "cf_2_col_val_2_key_1"}};
  971. WideColumns key_1_columns_in_cf_3{
  972. {"cf_3_col_name_1", "cf_3_col_val_1_key_1"},
  973. {"cf_3_col_name_2", "cf_3_col_val_2_key_1"},
  974. {"cf_3_col_name_3", "cf_3_col_val_3_key_1"}};
  975. constexpr char key_2[] = "key_2";
  976. WideColumns key_2_columns_in_cf_1{
  977. {"cf_1_col_name_1", "cf_1_col_val_1_key_2"}};
  978. WideColumns key_2_columns_in_cf_2{
  979. {"cf_2_col_name_1", "cf_2_col_val_1_key_2"},
  980. {"cf_2_col_name_2", "cf_2_col_val_2_key_2"}};
  981. constexpr char key_3[] = "key_3";
  982. WideColumns key_3_columns_in_cf_1{
  983. {"cf_1_col_name_1", "cf_1_col_val_1_key_3"}};
  984. WideColumns key_3_columns_in_cf_3{
  985. {"cf_3_col_name_1", "cf_3_col_val_1_key_3"}};
  986. constexpr char key_4[] = "key_4";
  987. WideColumns key_4_columns_in_cf_0{
  988. {"cf_0_col_name_1", "cf_0_col_val_1_key_4"}};
  989. WideColumns key_4_columns_in_cf_2{
  990. {"cf_2_col_name_1", "cf_2_col_val_1_key_4"}};
  991. AttributeGroups key_1_attribute_groups{
  992. AttributeGroup(handles_[2], key_1_columns_in_cf_2),
  993. AttributeGroup(handles_[3], key_1_columns_in_cf_3)};
  994. AttributeGroups key_2_attribute_groups{
  995. AttributeGroup(handles_[1], key_2_columns_in_cf_1),
  996. AttributeGroup(handles_[2], key_2_columns_in_cf_2)};
  997. AttributeGroups key_3_attribute_groups{
  998. AttributeGroup(handles_[1], key_3_columns_in_cf_1),
  999. AttributeGroup(handles_[3], key_3_columns_in_cf_3)};
  1000. AttributeGroups key_4_attribute_groups{
  1001. AttributeGroup(handles_[0], key_4_columns_in_cf_0),
  1002. AttributeGroup(handles_[2], key_4_columns_in_cf_2)};
  1003. ASSERT_OK(db_->PutEntity(WriteOptions(), key_1, key_1_attribute_groups));
  1004. ASSERT_OK(db_->PutEntity(WriteOptions(), key_2, key_2_attribute_groups));
  1005. ASSERT_OK(db_->PutEntity(WriteOptions(), key_3, key_3_attribute_groups));
  1006. ASSERT_OK(db_->PutEntity(WriteOptions(), key_4, key_4_attribute_groups));
  1007. IteratorAttributeGroups key_1_expected_attribute_groups{
  1008. IteratorAttributeGroup(key_1_attribute_groups[0]),
  1009. IteratorAttributeGroup(key_1_attribute_groups[1])};
  1010. IteratorAttributeGroups key_2_expected_attribute_groups{
  1011. IteratorAttributeGroup(key_2_attribute_groups[0]),
  1012. IteratorAttributeGroup(key_2_attribute_groups[1])};
  1013. IteratorAttributeGroups key_3_expected_attribute_groups{
  1014. IteratorAttributeGroup(key_3_attribute_groups[0]),
  1015. IteratorAttributeGroup(key_3_attribute_groups[1])};
  1016. IteratorAttributeGroups key_4_expected_attribute_groups{
  1017. IteratorAttributeGroup(key_4_attribute_groups[0]),
  1018. IteratorAttributeGroup(key_4_attribute_groups[1])};
  1019. std::vector<ColumnFamilyHandle*> cfhs_order_0_1_2_3{handles_[0], handles_[1],
  1020. handles_[2], handles_[3]};
  1021. std::vector<Slice> expected_keys{key_1, key_2, key_3, key_4};
  1022. std::vector<IteratorAttributeGroups> expected_attribute_groups{
  1023. key_1_expected_attribute_groups, key_2_expected_attribute_groups,
  1024. key_3_expected_attribute_groups, key_4_expected_attribute_groups};
  1025. VerifyAttributeGroupIterator(
  1026. cfhs_order_0_1_2_3, expected_keys, expected_attribute_groups,
  1027. /* lower_bound */ nullptr, /* upper_bound */ nullptr,
  1028. /* allow_unprepared_value */ true);
  1029. }
  1030. } // namespace ROCKSDB_NAMESPACE
  1031. int main(int argc, char** argv) {
  1032. ROCKSDB_NAMESPACE::port::InstallStackTraceHandler();
  1033. ::testing::InitGoogleTest(&argc, argv);
  1034. return RUN_ALL_TESTS();
  1035. }