TestSqlBtreeIndex.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  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::Heap& heap);
  120. void insert_and_get_to_and_from_btree(int num_keys);
  121. void insert_into_and_scan_btree(int num_keys);
  122. NonnullRefPtr<SQL::BTree> setup_btree(SQL::Heap& heap)
  123. {
  124. NonnullRefPtr<SQL::TupleDescriptor> tuple_descriptor = adopt_ref(*new SQL::TupleDescriptor);
  125. tuple_descriptor->append({ "key_value", SQL::SQLType::Integer, SQL::Order::Ascending });
  126. auto root_pointer = heap.user_value(0);
  127. if (!root_pointer) {
  128. root_pointer = heap.new_record_pointer();
  129. heap.set_user_value(0, root_pointer);
  130. }
  131. auto btree = SQL::BTree::construct(heap, tuple_descriptor, true, root_pointer);
  132. btree->on_new_root = [&]() {
  133. 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. auto btree = setup_btree(heap);
  143. for (auto ix = 0; ix < num_keys; ix++) {
  144. SQL::Key k(btree->descriptor());
  145. k[0] = keys[ix];
  146. k.set_pointer(pointers[ix]);
  147. btree->insert(k);
  148. }
  149. #ifdef LIST_TREE
  150. btree->list_tree();
  151. #endif
  152. }
  153. {
  154. auto heap = SQL::Heap::construct("/tmp/test.db");
  155. auto btree = setup_btree(heap);
  156. for (auto ix = 0; ix < num_keys; ix++) {
  157. SQL::Key k(btree->descriptor());
  158. k[0] = keys[ix];
  159. auto pointer_opt = btree->get(k);
  160. EXPECT(pointer_opt.has_value());
  161. EXPECT_EQ(pointer_opt.value(), pointers[ix]);
  162. }
  163. }
  164. }
  165. void insert_into_and_scan_btree(int num_keys)
  166. {
  167. ScopeGuard guard([]() { unlink("/tmp/test.db"); });
  168. {
  169. auto heap = SQL::Heap::construct("/tmp/test.db");
  170. auto btree = setup_btree(heap);
  171. for (auto ix = 0; ix < num_keys; ix++) {
  172. SQL::Key k(btree->descriptor());
  173. k[0] = keys[ix];
  174. k.set_pointer(pointers[ix]);
  175. btree->insert(k);
  176. }
  177. #ifdef LIST_TREE
  178. btree->list_tree();
  179. #endif
  180. }
  181. {
  182. auto heap = SQL::Heap::construct("/tmp/test.db");
  183. auto btree = setup_btree(heap);
  184. int count = 0;
  185. SQL::Tuple prev;
  186. for (auto iter = btree->begin(); !iter.is_end(); iter++, count++) {
  187. auto key = (*iter);
  188. if (prev.length()) {
  189. EXPECT(prev < key);
  190. }
  191. auto key_value = (int)key[0];
  192. for (auto ix = 0; ix < num_keys; ix++) {
  193. if (keys[ix] == key_value) {
  194. EXPECT_EQ(key.pointer(), pointers[ix]);
  195. break;
  196. }
  197. }
  198. prev = key;
  199. }
  200. EXPECT_EQ(count, num_keys);
  201. }
  202. }
  203. TEST_CASE(btree_one_key)
  204. {
  205. insert_and_get_to_and_from_btree(1);
  206. }
  207. TEST_CASE(btree_four_keys)
  208. {
  209. insert_and_get_to_and_from_btree(4);
  210. }
  211. TEST_CASE(btree_five_keys)
  212. {
  213. insert_and_get_to_and_from_btree(5);
  214. }
  215. TEST_CASE(btree_10_keys)
  216. {
  217. insert_and_get_to_and_from_btree(10);
  218. }
  219. TEST_CASE(btree_13_keys)
  220. {
  221. insert_and_get_to_and_from_btree(13);
  222. }
  223. TEST_CASE(btree_20_keys)
  224. {
  225. insert_and_get_to_and_from_btree(20);
  226. }
  227. TEST_CASE(btree_25_keys)
  228. {
  229. insert_and_get_to_and_from_btree(25);
  230. }
  231. TEST_CASE(btree_30_keys)
  232. {
  233. insert_and_get_to_and_from_btree(30);
  234. }
  235. TEST_CASE(btree_35_keys)
  236. {
  237. insert_and_get_to_and_from_btree(35);
  238. }
  239. TEST_CASE(btree_40_keys)
  240. {
  241. insert_and_get_to_and_from_btree(40);
  242. }
  243. TEST_CASE(btree_45_keys)
  244. {
  245. insert_and_get_to_and_from_btree(45);
  246. }
  247. TEST_CASE(btree_50_keys)
  248. {
  249. insert_and_get_to_and_from_btree(50);
  250. }
  251. TEST_CASE(btree_scan_one_key)
  252. {
  253. insert_into_and_scan_btree(1);
  254. }
  255. TEST_CASE(btree_scan_four_keys)
  256. {
  257. insert_into_and_scan_btree(4);
  258. }
  259. TEST_CASE(btree_scan_five_keys)
  260. {
  261. insert_into_and_scan_btree(5);
  262. }
  263. TEST_CASE(btree_scan_10_keys)
  264. {
  265. insert_into_and_scan_btree(10);
  266. }
  267. TEST_CASE(btree_scan_15_keys)
  268. {
  269. insert_into_and_scan_btree(15);
  270. }
  271. TEST_CASE(btree_scan_30_keys)
  272. {
  273. insert_into_and_scan_btree(15);
  274. }
  275. TEST_CASE(btree_scan_50_keys)
  276. {
  277. insert_into_and_scan_btree(50);
  278. }