From c039f07f2dc5d6d0df902fde70b4ec2224043869 Mon Sep 17 00:00:00 2001 From: Patrick Pelissier Date: Sat, 15 Aug 2020 15:27:28 +0200 Subject: [PATCH] Add macros BPTREE_DEF2_AS BPTREE_DEF_AS BPTREE_MULTI_DEF2_AS BPTREE_MULTI_DEF_AS --- m-bptree.h | 59 ++++++++++++++++++++++++++++-- tests/test-mbptree.c | 85 ++++++++++++++++++++++++++++++-------------- 2 files changed, 115 insertions(+), 29 deletions(-) diff --git a/m-bptree.h b/m-bptree.h index f3b95fe5..8e846b94 100644 --- a/m-bptree.h +++ b/m-bptree.h @@ -42,6 +42,21 @@ M_END_PROTECTED_CODE +/* Define a B+tree of size 'N' that maps a 'key' to a 'value' + as the given name name_t with its associated functions. + USAGE: + BPTREE_DEF2_AS(name, name_t, it_t, itref_t, N, key_t, key_oplist, value_t, value_oplist) + OR + BPTREE_DEF2_AS(name, name_t, it_t, itref_t, N, key_t, value_t) +*/ +#define BPTREE_DEF2_AS(name, name_t, it_t, itref_t, N, key_type, ...) \ + M_BEGIN_PROTECTED_CODE \ + BPTREEI_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ + ((name, N, key_type, M_GLOBAL_OPLIST_OR_DEF(key_type)(), __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), 1, 0, name_t, M_C(name, _node_ct), M_C(name, _pit_ct), it_t, itref_t ), \ + (name, N, key_type, __VA_ARGS__, 1, 0, name_t, M_C(name, _node_ct), M_C(name, _pit_ct), it_t, itref_t ))) \ + M_END_PROTECTED_CODE + + /* Define a B+tree of a given type, of size N. with its associated functions USAGE: BPTREE_DEF(name, N, type, [, oplist_of_the_type]) */ @@ -53,6 +68,17 @@ M_END_PROTECTED_CODE +/* Define a B+tree of a given type, of size N. + as the given name name_t with its associated functions + USAGE: BPTREE_DEF_AS(name, name_t, it_t, N, type, [, oplist_of_the_type]) */ +#define BPTREE_DEF_AS(name, name_t, it_t, N, ...) \ + M_BEGIN_PROTECTED_CODE \ + BPTREEI_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ + ((name, N, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), 0, 0, name_t, M_C(name, _node_ct), M_C(name, _pit_ct), it_t, M_C(name, _type_ct) ), \ + (name, N, __VA_ARGS__, __VA_ARGS__, 0, 0, name_t, M_C(name, _node_ct), M_C(name, _pit_ct), it_t, M_C(name, _type_ct) ))) \ + M_END_PROTECTED_CODE + + /* Define a B+tree of size 'N' that maps a 'key' to a 'value', allowing multiple equal keys to exist, with its associated functions. @@ -69,6 +95,22 @@ M_END_PROTECTED_CODE +/* Define a B+tree of size 'N' that maps a 'key' to a 'value', + allowing multiple equal keys to exist, + as the given name name_t with its associated functions. + USAGE: + BPTREE_MULTI_DEF2_AS(name, name_t, it_t, itref_t, N, key_t, key_oplist, value_t, value_oplist) + OR + BPTREE_MULTI_DEF2_AS(name, name_t, it_t, itref_t, N, key_t, value_t) +*/ +#define BPTREE_MULTI_DEF2_AS(name, name_t, it_t, itref_t, N, key_type, ...) \ + M_BEGIN_PROTECTED_CODE \ + BPTREEI_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ + ((name, N, key_type, M_GLOBAL_OPLIST_OR_DEF(key_type)(), __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), 1, 1, name_t, M_C(name, _node_ct), M_C(name, _pit_ct), it_t, itref_t ), \ + (name, N, key_type, __VA_ARGS__, 1, 1, name_t, M_C(name, _node_ct), M_C(name, _pit_ct), it_t, itref_t ))) \ + M_END_PROTECTED_CODE + + /* Define a B+tree of a given type, of size N. allowing multiple equal keys to exist, with its associated functions @@ -81,8 +123,19 @@ M_BEGIN_PROTECTED_CODE +/* Define a B+tree of a given type, of size N. + allowing multiple equal keys to exist, + as the given name name_t with its associated functions + USAGE: BPTREE_MULTI_DEF_AS(name, name_t, it_t, N, type, [, oplist_of_the_type]) */ +#define BPTREE_MULTI_DEF_AS(name, name_t, it_t, N, ...) \ + M_BEGIN_PROTECTED_CODE \ + BPTREEI_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ + ((name, N, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), 0, 1, name_t, M_C(name, _node_ct), M_C(name, _pit_ct), it_t, M_C(name, _type_ct) ), \ + (name, N, __VA_ARGS__, __VA_ARGS__, 0, 1, name_t, M_C(name, _node_ct), M_C(name, _pit_ct), it_t, M_C(name, _type_ct) ))) \ + M_BEGIN_PROTECTED_CODE -/* Define the oplist of a rbtree of type (from BPTREE_DEF). + +/* Define the oplist of a B+TREE used as a set of type (from BPTREE_DEF). USAGE: BPTREE_OPLIST(name [, oplist_of_the_type]) */ #define BPTREE_OPLIST(...) \ BPTREEI_KEY_OPLIST_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ @@ -90,7 +143,7 @@ (__VA_ARGS__ ))) -/* Define the oplist of a rbtree of type (from BPTREE_DEF2). +/* Define the oplist of a B+TREE used as a map of a key type to a value type (from BPTREE_DEF2). USAGE: BPTREE_OPLIST2(name[, key_oplist, value_oplist]) NOTE: IT_REF is not exported so that the contained appears as not modifiable by algorithm. @@ -120,6 +173,7 @@ #define BPTREEI_KEY_OPLIST_P3(name, oplist) \ (INIT(M_C(name, _init)), \ INIT_SET(M_C(name, _init_set)), \ + INIT_WITH(API_1(M_INIT_VAI)), \ SET(M_C(name, _set)), \ CLEAR(M_C(name, _clear)), \ INIT_MOVE(M_C(name, _init_move)), \ @@ -169,6 +223,7 @@ #define BPTREEI_OPLIST2_P4(name, key_oplist, value_oplist) \ (INIT(M_C(name, _init)), \ INIT_SET(M_C(name, _init_set)), \ + INIT_WITH(API_1(M_INIT_KEY_VAI)), \ SET(M_C(name, _set)), \ CLEAR(M_C(name, _clear)), \ INIT_MOVE(M_C(name, _init_move)), \ diff --git a/tests/test-mbptree.c b/tests/test-mbptree.c index 0ffc31de..7c37ad81 100644 --- a/tests/test-mbptree.c +++ b/tests/test-mbptree.c @@ -40,7 +40,16 @@ BPTREE_DEF(btree_myset, 15, testobj_t, TESTOBJ_CMP_OPLIST) BPTREE_MULTI_DEF2(multimap, 3, int, M_DEFAULT_OPLIST, int, M_DEFAULT_OPLIST) BPTREE_MULTI_DEF(multiset, 6, int, M_DEFAULT_OPLIST) - + +BPTREE_DEF2_AS(MapDouble, MapDouble, MapDoubleIt, MapDoubleItRef, 4, double, double) +#define M_OPL_MapDouble() BPTREE_OPLIST2(MapDouble, M_DEFAULT_OPLIST, M_DEFAULT_OPLIST) +BPTREE_DEF_AS(SetDouble, SetDouble, SetDoubleIt, 7, double) +#define M_OPL_SetDouble() BPTREE_OPLIST(SetDouble, M_DEFAULT_OPLIST) +BPTREE_MULTI_DEF2_AS(MultiMapDouble, MultiMapDouble, MultiMapDoubleIt, MultiMapDoubleItRef, 8, double, double) +#define M_OPL_MultiMapDouble() BPTREE_OPLIST2(MultiMapDouble, M_DEFAULT_OPLIST, M_DEFAULT_OPLIST) +BPTREE_MULTI_DEF_AS(MultiSetDouble, MultiSetDouble, MultiSetDoubleIt, 9, double) +#define M_OPL_MultiSetDouble() BPTREE_OPLIST(MultiSetDouble, M_DEFAULT_OPLIST) + static void test1(void) { btree_t b; @@ -499,32 +508,6 @@ static void test_io_set(void) } } -#if 0 -// Dump code for debug -static void multimap_dump_node(multimap_node_t n) -{ - while (n) { - int num = n->num < 0 ? -n->num : n->num; - printf ("["); - for(int i = 0; i < num; i++) - printf ("%d, ", n->key[i]); - printf ("] "); - n = n->next; - } - printf("\n"); -} -static void -multimap_dump(multimap_t b) -{ - multimap_node_t n = b->root; - while (n->num > 0) { - multimap_dump_node(n); - n = n->kind.node[0]; - } - multimap_dump_node(n); -} -#endif - static void test_multimap(void) { @@ -596,6 +579,53 @@ test_multiset(void) multiset_clear(b); } +static void test_double(void) +{ + M_LET( (tree, (1.0, 2.0), (3.0, 4.0)), MapDouble) { + double *r = MapDouble_get(tree, 1.0); + assert( r != NULL); + assert( *r == 2.0); + r = MapDouble_get(tree, 3.0); + assert( r != NULL); + assert( *r == 4.0); + r = MapDouble_get(tree, 4.0); + assert( r == NULL); + } + + M_LET( (tree, 1.0, 3.0), SetDouble) { + double *r = SetDouble_get(tree, 1.0); + assert( r != NULL); + assert( *r == 1.0); + r = SetDouble_get(tree, 3.0); + assert( r != NULL); + assert( *r == 3.0); + r = SetDouble_get(tree, 4.0); + assert( r == NULL); + } + + M_LET( (tree, (1.0, 2.0), (3.0, 4.0)), MultiMapDouble) { + double *r = MultiMapDouble_get(tree, 1.0); + assert( r != NULL); + assert( *r == 2.0); + r = MultiMapDouble_get(tree, 3.0); + assert( r != NULL); + assert( *r == 4.0); + r = MultiMapDouble_get(tree, 4.0); + assert( r == NULL); + } + + M_LET( (tree, 1.0, 3.0), MultiSetDouble) { + double *r = MultiSetDouble_get(tree, 1.0); + assert( r != NULL); + assert( *r == 1.0); + r = MultiSetDouble_get(tree, 3.0); + assert( r != NULL); + assert( *r == 3.0); + r = MultiSetDouble_get(tree, 4.0); + assert( r == NULL); + } +} + int main(void) { test1(); @@ -608,5 +638,6 @@ int main(void) test_io_set(); test_multimap(); test_multiset(); + test_double(); exit(0); }