@@ -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
0 commit comments