/* This software is licensed by the MIT License, see LICENSE file */ /* Copyright © 2022 Gregory Lirent */ #include "../../include/set.h" #include "../__internal/rbtree.h" int libcdsb_vset_find(vtype_set* x, const void* v, vtype t, void* _, vset_access_callback callback, bool cut) { rbnode_t* c; void *val; int cmp; c = x->root; while (!rbnode_is_empty(c)) { val = vnode_peek(&c->value, x->type); cmp = vtype_compare(v, t, val, x->type); if (cmp == 0) { cmp = (callback) ? callback(val, x->type, _) : 0; if (cut) { c = rbnode_delete(&x->root, c); vnode_free(&c->value, x->type); free(c); } return cmp; } else c = (cmp < 0) ? c->left : c->right; } return -1; } int libcdsb_vset_foreach(set_t* x, void* data, vset_access_callback callback, bool flush) { stack_t z; int r; rbnode_t* c; stack_init(&z); stack_push(&z, x->root); r = 0; if (rbnode_is_empty(x->root)) return 0; while ((c = stack_pop(&z))) { if ((r = callback(vnode_peek(&c->value, x->type), x->type, data))) break; if (!rbnode_is_empty(c->right)) stack_push(&z, c->right); if (!rbnode_is_empty(c->left)) stack_push(&z, c->left); if (flush) { vnode_free(&c->value, x->type); free(c); } } if (flush) { while (c) { if (!rbnode_is_empty(c->right)) stack_push(&z, c->right); if (!rbnode_is_empty(c->left)) stack_push(&z, c->left); vnode_free(&c->value, x->type); free(c); c = stack_pop(&z); } memset(x, 0, sizeof(*x)); } else stack_flush(&z); return r; }