TestSqlBtreeIndex.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. /*
  2. * Copyright (c) 2021, Jan de Visser <jan@de-visser.net>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <unistd.h>
  7. #include <AK/ScopeGuard.h>
  8. #include <LibSQL/BTree.h>
  9. #include <LibSQL/Heap.h>
  10. #include <LibSQL/Key.h>
  11. #include <LibSQL/Meta.h>
  12. #include <LibSQL/TupleDescriptor.h>
  13. #include <LibSQL/Value.h>
  14. #include <LibTest/TestCase.h>
  15. constexpr static int keys[] = {
  16. 39,
  17. 87,
  18. 77,
  19. 42,
  20. 98,
  21. 40,
  22. 53,
  23. 8,
  24. 37,
  25. 12,
  26. 90,
  27. 72,
  28. 73,
  29. 11,
  30. 88,
  31. 22,
  32. 10,
  33. 82,
  34. 25,
  35. 61,
  36. 97,
  37. 18,
  38. 60,
  39. 68,
  40. 21,
  41. 3,
  42. 58,
  43. 29,
  44. 13,
  45. 17,
  46. 89,
  47. 81,
  48. 16,
  49. 64,
  50. 5,
  51. 41,
  52. 36,
  53. 91,
  54. 38,
  55. 24,
  56. 32,
  57. 50,
  58. 34,
  59. 94,
  60. 49,
  61. 47,
  62. 1,
  63. 6,
  64. 44,
  65. 76,
  66. };
  67. constexpr static u32 pointers[] = {
  68. 92,
  69. 4,
  70. 50,
  71. 47,
  72. 68,
  73. 73,
  74. 24,
  75. 28,
  76. 50,
  77. 93,
  78. 60,
  79. 36,
  80. 92,
  81. 72,
  82. 53,
  83. 26,
  84. 91,
  85. 84,
  86. 25,
  87. 43,
  88. 88,
  89. 12,
  90. 62,
  91. 35,
  92. 96,
  93. 27,
  94. 96,
  95. 27,
  96. 99,
  97. 30,
  98. 21,
  99. 89,
  100. 54,
  101. 60,
  102. 37,
  103. 68,
  104. 35,
  105. 55,
  106. 80,
  107. 2,
  108. 33,
  109. 26,
  110. 93,
  111. 70,
  112. 45,
  113. 44,
  114. 3,
  115. 66,
  116. 75,
  117. 4,
  118. };
  119. NonnullRefPtr<SQL::BTree> setup_btree(SQL::Serializer&);
  120. void insert_and_get_to_and_from_btree(int);
  121. void insert_into_and_scan_btree(int);
  122. NonnullRefPtr<SQL::BTree> setup_btree(SQL::Serializer& serializer)
  123. {
  124. NonnullRefPtr<SQL::TupleDescriptor> tuple_descriptor = adopt_ref(*new SQL::TupleDescriptor);
  125. tuple_descriptor->append({ "schema", "table", "key_value", SQL::SQLType::Integer, SQL::Order::Ascending });
  126. auto root_pointer = serializer.heap().user_value(0);
  127. if (!root_pointer) {
  128. root_pointer = serializer.heap().new_record_pointer();
  129. serializer.heap().set_user_value(0, root_pointer);
  130. }
  131. auto btree = SQL::BTree::construct(serializer, tuple_descriptor, true, root_pointer);
  132. btree->on_new_root = [&]() {
  133. serializer.heap().set_user_value(0, btree->root());
  134. };
  135. return btree;
  136. }
  137. void insert_and_get_to_and_from_btree(int num_keys)
  138. {
  139. ScopeGuard guard([]() { unlink("/tmp/test.db"); });
  140. {
  141. auto heap = SQL::Heap::construct("/tmp/test.db");
  142. EXPECT(!heap->open().is_error());
  143. SQL::Serializer serializer(heap);
  144. auto btree = setup_btree(serializer);
  145. for (auto ix = 0; ix < num_keys; ix++) {
  146. SQL::Key k(btree->descriptor());
  147. k[0] = keys[ix];
  148. k.set_pointer(pointers[ix]);
  149. btree->insert(k);
  150. }
  151. #ifdef LIST_TREE
  152. btree->list_tree();
  153. #endif
  154. }
  155. {
  156. auto heap = SQL::Heap::construct("/tmp/test.db");
  157. EXPECT(!heap->open().is_error());
  158. SQL::Serializer serializer(heap);
  159. auto btree = setup_btree(serializer);
  160. for (auto ix = 0; ix < num_keys; ix++) {
  161. SQL::Key k(btree->descriptor());
  162. k[0] = keys[ix];
  163. auto pointer_opt = btree->get(k);
  164. VERIFY(pointer_opt.has_value());
  165. EXPECT_EQ(pointer_opt.value(), pointers[ix]);
  166. }
  167. }
  168. }
  169. void insert_into_and_scan_btree(int num_keys)
  170. {
  171. ScopeGuard guard([]() { unlink("/tmp/test.db"); });
  172. {
  173. auto heap = SQL::Heap::construct("/tmp/test.db");
  174. EXPECT(!heap->open().is_error());
  175. SQL::Serializer serializer(heap);
  176. auto btree = setup_btree(serializer);
  177. for (auto ix = 0; ix < num_keys; ix++) {
  178. SQL::Key k(btree->descriptor());
  179. k[0] = keys[ix];
  180. k.set_pointer(pointers[ix]);
  181. btree->insert(k);
  182. }
  183. #ifdef LIST_TREE
  184. btree->list_tree();
  185. #endif
  186. }
  187. {
  188. auto heap = SQL::Heap::construct("/tmp/test.db");
  189. EXPECT(!heap->open().is_error());
  190. SQL::Serializer serializer(heap);
  191. auto btree = setup_btree(serializer);
  192. int count = 0;
  193. SQL::Tuple prev;
  194. for (auto iter = btree->begin(); !iter.is_end(); iter++, count++) {
  195. auto key = (*iter);
  196. if (prev.size()) {
  197. EXPECT(prev < key);
  198. }
  199. auto key_value = (int)key[0];
  200. for (auto ix = 0; ix < num_keys; ix++) {
  201. if (keys[ix] == key_value) {
  202. EXPECT_EQ(key.pointer(), pointers[ix]);
  203. break;
  204. }
  205. }
  206. prev = key;
  207. }
  208. EXPECT_EQ(count, num_keys);
  209. }
  210. }
  211. TEST_CASE(btree_one_key)
  212. {
  213. insert_and_get_to_and_from_btree(1);
  214. }
  215. TEST_CASE(btree_four_keys)
  216. {
  217. insert_and_get_to_and_from_btree(4);
  218. }
  219. TEST_CASE(btree_five_keys)
  220. {
  221. insert_and_get_to_and_from_btree(5);
  222. }
  223. TEST_CASE(btree_10_keys)
  224. {
  225. insert_and_get_to_and_from_btree(10);
  226. }
  227. TEST_CASE(btree_13_keys)
  228. {
  229. insert_and_get_to_and_from_btree(13);
  230. }
  231. TEST_CASE(btree_20_keys)
  232. {
  233. insert_and_get_to_and_from_btree(20);
  234. }
  235. TEST_CASE(btree_25_keys)
  236. {
  237. insert_and_get_to_and_from_btree(25);
  238. }
  239. TEST_CASE(btree_30_keys)
  240. {
  241. insert_and_get_to_and_from_btree(30);
  242. }
  243. TEST_CASE(btree_35_keys)
  244. {
  245. insert_and_get_to_and_from_btree(35);
  246. }
  247. TEST_CASE(btree_40_keys)
  248. {
  249. insert_and_get_to_and_from_btree(40);
  250. }
  251. TEST_CASE(btree_45_keys)
  252. {
  253. insert_and_get_to_and_from_btree(45);
  254. }
  255. TEST_CASE(btree_50_keys)
  256. {
  257. insert_and_get_to_and_from_btree(50);
  258. }
  259. TEST_CASE(btree_scan_one_key)
  260. {
  261. insert_into_and_scan_btree(1);
  262. }
  263. TEST_CASE(btree_scan_four_keys)
  264. {
  265. insert_into_and_scan_btree(4);
  266. }
  267. TEST_CASE(btree_scan_five_keys)
  268. {
  269. insert_into_and_scan_btree(5);
  270. }
  271. TEST_CASE(btree_scan_10_keys)
  272. {
  273. insert_into_and_scan_btree(10);
  274. }
  275. TEST_CASE(btree_scan_15_keys)
  276. {
  277. insert_into_and_scan_btree(15);
  278. }
  279. TEST_CASE(btree_scan_30_keys)
  280. {
  281. insert_into_and_scan_btree(15);
  282. }
  283. TEST_CASE(btree_scan_50_keys)
  284. {
  285. insert_into_and_scan_btree(50);
  286. }