B+TREE: Add _size operator

This commit is contained in:
Patrick Pelissier committed 2018-04-04 22:54:39 +02:00
1 parent 7ca254ade9
commit 27b7380433
1 file changed
+16 -2
+16 -2
View File
@@ -72,6 +72,7 @@
assert (N >= 3); /* TBC: 2 instead ? */ \ assert (N >= 3); /* TBC: 2 instead ? */ \
BPTREEI_NODE_CONTRACT(N, key_oplist, (b)->root, (b)->root); \ BPTREEI_NODE_CONTRACT(N, key_oplist, (b)->root, (b)->root); \
assert ((b)->root->next == NULL); \ assert ((b)->root->next == NULL); \
if ((b)->root->num <= 0) assert (-(b)->root->num == (int) (b)->size); \
} while (0) } while (0)
/* Max depth of any B+tree */ /* Max depth of any B+tree */
@@ -95,6 +96,7 @@
/* A B+TREE is just a pointer to the root node */ \ /* A B+TREE is just a pointer to the root node */ \
typedef struct M_C(name, _s) { \ typedef struct M_C(name, _s) { \
node_t root; \ node_t root; \
size_t size; \
} tree_t[1]; \ } tree_t[1]; \
\ \
/* Parent Iterator */ \ /* Parent Iterator */ \
@@ -119,6 +121,7 @@
static inline void M_C(name, _init)(tree_t b) \ static inline void M_C(name, _init)(tree_t b) \
{ \ { \
b->root = M_C(name, _new_node)(); \ b->root = M_C(name, _new_node)(); \
b->size = 0; \
BPTREEI_CONTRACT(N, key_oplist, b); \ BPTREEI_CONTRACT(N, key_oplist, b); \
} \ } \
\ \
@@ -172,6 +175,7 @@
} \ } \
/* Clean root */ \ /* Clean root */ \
b->root->num = 0; \ b->root->num = 0; \
b->size = 0; \
BPTREEI_CONTRACT(N, key_oplist, b); \ BPTREEI_CONTRACT(N, key_oplist, b); \
} \ } \
\ \
@@ -187,7 +191,14 @@
{ \ { \
BPTREEI_CONTRACT(N, key_oplist, b); \ BPTREEI_CONTRACT(N, key_oplist, b); \
/* root shall be an empty leaf */ \ /* root shall be an empty leaf */ \
return b->root->num == 0; \ return b->size == 0; \
} \
\
static inline size_t M_C(name, _size)(const tree_t b) \
{ \
BPTREEI_CONTRACT(N, key_oplist, b); \
/* root shall be an empty leaf */ \
return b->size; \
} \ } \
\ \
static inline node_t M_C(name, _search_leaf)(pit_t pit, const tree_t b, key_t const key) \ static inline node_t M_C(name, _search_leaf)(pit_t pit, const tree_t b, key_t const key) \
@@ -240,7 +251,7 @@
int cmp = M_GET_CMP key_oplist (key, n->key[i]); \ int cmp = M_GET_CMP key_oplist (key, n->key[i]); \
if (M_UNLIKELY (cmp == 0)) { \ if (M_UNLIKELY (cmp == 0)) { \
M_IF(isMap)(M_GET_SET value_oplist (n->kind.value[i], value);,) \ M_IF(isMap)(M_GET_SET value_oplist (n->kind.value[i], value);,) \
return i; \ return -1; \
} else if (cmp < 0) { \ } else if (cmp < 0) { \
/* Move tables to make space for insertion */ \ /* Move tables to make space for insertion */ \
memmove(&n->key[i+1], &n->key[i], sizeof(key_t)*(num-i)); \ memmove(&n->key[i+1], &n->key[i], sizeof(key_t)*(num-i)); \
@@ -282,6 +293,7 @@
/* Insert key into the leaf.*/ \ /* Insert key into the leaf.*/ \
/* NOTE: Even if there is N elements, we can still add one more.*/ \ /* NOTE: Even if there is N elements, we can still add one more.*/ \
int i = M_C(name, _search_and_insert_leaf)(leaf, key M_IF (isMap)(M_DEFERRED_COMMA value,)); \ int i = M_C(name, _search_and_insert_leaf)(leaf, key M_IF (isMap)(M_DEFERRED_COMMA value,)); \
b->size += (i >= 0); \
/* Most likely case: leaf can accept key!*/ \ /* Most likely case: leaf can accept key!*/ \
int num = -leaf->num; \ int num = -leaf->num; \
assert (num > 0); \ assert (num > 0); \
@@ -289,6 +301,7 @@
BPTREEI_CONTRACT(N, key_oplist, b); \ BPTREEI_CONTRACT(N, key_oplist, b); \
return; \ return; \
} \ } \
assert (i >= 0); \
assert (num == N+1); \ assert (num == N+1); \
/* leaf is full: need to slip it in two */ \ /* leaf is full: need to slip it in two */ \
int nnum = (N + 1) / 2; \ int nnum = (N + 1) / 2; \
@@ -487,6 +500,7 @@
int k = M_C(name, _search_and_remove_leaf)(leaf, key); \ int k = M_C(name, _search_and_remove_leaf)(leaf, key); \
/* If not found, or number of keys greater than N>2 or root */ \ /* If not found, or number of keys greater than N>2 or root */ \
if (k < 0) return false; \ if (k < 0) return false; \
b->size --; \
if (M_LIKELY (M_C(name, _get_num)(leaf) >= N/2) || pit->num == 0) return true; \ if (M_LIKELY (M_C(name, _get_num)(leaf) >= N/2) || pit->num == 0) return true; \
/* Leaf is too small. Needs rebalancing */ \ /* Leaf is too small. Needs rebalancing */ \
assert (M_C(name, _get_num)(leaf) == N/2-1); \ assert (M_C(name, _get_num)(leaf) == N/2-1); \