/* This software is licensed by the MIT License, see LICENSE file */ /* Copyright © 2022 Gregory Lirent */ #include "include.h" int libcdsb_dict_find(dict_t* x, const void* k, vtype t, void* dt, dict_access_callback callback, bool cut) { dnode_t *c, **p; int r; void* key; if (x->capacity) { c = *(p = x->nodes + (vtype_hash(k, t) % x->capacity)); while (!is_null(c)) { key = vnode_peek(&c->key, c->key_type); if (vtype_compare(k, t, key, c->key_type) == 0) { r = (callback) ? callback(key, c->key_type, vnode_peek(&c->value, c->value_type), c->value_type, dt) : 0; if (cut) { *p = c->prev; vnode_free(&c->key, c->key_type); vnode_free(&c->value, c->value_type); free(c); --x->size; } return r; } else c = *(p = &c->prev); } } return -1; } int libcdsb_dict_foreach(dict_t* x, void* dt, dict_access_callback callback, bool flush) { dnode_t *c; ssize_t i; int r; r = 0; i = x->capacity; while (i) { c = x->nodes[--i]; while (!is_null(c)) { r = callback(vnode_peek(&c->key, c->key_type), c->key_type, vnode_peek(&c->value, c->value_type), c->value_type, dt); c = c->prev; if (r) { if (!flush) goto end_; else goto flush_loop_; } else if (flush) { vnode_free(&x->nodes[i]->key, x->nodes[i]->key_type); vnode_free(&x->nodes[i]->value, x->nodes[i]->value_type); free(x->nodes[i]); x->nodes[i] = c; } } } if (flush) { while (i) { --i; while (!is_null(x->nodes[i])) { flush_loop_: vnode_free(&x->nodes[i]->key, x->nodes[i]->key_type); vnode_free(&x->nodes[i]->value, x->nodes[i]->value_type); c = x->nodes[i]->prev; free(x->nodes[i]); x->nodes[i] = c; } } free(x->nodes); memset(x, 0, sizeof(*x)); } end_: return r; }