@@ -52,29 +52,47 @@ class QuART_lil : ART::ART {
5252
5353 void insert (uint8_t key[], uintptr_t value) {
5454 // std::cout << "Value inserted: " << value << std::endl;
55- if (value >= 65538 ) {
55+ if (value >= 1 ) {
5656 std::cout << std::endl;
5757 // printTree();
5858 }
5959
60- // First, check if the new key fits on the fast path.
61- int depth = 0 ;
60+ // Check if the fast path exists and if the new key fits on the fast
61+ // path.
6262 if (fp != NULL ) {
63- for (size_t i = 0 ; i < fp_path_length - 1 ; i++) {
64- depth += fp_path[i]->prefixLength ;
65- depth++;
63+ bool onFastPath = canLilInsert (key);
64+ bool isFull;
65+ switch (fp->type ) {
66+ case NodeType4:
67+ isFull = fp->count == 4 ;
68+ break ;
69+ case NodeType16:
70+ isFull = fp->count == 16 ;
71+ break ;
72+ case NodeType48:
73+ isFull = fp->count == 48 ;
74+ break ;
75+ case NodeType256:
76+ isFull = fp->count == 256 ;
77+ break ;
78+ };
79+ if (onFastPath && !isFull) {
80+ // If so, insert from the end of the fast path.
81+ insertRecursive (this , fp, fp_ref, key, fp_depth, value,
82+ maxPrefixLength, true );
6683 }
67- }
68- bool onFastPath = canLilInsert (key);
69- if (onFastPath) { // If so, insert from the end of the fast path.
70- // std::cout << "Inserting to fast path" << std::endl;
71- insert (this , fp, &fp, key, depth, value, maxPrefixLength);
7284 } else { // Else, reset the fast path and insert from the root
73- fp = NULL ;
74- fp_path_length = 0 ;
85+ fp = root;
86+ fp_ref = &root;
87+ fp_path_length = 1 ;
88+ fp_depth = (root != NULL && !isLeaf (root)) ? root->prefixLength : 0 ;
7589 fp_path.fill (NULL );
76- // std::cout << "Inserting to root" << std::endl;
77- insert (this , root, &root, key, 0 , value, maxPrefixLength);
90+ fp_path_ref.fill (NULL );
91+ fp_path[0 ] = root;
92+ fp_path_ref[0 ] = &root;
93+ fp_leaf = NULL ;
94+ insertRecursive (this , root, &root, key, fp_depth, value,
95+ maxPrefixLength, true );
7896 }
7997 }
8098
@@ -90,14 +108,14 @@ class QuART_lil : ART::ART {
90108
91109 private:
92110 // Void insert function
93- void insert (QuART_lil* tree, ArtNode* node, ArtNode** nodeRef,
94- uint8_t key[], unsigned depth, uintptr_t value,
95- unsigned maxKeyLength) {
111+ void insertRecursive (QuART_lil* tree, ArtNode* node, ArtNode** nodeRef,
112+ uint8_t key[], unsigned depth, uintptr_t value,
113+ unsigned maxKeyLength, bool firstCall ) {
96114 // Insert the leaf value into the tree
97115
98116 // If tree is empty, populate with a single node.
99- // Do not alter fp values; fp should only refer to internal nodes, not
100- // leaf nodes
117+ // Do not alter fp values; fp should only refer to internal nodes,
118+ // not leaf nodes
101119 if (node == NULL ) {
102120 ArtNode* newLeaf = makeLeaf (value);
103121 *nodeRef = newLeaf;
@@ -128,7 +146,11 @@ class QuART_lil : ART::ART {
128146
129147 // update the fast path
130148 fp = newNode;
131- fp_path[fp_path_length++] = newNode;
149+ fp_ref = nodeRef;
150+ fp_path[0 ] = newNode;
151+ fp_path_ref[0 ] = nodeRef;
152+ fp_path_length = 1 ;
153+ fp_depth = newNode->prefixLength ;
132154 fp_leaf = newLeaf;
133155
134156 return ;
@@ -168,74 +190,68 @@ class QuART_lil : ART::ART {
168190
169191 // update the fast path
170192 fp = newNode;
171- fp_path[fp_path_length++] = newNode;
193+ fp_ref = nodeRef;
194+ fp_path[fp_path_length] = newNode;
195+ fp_path_ref[fp_path_length] = nodeRef;
196+ fp_path_length++;
197+ fp_depth += newNode->prefixLength ;
172198 fp_leaf = newLeaf;
173199
174200 return ;
175201 }
176202 depth += node->prefixLength ;
177203 }
178- // If the last node on the fp is the same as the current internal node
179- // then an insert to fp must be occurring. Avoid adding another pointer
180- // to that node to fp_path.
181- if (node != fp_path[fp_path_length - 1 ]) {
182- fp_path[fp_path_length++] = node;
204+ // The first call in the recursive loop always starts on a node
205+ // already in the fast path. To avoid double-counting it, only
206+ // update these values on subsequent calls.
207+ if (!firstCall) {
183208 fp = node;
209+ fp_ref = nodeRef;
210+ fp_path[fp_path_length] = node;
211+ fp_path_ref[fp_path_length] = nodeRef;
212+ fp_path_length++;
213+ fp_depth += node->prefixLength ;
184214 }
185215
186216 // Recurse
187217 ArtNode** child = findChild (node, key[depth]);
188218 if (*child) {
189- insert (tree, *child, child, key, depth + 1 , value, maxKeyLength);
219+ insertRecursive (tree, *child, child, key, depth + 1 , value,
220+ maxKeyLength, false );
190221 return ;
191222 }
192223
193224 // Insert leaf into inner node
194- ArtNode* newNode = makeLeaf (value);
195- fp_leaf = newNode;
196-
197- // find the pointer to the current internal node in the tree
198- ArtNode** parentPointer =
199- (fp_path_length == 1 )
200- ? &root
201- : findChild (fp_path[fp_path_length - 2 ], key[depth - 1 ]);
202- int8_t nodeType = node->type ;
225+ ArtNode* newLeaf = makeLeaf (value);
226+ fp_leaf = newLeaf;
227+
203228 switch (node->type ) {
204229 case NodeType4:
205230 static_cast <Node4*>(node)->insertNode4 (this , nodeRef,
206- key[depth], newNode );
231+ key[depth], newLeaf );
207232 break ;
208233 case NodeType16:
209234 static_cast <Node16*>(node)->insertNode16 (this , nodeRef,
210- key[depth], newNode );
235+ key[depth], newLeaf );
211236 break ;
212237 case NodeType48:
213238 static_cast <Node48*>(node)->insertNode48 (this , nodeRef,
214- key[depth], newNode );
239+ key[depth], newLeaf );
215240 break ;
216241 case NodeType256:
217242 static_cast <Node256*>(node)->insertNode256 (this , nodeRef,
218- key[depth], newNode );
243+ key[depth], newLeaf );
219244 break ;
220245 }
221- // If the identified node pointer no longer points to the same node as
222- // that of the fp pointer, the node must have upscaled. Update the tree
223- // pointer.
224- // if (*parentPointer != *nodeRef) {
225- // *parentPointer = *nodeRef;
226- // }
227- if (nodeType != (*nodeRef)->type ) {
228- *parentPointer = *nodeRef;
229- }
230246 }
231247
232248 // Lookup function, returns ArtNode
233249 ArtNode* lookup (ArtNode* node, uint8_t key[], unsigned keyLength,
234250 unsigned depth, unsigned maxKeyLength) {
235251 // Find the node with a matching key, optimistic version
236252
237- bool skippedPrefix = false ; // Did we optimistically skip some prefix
238- // without checking it?
253+ bool skippedPrefix = false ; // Did we optimistically skip some
254+ // prefix without checking it?
239255
240256 while (node != NULL ) {
241257 if (isLeaf (node)) {
0 commit comments