diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2023-08-05 11:51:25 +0000 |
---|---|---|
committer | Laurent Bercot <ska@appnovation.com> | 2023-08-05 11:51:25 +0000 |
commit | 17c382d1c9d7236c101418060758d2296cc5e17e (patch) | |
tree | fd00e58df0d9d3c70ddd1accfec9e819249c672a /src/config/conftree.c | |
download | tipidee-17c382d1c9d7236c101418060758d2296cc5e17e.tar.xz |
Initial commit
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src/config/conftree.c')
-rw-r--r-- | src/config/conftree.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/config/conftree.c b/src/config/conftree.c new file mode 100644 index 0000000..fc0b5bc --- /dev/null +++ b/src/config/conftree.c @@ -0,0 +1,82 @@ +/* ISC license. */ + +#include <stdint.h> +#include <string.h> +#include <errno.h> + +#include <skalibs/gensetdyn.h> +#include <skalibs/avltree.h> +#include <skalibs/cdbmake.h> +#include <skalibs/strerr.h> + +#include "tipidee-config-internal.h" + +#define dienomem() strerr_diefu1sys(111, "stralloc_catb") + +static void *confnode_dtok (uint32_t d, void *data) +{ + return g.storage.s + GENSETDYN_P(confnode, (gensetdyn *)data, d)->key ; +} + +static int confnode_cmp (void const *a, void const *b, void *data) +{ + (void)data ; + return strcmp((char const *)a, (char const *)b) ; +} + +struct nodestore_s +{ + gensetdyn set ; + avltree tree ; +} ; + +static struct nodestore_s nodestore = \ +{ \ + .set = GENSETDYN_INIT(confnode, 8, 3, 8), \ + .tree = AVLTREE_INIT(8, 3, 8, &confnode_dtok, &confnode_cmp, &nodestore.set) \ +} ; + + +confnode const *conftree_search (char const *key) +{ + uint32_t i ; + return avltree_search(&nodestore.tree, key, &i) ? GENSETDYN_P(confnode const, &nodestore.set, i) : 0 ; +} + +void conftree_add (confnode const *node) +{ + uint32_t i ; + if (!gensetdyn_new(&nodestore.set, &i)) dienomem() ; + *GENSETDYN_P(confnode, &nodestore.set, i) = *node ; + if (!avltree_insert(&nodestore.tree, i)) dienomem() ; +} + +void conftree_update (confnode const *node) +{ + uint32_t i ; + if (avltree_search(&nodestore.tree, g.storage.s + node->key, &i)) + { + if (!avltree_delete(&nodestore.tree, g.storage.s + node->key)) dienomem() ; + *GENSETDYN_P(confnode, &nodestore.set, i) = *node ; + if (!avltree_insert(&nodestore.tree, i)) dienomem() ; + } + else return conftree_add(node) ; +} + +static int confnode_write (uint32_t d, unsigned int h, void *data) +{ + confnode *node = GENSETDYN_P(confnode, &nodestore.set, d) ; + cdbmaker *cm = data ; + (void)h ; + if ((g.storage.s[node->key] & ~0x20) == 'A') + { + g.storage.s[++node->data] |= '@' ; + node->datalen-- ; + } + return cdbmake_add(cm, g.storage.s + node->key, node->keylen, g.storage.s + node->data, node->datalen) ; +} + +int conftree_write (cdbmaker *cm) +{ + return avltree_iter(&nodestore.tree, &confnode_write, cm) ; +} |