private char Insert(char p, char[] key, int start, char val) {
int len = Strlen(key, start);
if (p == 0) {
// this means there is no branch, this node will start a new branch.
// Instead of doing that, we store the key somewhere else and create
// only one node with a pointer to the key
p = freenode++;
eq[p] = val; // holds data
length++;
hi[p] = (char)0;
if (len > 0) {
sc[p] = (char)0xFFFF; // indicates branch is compressed
lo[p] = (char)kv.Alloc(len
+ 1); // use 'lo' to hold pointer to key
Strcpy(kv.Arr, lo[p], key, start);
} else {
sc[p] = (char)0;
lo[p] = (char)0;
}
return p;
}
if (sc[p] == 0xFFFF) {
// branch is compressed: need to decompress
// this will generate garbage in the external key array
// but we can do some garbage collection later
char pp = freenode++;
lo[pp] = lo[p]; // previous pointer to key
eq[pp] = eq[p]; // previous pointer to data
lo[p] = (char)0;
if (len > 0) {
sc[p] = kv[lo[pp]];
eq[p] = pp;
lo[pp]++;
if (kv[lo[pp]] == 0) {
// key completly decompressed leaving garbage in key array
lo[pp] = (char)0;
sc[pp] = (char)0;
hi[pp] = (char)0;
} else
sc[pp] =
(char)0xFFFF; // we only got first char of key, rest is still there
} else {
// In this case we can save a node by swapping the new node
// with the compressed node
sc[pp] = (char)0xFFFF;
hi[p] = pp;
sc[p] = (char)0;
eq[p] = val;
length++;
return p;
}
}
char s = key[start];
if (s < sc[p])
lo[p] = Insert(lo[p], key, start, val);
else if (s == sc[p]) {
if (s != 0)
eq[p] = Insert(eq[p], key, start + 1, val);
else {
// key already in tree, overwrite data
eq[p] = val;
}
} else
hi[p] = Insert(hi[p], key, start, val);
return p;
}