[6.0] src/rax.c
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
/* Rax -- A radix tree implementation.
|
||||
*
|
||||
* Copyright (c) 2017-2018, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||
* Version 1.2 -- 7 February 2019
|
||||
*
|
||||
* Copyright (c) 2017-2019, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -485,8 +487,8 @@ static inline size_t raxLowWalk(rax *rax, unsigned char *s, size_t len, raxNode
|
||||
if (h->iscompr) j = 0; /* Compressed node only child is at index 0. */
|
||||
memcpy(&h,children+j,sizeof(h));
|
||||
parentlink = children+j;
|
||||
j = 0; /* If the new node is compressed and we do not
|
||||
iterate again (since i == l) set the split
|
||||
j = 0; /* If the new node is non compressed and we do not
|
||||
iterate again (since i == len) set the split
|
||||
position to 0 to signal this node represents
|
||||
the searched key. */
|
||||
}
|
||||
@@ -626,7 +628,7 @@ int raxGenericInsert(rax *rax, unsigned char *s, size_t len, void *data, void **
|
||||
*
|
||||
* 3b. IF $SPLITPOS != 0:
|
||||
* Trim the compressed node (reallocating it as well) in order to
|
||||
* contain $splitpos characters. Change chilid pointer in order to link
|
||||
* contain $splitpos characters. Change child pointer in order to link
|
||||
* to the split node. If new compressed node len is just 1, set
|
||||
* iscompr to 0 (layout is the same). Fix parent's reference.
|
||||
*
|
||||
@@ -1080,7 +1082,7 @@ int raxRemove(rax *rax, unsigned char *s, size_t len, void **old) {
|
||||
}
|
||||
} else if (h->size == 1) {
|
||||
/* If the node had just one child, after the removal of the key
|
||||
* further compression with adjacent nodes is pontentially possible. */
|
||||
* further compression with adjacent nodes is potentially possible. */
|
||||
trycompress = 1;
|
||||
}
|
||||
|
||||
@@ -1327,7 +1329,7 @@ int raxIteratorNextStep(raxIterator *it, int noup) {
|
||||
if (!noup && children) {
|
||||
debugf("GO DEEPER\n");
|
||||
/* Seek the lexicographically smaller key in this subtree, which
|
||||
* is the first one found always going torwards the first child
|
||||
* is the first one found always going towards the first child
|
||||
* of every successive node. */
|
||||
if (!raxStackPush(&it->stack,it->node)) return 0;
|
||||
raxNode **cp = raxNodeFirstChildPtr(it->node);
|
||||
@@ -1346,7 +1348,7 @@ int raxIteratorNextStep(raxIterator *it, int noup) {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
/* If we finished exporing the previous sub-tree, switch to the
|
||||
/* If we finished exploring the previous sub-tree, switch to the
|
||||
* new one: go upper until a node is found where there are
|
||||
* children representing keys lexicographically greater than the
|
||||
* current key. */
|
||||
@@ -1406,7 +1408,7 @@ int raxIteratorNextStep(raxIterator *it, int noup) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Seek the grestest key in the subtree at the current node. Return 0 on
|
||||
/* Seek the greatest key in the subtree at the current node. Return 0 on
|
||||
* out of memory, otherwise 1. This is an helper function for different
|
||||
* iteration functions below. */
|
||||
int raxSeekGreatest(raxIterator *it) {
|
||||
@@ -1508,7 +1510,7 @@ int raxIteratorPrevStep(raxIterator *it, int noup) {
|
||||
int raxSeek(raxIterator *it, const char *op, unsigned char *ele, size_t len) {
|
||||
int eq = 0, lt = 0, gt = 0, first = 0, last = 0;
|
||||
|
||||
it->stack.items = 0; /* Just resetting. Intialized by raxStart(). */
|
||||
it->stack.items = 0; /* Just resetting. Initialized by raxStart(). */
|
||||
it->flags |= RAX_ITER_JUST_SEEKED;
|
||||
it->flags &= ~RAX_ITER_EOF;
|
||||
it->key_len = 0;
|
||||
@@ -1673,6 +1675,7 @@ int raxSeek(raxIterator *it, const char *op, unsigned char *ele, size_t len) {
|
||||
* node, but will be our match, representing the key "f".
|
||||
*
|
||||
* So in that case, we don't seek backward. */
|
||||
it->data = raxGetData(it->node);
|
||||
} else {
|
||||
if (gt && !raxIteratorNextStep(it,0)) return 0;
|
||||
if (lt && !raxIteratorPrevStep(it,0)) return 0;
|
||||
@@ -1728,7 +1731,7 @@ int raxPrev(raxIterator *it) {
|
||||
* tree, expect a disappointing distribution. A random walk produces good
|
||||
* random elements if the tree is not sparse, however in the case of a radix
|
||||
* tree certain keys will be reported much more often than others. At least
|
||||
* this function should be able to expore every possible element eventually. */
|
||||
* this function should be able to explore every possible element eventually. */
|
||||
int raxRandomWalk(raxIterator *it, size_t steps) {
|
||||
if (it->rt->numele == 0) {
|
||||
it->flags |= RAX_ITER_EOF;
|
||||
@@ -1736,7 +1739,7 @@ int raxRandomWalk(raxIterator *it, size_t steps) {
|
||||
}
|
||||
|
||||
if (steps == 0) {
|
||||
size_t fle = floor(log(it->rt->numele));
|
||||
size_t fle = 1+floor(log(it->rt->numele));
|
||||
fle *= 2;
|
||||
steps = 1 + rand() % fle;
|
||||
}
|
||||
@@ -1765,6 +1768,7 @@ int raxRandomWalk(raxIterator *it, size_t steps) {
|
||||
if (n->iskey) steps--;
|
||||
}
|
||||
it->node = n;
|
||||
it->data = raxGetData(it->node);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1791,7 +1795,8 @@ int raxCompare(raxIterator *iter, const char *op, unsigned char *key, size_t key
|
||||
if (eq && key_len == iter->key_len) return 1;
|
||||
else if (lt) return iter->key_len < key_len;
|
||||
else if (gt) return iter->key_len > key_len;
|
||||
} if (cmp > 0) {
|
||||
else return 0; /* Avoid warning, just 'eq' is handled before. */
|
||||
} else if (cmp > 0) {
|
||||
return gt ? 1 : 0;
|
||||
} else /* (cmp < 0) */ {
|
||||
return lt ? 1 : 0;
|
||||
@@ -1820,7 +1825,7 @@ uint64_t raxSize(rax *rax) {
|
||||
/* ----------------------------- Introspection ------------------------------ */
|
||||
|
||||
/* This function is mostly used for debugging and learning purposes.
|
||||
* It shows an ASCII representation of a tree on standard output, outling
|
||||
* It shows an ASCII representation of a tree on standard output, outline
|
||||
* all the nodes and the contained keys.
|
||||
*
|
||||
* The representation is as follow:
|
||||
@@ -1830,7 +1835,7 @@ uint64_t raxSize(rax *rax) {
|
||||
* [abc]=0x12345678 (node is a key, pointing to value 0x12345678)
|
||||
* [] (a normal empty node)
|
||||
*
|
||||
* Children are represented in new idented lines, each children prefixed by
|
||||
* Children are represented in new indented lines, each children prefixed by
|
||||
* the "`-(x)" string, where "x" is the edge byte.
|
||||
*
|
||||
* [abc]
|
||||
|
||||
Reference in New Issue
Block a user