summaryrefslogtreecommitdiff
path: root/src/config/conftree.c
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2023-08-05 11:51:25 +0000
committerLaurent Bercot <ska@appnovation.com>2023-08-05 11:51:25 +0000
commit17c382d1c9d7236c101418060758d2296cc5e17e (patch)
treefd00e58df0d9d3c70ddd1accfec9e819249c672a /src/config/conftree.c
downloadtipidee-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.c82
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) ;
+}