Skip to content

Commit e186833

Browse files
author
Can Gokmen
committed
Implemented evrything until the last group
1 parent 6d8a666 commit e186833

2 files changed

Lines changed: 132 additions & 56 deletions

File tree

ART.h

Lines changed: 112 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ class ART {
176176
void bulkLoad(const std::vector<uint32_t>& keys, const std::vector<uint32_t>& values) {
177177
ArtNode* bl_ptr = nullptr; // pointer to current bulk load node
178178
ArtNode** bl_ptr_ref = &this->root; // reference to current bulk load node
179-
std::array<int8_t, 3> bl_pf_bytes; // key bytes for d1, d2, d3 nodes
179+
std::array<uint8_t, 3> bl_pf_bytes; // key bytes for d1, d2, d3 nodes
180180

181181
// Calculate number of complete groups of 256
182182
size_t num_complete_groups = keys.size() / 256;
@@ -203,7 +203,7 @@ class ART {
203203

204204
bl_ptr = d2_node;
205205
bl_ptr_ref = findChild(*findChild(this->root, 0), 0);
206-
bl_pf_bytes = {0, 0, 0};
206+
bl_pf_bytes = {{0, 0, 0}};
207207

208208
// Insert 256 keys into this group
209209
for (size_t i = 1; i < 256; i++) {
@@ -212,7 +212,7 @@ class ART {
212212
}
213213
}
214214

215-
this->printTree();
215+
//this->printTree();
216216

217217
// Process complete groups of 256 keys
218218
for (size_t group = 1; group < num_complete_groups; group++) {
@@ -223,73 +223,129 @@ class ART {
223223
uint8_t b1 = (start_idx >> 16) & 0xFF;
224224
uint8_t b2 = (start_idx >> 8) & 0xFF;
225225

226-
// Check if this is a bridge value (transitioning to new prefix)
227-
bool is_bridge = false;
228-
229226
// Bridge at byte 0: b0 changed, b1=0, b2=0, previous b0 was at max (255)
230-
if (b0 != bl_pf_bytes[0] && b1 == 0 && b2 == 0 &&
231-
bl_pf_bytes[1] == -1 && bl_pf_bytes[2] == -1) {
232-
is_bridge = true;
227+
if (b0 != bl_pf_bytes[0] && b1 == 0 && b2 == 0) {
228+
Node4* new_d1_node = new Node4();
229+
new_d1_node->prefixLength = 0;
230+
switch (this->root->type) {
231+
case NodeType4:
232+
static_cast<Node4*>(this->root)->bulkLoadInsertNode4(this, &this->root, b0, new_d1_node, bl_ptr);
233+
break;
234+
case NodeType16:
235+
static_cast<Node16*>(this->root)->bulkLoadInsertNode16(this, &this->root, b0, new_d1_node, bl_ptr);
236+
break;
237+
case NodeType48:
238+
static_cast<Node48*>(this->root)->bulkLoadInsertNode48(this, &this->root, b0, new_d1_node, bl_ptr);
239+
break;
240+
case NodeType256:
241+
static_cast<Node256*>(this->root)->bulkLoadInsertNode256(this, &this->root, b0, new_d1_node, bl_ptr);
242+
break;
243+
}
244+
// insert a d2 node under new d1 node
245+
ArtNode** d1_ref = findChild(this->root, b0);
246+
ArtNode* d1_node = *d1_ref;
247+
Node4* new_d2_node = new Node4();
248+
new_d2_node->prefixLength = 0;
249+
static_cast<Node4*>(d1_node)->bulkLoadInsertNode4(this, d1_ref, b1, new_d2_node, bl_ptr);
250+
// Update bl_ptr to new d2 node
251+
bl_ptr = new_d2_node;
252+
bl_ptr_ref = findChild(*d1_ref, b1);
253+
bl_pf_bytes = {b0, 0, 0};
254+
255+
// insert the grouped keys into d3 node under new d2 node
256+
Node256* d3_node = new Node256();
257+
d3_node->prefixLength = 0;
258+
static_cast<Node4*>(new_d2_node)->bulkLoadInsertNode4(this, bl_ptr_ref, b2, d3_node, bl_ptr);
259+
// Insert 256 keys into d3 node
260+
for (size_t i = 0; i < 256; i++) {
261+
uint8_t b3 = keys[start_idx + i] & 0xFF;
262+
d3_node->child[b3] = makeLeaf(values[start_idx + i]);
263+
}
264+
continue;
233265
}
234266
// Bridge at byte 1: b0 same, b1 changed, b2=0, previous b1 was at max
235-
else if (b0 == bl_pf_bytes[0] && b1 != bl_pf_bytes[1] && b2 == 0 &&
236-
bl_pf_bytes[2] == -1) {
237-
is_bridge = true;
238-
// Navigate from root->d1 to create new d2->d3 path
239-
}
240-
// Bridge at byte 2: b0 same, b1 same, b2 changed, previous b2 was at max
241-
else if (b0 == bl_pf_bytes[0] && b1 == bl_pf_bytes[1] && b2 != bl_pf_bytes[2] &&
242-
bl_pf_bytes[2] == -1) {
243-
is_bridge = true;
244-
// Reuse bl_ptr (d2 node), create new d3 (Node256) under it
245-
}
246-
247-
if (!is_bridge) {
248-
// Navigate from bl_ptr (d2 node) to get/create d3 node at position b2
249-
ArtNode** d3_ref = findChild(bl_ptr, b2);
250-
Node256* d3_node;
251-
252-
if (*d3_ref == nullptr) {
253-
// Create new d3 node
254-
d3_node = new Node256();
255-
d3_node->prefixLength = 0;
256-
// Insert into bl_ptr (d2 node)
257-
switch (bl_ptr->type) {
258-
case NodeType4:
259-
static_cast<Node4*>(bl_ptr)->bulkLoadInsertNode4(this, bl_ptr_ref, b2, d3_node, bl_ptr);
260-
break;
261-
case NodeType16:
262-
static_cast<Node16*>(bl_ptr)->bulkLoadInsertNode16(this, bl_ptr_ref, b2, d3_node, bl_ptr);
263-
break;
264-
case NodeType48:
265-
static_cast<Node48*>(bl_ptr)->bulkLoadInsertNode48(this, bl_ptr_ref, b2, d3_node, bl_ptr);
266-
break;
267-
case NodeType256:
268-
static_cast<Node256*>(bl_ptr)->bulkLoadInsertNode256(this, bl_ptr_ref, b2, d3_node, bl_ptr);
269-
break;
270-
}
271-
// Re-get the reference after potential expansion
272-
d3_ref = findChild(bl_ptr, b2);
273-
d3_node = static_cast<Node256*>(*d3_ref);
274-
} else {
275-
d3_node = static_cast<Node256*>(*d3_ref);
267+
else if (b0 == bl_pf_bytes[0] && b1 != bl_pf_bytes[1] && b2 == 0) {
268+
ArtNode** d1_ref = findChild(this->root, b0);
269+
ArtNode* d1_node = *d1_ref;
270+
// Create new d2 node
271+
Node4* new_d2_node = new Node4();
272+
new_d2_node->prefixLength = 0;
273+
switch (d1_node->type) {
274+
case NodeType4:
275+
static_cast<Node4*>(d1_node)->bulkLoadInsertNode4(this, d1_ref, b1, new_d2_node, bl_ptr);
276+
break;
277+
case NodeType16:
278+
static_cast<Node16*>(d1_node)->bulkLoadInsertNode16(this, d1_ref, b1, new_d2_node, bl_ptr);
279+
break;
280+
case NodeType48:
281+
static_cast<Node48*>(d1_node)->bulkLoadInsertNode48(this, d1_ref, b1, new_d2_node, bl_ptr);
282+
break;
283+
case NodeType256:
284+
static_cast<Node256*>(d1_node)->bulkLoadInsertNode256(this, d1_ref, b1, new_d2_node, bl_ptr);
285+
break;
276286
}
287+
// Update bl_ptr to new d2 node
288+
bl_ptr = new_d2_node;
289+
bl_ptr_ref = findChild(*d1_ref, b1);
290+
bl_pf_bytes[1] = b1;
291+
bl_pf_bytes[2] = 0;
277292

293+
// insert the grouped keys into d3 node under new d2 node
294+
Node256* d3_node = new Node256();
295+
d3_node->prefixLength = 0;
296+
static_cast<Node4*>(new_d2_node)->bulkLoadInsertNode4(this, bl_ptr_ref, b2, d3_node, bl_ptr);
278297
// Insert 256 keys into d3 node
279298
for (size_t i = 0; i < 256; i++) {
280299
uint8_t b3 = keys[start_idx + i] & 0xFF;
281300
d3_node->child[b3] = makeLeaf(values[start_idx + i]);
282-
}
283-
284-
// Update bl_pf_bytes to track current position
285-
bl_pf_bytes[2] = b2;
301+
}
302+
continue;
303+
}
286304

287-
this->printTree();
305+
// Navigate from bl_ptr (d2 node) to get/create d3 node at position b2
306+
ArtNode** d3_ref = findChild(bl_ptr, b2);
307+
Node256* d3_node;
308+
309+
if (*d3_ref == nullptr) {
310+
// Create new d3 node
311+
d3_node = new Node256();
312+
d3_node->prefixLength = 0;
313+
// Insert into bl_ptr (d2 node)
314+
switch (bl_ptr->type) {
315+
case NodeType4:
316+
static_cast<Node4*>(bl_ptr)->bulkLoadInsertNode4(this, bl_ptr_ref, b2, d3_node, bl_ptr);
317+
break;
318+
case NodeType16:
319+
static_cast<Node16*>(bl_ptr)->bulkLoadInsertNode16(this, bl_ptr_ref, b2, d3_node, bl_ptr);
320+
break;
321+
case NodeType48:
322+
static_cast<Node48*>(bl_ptr)->bulkLoadInsertNode48(this, bl_ptr_ref, b2, d3_node, bl_ptr);
323+
break;
324+
case NodeType256:
325+
static_cast<Node256*>(bl_ptr)->bulkLoadInsertNode256(this, bl_ptr_ref, b2, d3_node, bl_ptr);
326+
break;
327+
}
328+
// Re-get the reference after potential expansion
329+
d3_ref = findChild(bl_ptr, b2);
330+
d3_node = static_cast<Node256*>(*d3_ref);
331+
} else {
332+
d3_node = static_cast<Node256*>(*d3_ref);
333+
}
334+
335+
// Insert 256 keys into d3 node
336+
for (size_t i = 0; i < 256; i++) {
337+
uint8_t b3 = keys[start_idx + i] & 0xFF;
338+
d3_node->child[b3] = makeLeaf(values[start_idx + i]);
288339
}
289340

341+
// Update bl_pf_bytes to track current position
342+
bl_pf_bytes[2] = b2;
343+
344+
//this->printTree();
345+
290346
}
291347

292-
this->printTree();
348+
//this->printTree();
293349
return;
294350
}
295351

run.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,26 @@ int main(int argc, char** argv) {
7979
tree->bulkLoad(keys_to_load, keys_to_load);
8080
auto stop = chrono::high_resolution_clock::now();
8181
insertion_time = chrono::duration_cast<chrono::nanoseconds>(stop - start).count();
82+
83+
long long query_time = 0;
84+
for (uint64_t i = 1; i < N+1; i++) {
85+
uint8_t key[4];
86+
ART::loadKey(keys[i], key);
87+
auto start = chrono::high_resolution_clock::now();
88+
ART::ArtNode* leaf = tree->lookup(key);
89+
auto stop = chrono::high_resolution_clock::now();
90+
auto duration = chrono::duration_cast<chrono::nanoseconds>(stop - start);
91+
query_time += duration.count();
92+
assert(ART::isLeaf(leaf) && ART::getLeafValue(leaf) == keys[i]);
93+
}
94+
95+
if (verbose) {
96+
cout << "Tree type: " << tree_type << endl;
97+
cout << "Insertion time: " << insertion_time << " ns" << endl;
98+
cout << "Query time: " << query_time << " ns" << endl;
99+
}
100+
101+
return 0;
82102
} else {
83103
for (uint64_t i = 0; i < N; i++) {
84104
uint8_t key[4];

0 commit comments

Comments
 (0)