/* This software is licensed by the MIT License, see LICENSE file */ /* Copyright © 2022 Gregory Lirent */ #include "include.h" bool libcdsb_map_update(map_t* x, const void* k, vtype kt, const void* v, vtype vt, void* dt, map_access_callback callback) { int cmp; mnode_t* n; mnode_t* p; if (!mnode_is_empty(n = x->root)) { do { p = n; cmp = vtype_compare(k, kt, vnode_peek(&n->key, kt), kt); if (cmp == 0) { if (callback) callback(vnode_peek(&n->key, x->type), x->type, vnode_peek(&n->value, n->type), n->type, dt); vnode_free(&n->value, n->type); n->value = vnode_create(v, n->type = vt); return true; } n = (cmp < 0) ? n->left : n->right; } while (!mnode_is_empty(n)); n = mnode_create(nullptr, p, 1); if (cmp < 0) p->left = n; else p->right = n; if (!mnode_is_root(p)) mnode_fixup(&x->root, n); } else n = x->root = mnode_create(nullptr, mnode_empty, 0); n->key = vnode_tcreate(x->type, k, kt); n->value = vnode_create(v, vt); n->type = vt; return false; } bool libcdsb_map_inject(map_t* x, const void* k, vtype kt, const void* v, vtype vt, void* dt, map_access_callback callback) { int cmp; mnode_t* n; mnode_t* p; vnode_t kn; vnode_tattach(&kn, x->type, k, kt); n = x->root; kt = x->type; k = vnode_peek(&kn, kt); if (!mnode_is_empty(n)) { do { p = n; cmp = vtype_compare(k, kt, vnode_peek(&n->key, kt), kt); if (cmp == 0) { if (callback) callback(vnode_peek(&n->key, x->type), x->type, vnode_peek(&n->value, n->type), n->type, dt); vnode_free(&n->key, x->type); vnode_free(&n->value, n->type); n->key = kn; vnode_attach(&n->value, v, n->type = vt); return true; } n = (cmp < 0) ? n->left : n->right; } while (!mnode_is_empty(n)); n = mnode_create(kn, p, 1); if (cmp < 0) p->left = n; else p->right = n; if (!mnode_is_root(p)) mnode_fixup(&x->root, n); } else n = x->root = mnode_create(kn, mnode_empty, 0); vnode_attach(&n->value, v, n->type = vt); return false; }