Skip to content

Commit f657eea

Browse files
committed
Implemented new version of lil. Not yet functional.
1 parent df1eaa5 commit f657eea

3 files changed

Lines changed: 75 additions & 52 deletions

File tree

ART.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@ class ART {
3737
public:
3838
ArtNode* root; // pointer to root node
3939
ArtNode* fp; // fast path
40+
ArtNode** fp_ref; // pointer to fp
41+
unsigned fp_depth; // depth of fp
4042
std::array<ArtNode*, maxPrefixLength> fp_path; // fp path
43+
std::array<ArtNode**, maxPrefixLength>
44+
fp_path_ref; // references to nodes on fp_path
4145
size_t fp_path_length; // stores real length of fp path
4246
ArtNode* fp_leaf;
4347

ArtNode_lil.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ void Node4::insertNode4(ART* tree, ArtNode** nodeRef, uint8_t keyByte,
4848
// update fast path
4949
tree->fp = newNode;
5050
tree->fp_path[tree->fp_path_length - 1] = newNode;
51+
tree->fp_path_ref[tree->fp_path_length - 1] = nodeRef;
5152

5253
newNode->count = 4;
5354
copyPrefix(this, newNode);
@@ -85,6 +86,7 @@ void Node16::insertNode16(ART* tree, ArtNode** nodeRef, uint8_t keyByte,
8586
// update fast path
8687
tree->fp = newNode;
8788
tree->fp_path[tree->fp_path_length - 1] = newNode;
89+
tree->fp_path_ref[tree->fp_path_length - 1] = nodeRef;
8890

8991
memcpy(newNode->child, this->child, this->count * sizeof(uintptr_t));
9092
for (unsigned i = 0; i < this->count; i++)
@@ -120,6 +122,7 @@ void Node48::insertNode48(ART* tree, ArtNode** nodeRef, uint8_t keyByte,
120122
// update fast path
121123
tree->fp = newNode;
122124
tree->fp_path[tree->fp_path_length - 1] = newNode;
125+
tree->fp_path_ref[tree->fp_path_length - 1] = nodeRef;
123126

124127
delete this;
125128
return newNode->insertNode256(tree, nodeRef, keyByte, child);

QuART_lil.h

Lines changed: 68 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)