* Update comments.
* Fix position of const for some prototypes.
This commit is contained in:
1 parent
cc45b9c1fe
commit
65e3f1049b
1 file changed
+44
-12
+44
-12
@@ -321,7 +321,8 @@
|
||||
M_CHECK_COMPATIBLE_OPLIST(name, 1, key_t, key_oplist) \
|
||||
M_CHECK_COMPATIBLE_OPLIST(name, 2, value_t, value_oplist) \
|
||||
\
|
||||
/* TODO: Can be optimized to alloc for leaf or for node */ \
|
||||
/* Allocate a new node */ \
|
||||
/* TODO: Can be specialized to alloc for leaf or for non leaf */ \
|
||||
static inline node_t M_C(name, _new_node)(void) \
|
||||
{ \
|
||||
node_t n = M_CALL_NEW(key_oplist, struct M_C(name, _node_s)); \
|
||||
@@ -341,13 +342,15 @@
|
||||
BPTREEI_CONTRACT(N, isMulti, key_oplist, b); \
|
||||
} \
|
||||
\
|
||||
static inline bool M_C(name, _is_leaf)(node_t n) \
|
||||
static inline bool M_C(name, _is_leaf)(const node_t n) \
|
||||
{ \
|
||||
/* We consider the empty node as a leaf */ \
|
||||
/* Only the root node can be empty */ \
|
||||
return n->num <= 0; \
|
||||
} \
|
||||
\
|
||||
static inline int M_C(name, _get_num)(node_t n) \
|
||||
/* Return the number of keys of the node */ \
|
||||
static inline int M_C(name, _get_num)(const node_t n) \
|
||||
{ \
|
||||
int num = n->num; \
|
||||
num = num < 0 ? -num : num; \
|
||||
@@ -360,8 +363,9 @@
|
||||
BPTREEI_CONTRACT(N, isMulti, key_oplist, b); \
|
||||
node_t next, n = b->root; \
|
||||
pit_t pit; \
|
||||
/* np is the heigh of the tree */ \
|
||||
int np = 0; \
|
||||
/* Scan down the nodes */ \
|
||||
/* Scan down the nodes to the left down node */ \
|
||||
while (!M_C(name, _is_leaf)(n)) { \
|
||||
pit->parent[np++] = n; \
|
||||
assert (np <= BPTREEI_MAX_STACK); \
|
||||
@@ -385,6 +389,7 @@
|
||||
/* Next node of the same height */ \
|
||||
next = n->next; \
|
||||
if (i != 0) { \
|
||||
/* Free the node if non root */ \
|
||||
M_CALL_DEL(key_oplist, n); \
|
||||
} \
|
||||
n = next; \
|
||||
@@ -405,31 +410,41 @@
|
||||
b->root = NULL; \
|
||||
} \
|
||||
\
|
||||
/* Copy recursively the node 'o' of root node 'root' */ \
|
||||
static inline node_t M_C(name, _copy_node)(const node_t o, const node_t root) \
|
||||
{ \
|
||||
node_t n = M_C(name, _new_node)(); \
|
||||
/* Set default number of keys and type to copy */ \
|
||||
n->num = o->num; \
|
||||
/* By default it is not linked to its brother. \
|
||||
Only the parent of this node can do it. It is fixed by it */ \
|
||||
n->next = NULL; \
|
||||
/* Get number of keys in the node and copy them */ \
|
||||
int num = M_C(name, _get_num)(o); \
|
||||
for(int i = 0; i < num; i++) { \
|
||||
M_CALL_INIT_SET(key_oplist, n->key[i], o->key[i]); \
|
||||
} \
|
||||
if (M_C(name, _is_leaf)(o)) { \
|
||||
/* Copy the associated values if it is a leaf and a MAP */ \
|
||||
M_IF(isMap)( \
|
||||
for(int i = 0; i < num; i++) { \
|
||||
M_CALL_INIT_SET(value_oplist, n->kind.value[i], o->kind.value[i]); \
|
||||
} \
|
||||
, /* End of isMap */) \
|
||||
} else { \
|
||||
/* Not a leaf */ \
|
||||
/* Copy recursively the associated nodes if it is not a leaf */ \
|
||||
for(int i = 0; i <= num; i++) { \
|
||||
assert(o->kind.node[i] != root); \
|
||||
n->kind.node[i] = M_C(name, _copy_node)(o->kind.node[i], root); \
|
||||
} \
|
||||
/* The copied nodes don't have their next field correct */ \
|
||||
/* Fix the next field for the copied nodes */ \
|
||||
for(int i = 0; i < num; i++) { \
|
||||
node_t current = n->kind.node[i]; \
|
||||
node_t next = n->kind.node[i+1]; \
|
||||
current->next = next; \
|
||||
/* Go down the tree up to the leaf \
|
||||
and fix the final 'next' link with the copied node */ \
|
||||
while (!M_C(name, _is_leaf)(current)) { \
|
||||
assert(!M_C(name, _is_leaf)(next)); \
|
||||
current = current->kind.node[current->num]; \
|
||||
@@ -446,6 +461,7 @@
|
||||
{ \
|
||||
BPTREEI_CONTRACT(N, isMulti, key_oplist, o); \
|
||||
assert (b != NULL); \
|
||||
/* Just copy recursively the root node */ \
|
||||
b->root = M_C(name, _copy_node)(o->root, o->root); \
|
||||
b->size = o->size; \
|
||||
BPTREEI_CONTRACT(N, isMulti, key_oplist, b); \
|
||||
@@ -453,6 +469,8 @@
|
||||
\
|
||||
static inline void M_C(name, _set)(tree_t b, const tree_t o) \
|
||||
{ \
|
||||
/* NOTE: We could reuse the already allocated nodes of 'b'. \
|
||||
Not sure if it worth the effort */ \
|
||||
M_C(name, _clear)(b); \
|
||||
M_C(name, _init_set)(b, o); \
|
||||
} \
|
||||
@@ -475,19 +493,22 @@
|
||||
node_t n = b->root; \
|
||||
int np = 0; \
|
||||
BPTREEI_NODE_CONTRACT(N, isMulti, key_oplist, n, b->root); \
|
||||
/* Go down the tree while searching for key */ \
|
||||
while (!M_C(name, _is_leaf)(n)) { \
|
||||
assert (np <= BPTREEI_MAX_STACK); \
|
||||
int i, hi = n->num; \
|
||||
assert (hi > 0); \
|
||||
/* Linear search is usually faster than binary search for \
|
||||
B+TREE (due to cache effect). If a binary tree is faster for \
|
||||
the choosen type and size , it simply means that the \
|
||||
size of B+TREE is too big (TBC) and shall be reduced. */ \
|
||||
the choosen type and size , it probably means that the \
|
||||
size of B+TREE is too big and should be reduced. */ \
|
||||
for(i = 0; i < hi; i++) { \
|
||||
if (M_CALL_CMP(key_oplist, key, n->key[i]) <= 0) \
|
||||
break; \
|
||||
} \
|
||||
/* Update the Parent iterator */ \
|
||||
pit->parent[np++] = n; \
|
||||
/* Select the new node to go down to */ \
|
||||
n = n->kind.node[i]; \
|
||||
assert (n != NULL); \
|
||||
BPTREEI_NODE_CONTRACT(N, isMulti, key_oplist, n, b->root); \
|
||||
@@ -500,18 +521,23 @@
|
||||
{ \
|
||||
BPTREEI_CONTRACT(N, isMulti, key_oplist, b); \
|
||||
pit_t pit; \
|
||||
/* Get the leaf node where the key can be */ \
|
||||
node_t n = M_C(name, _search_for_leaf)(pit, b, key); \
|
||||
int cmp = 0; \
|
||||
BPTREEI_NODE_CONTRACT(N, isMulti, key_oplist, n, b->root); \
|
||||
/* Search in the leaf for key */ \
|
||||
for(int i = 0; cmp >= 0 && i < -n->num; i++) { \
|
||||
cmp = M_CALL_CMP(key_oplist, key, n->key[i]); \
|
||||
if (cmp == 0) \
|
||||
if (cmp == 0) { \
|
||||
/* Return the value if MAP mode or the key if SET mode */ \
|
||||
return M_IF(isMap)(&n->kind.value[i],&n->key[i]); \
|
||||
} \
|
||||
} \
|
||||
/* Key not found */ \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
static inline const value_t *M_C(name, _cget)(const tree_t b, key_t const key) \
|
||||
static inline value_t const *M_C(name, _cget)(const tree_t b, key_t const key) \
|
||||
{ \
|
||||
return M_CONST_CAST(value_t, M_C(name, _get)(b, key)); \
|
||||
} \
|
||||
@@ -523,6 +549,7 @@
|
||||
assert (M_C(name, _is_leaf)(n)); \
|
||||
int i, num = M_C(name, _get_num)(n); \
|
||||
assert (num <= N); \
|
||||
/* Search for the key in the node n (a leaf) for insertion */ \
|
||||
for(i = 0; i < num; i++) { \
|
||||
int cmp = M_CALL_CMP(key_oplist, key, n->key[i]); \
|
||||
if (cmp <= 0) { \
|
||||
@@ -539,8 +566,10 @@
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
/* Insert key & value if MAP mode */ \
|
||||
M_CALL_INIT_SET(key_oplist, n->key[i], key); \
|
||||
M_IF(isMap)(M_CALL_INIT_SET(value_oplist, n->kind.value[i], value);,) \
|
||||
/* Increase the number of key in the node */ \
|
||||
n->num += -1; /* Increase num as num<0 for leaf */ \
|
||||
return i; \
|
||||
} \
|
||||
@@ -551,6 +580,7 @@
|
||||
assert (!M_C(name, _is_leaf)(n)); \
|
||||
int i, num = M_C(name, _get_num)(n); \
|
||||
assert (num <= N); \
|
||||
/* Search for the key in the node n (not a leaf) for insertion */ \
|
||||
for(i = 0; i < num; i++) { \
|
||||
if (n->kind.node[i] == l) { \
|
||||
/* Move tables to make space for insertion */ \
|
||||
@@ -559,8 +589,10 @@
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
/* Insert key in node */ \
|
||||
/* TBC: DO_INIT_MOVE instead ? If key was in a node !*/ \
|
||||
M_CALL_INIT_SET(key_oplist, n->key[i], key); \
|
||||
/* Increase the number of key in the node */ \
|
||||
n->num += 1; \
|
||||
return i; \
|
||||
} \
|
||||
@@ -935,7 +967,7 @@
|
||||
); \
|
||||
} \
|
||||
\
|
||||
static inline const M_C(name, _type_t) * \
|
||||
static inline M_C(name, _type_t) const * \
|
||||
M_C(name, _cref)(it_t it) \
|
||||
{ \
|
||||
return M_CONST_CAST(M_C(name, _type_t), M_C(name, _ref)(it)); \
|
||||
@@ -1014,13 +1046,13 @@
|
||||
return &n->M_IF(isMap)(kind.value, key)[-n->num-1]; \
|
||||
} \
|
||||
\
|
||||
static inline const value_t * \
|
||||
static inline value_t const * \
|
||||
M_C(name, _cmin)(const tree_t tree) \
|
||||
{ \
|
||||
return M_CONST_CAST(value_t, M_C(name, _min)(tree)); \
|
||||
} \
|
||||
\
|
||||
static inline const value_t * \
|
||||
static inline value_t const * \
|
||||
M_C(name, _cmax)(const tree_t tree) \
|
||||
{ \
|
||||
return M_CONST_CAST(value_t, M_C(name, _max)(tree)); \
|
||||
|
||||
Reference in new issue
Block a user