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