Fix set (extra) insertion & foreach

This commit is contained in:
Gregory Lirent 2022-06-06 23:46:55 +03:00
parent 09acdb5118
commit c17edda61c
1 changed files with 20 additions and 14 deletions

View File

@ -36,33 +36,38 @@ _Bool libcdsb_vset_find(val_t* x, set_t* s, const void* v, vtype t, _Bool cut) {
_Bool libcdsb_vset_insert(set_t* x, const void* v, vtype t) { _Bool libcdsb_vset_insert(set_t* x, const void* v, vtype t) {
int cmp; int cmp;
rbnode_t* n; rbnode_t* n;
rbnode_t* p; rbnode_t* p;
vnode_t vn;
n = x->root; n = x->root;
vn = vnode_tcreate(x->type, v, t);
t = x->type;
v = vnode_peek(&vn, t);
if (!rbnode_is_empty(n)) { if (!rbnode_is_empty(n)) {
do { do {
p = n; p = n;
cmp = vtype_compare(vnode_peek(&n->value, x->type), x->type, v, t); cmp = vtype_compare(v, t, vnode_peek(&n->value, t), t);
if (cmp == 0) return false; if (cmp == 0) {
vnode_free(&vn, t);
return false;
}
n = (cmp > 0) ? n->left : n->right; n = (cmp < 0) ? n->left : n->right;
} while (!rbnode_is_empty(n)); } while (!rbnode_is_empty(n));
n = rbnode_create(0, p, 1); n = rbnode_create(vn, p, 1);
if (cmp > 0) p->left = n; if (cmp < 0) p->left = n;
else p->right = n; else p->right = n;
if (!rbnode_is_root(n->parent)) if (!rbnode_is_root(p))
rbnode_fixup(&x->root, n); rbnode_fixup(&x->root, n);
} else n = x->root = rbnode_create(0, p, 1); } else n = x->root = rbnode_create(vn, rbnode_empty, 0);
n->value = vnode_tcreate(x->type, v, t);
return true; return true;
} }
@ -74,10 +79,11 @@ _Bool libcdsb_vset_insert(set_t* x, const void* v, vtype t) {
int libcdsb_vset_foreach(const vtype_set* x, int (*callback)(const void* value, vtype type)) { int libcdsb_vset_foreach(const vtype_set* x, int (*callback)(const void* value, vtype type)) {
rbiter_t i; rbiter_t i;
int r; int r;
rbnode_t* c;
if (rbiter_init(&i, &x->root, 0)) { if (rbiter_init(&i, &x->root, 0)) {
while (!rbnode_is_empty(rbiter_next(&i))) { while (!rbnode_is_empty(c = rbiter_next(&i))) {
if ((r = callback(vnode_peek(&i.cursor->value, x->type), x->type))) if ((r = callback(vnode_peek(&c->value, x->type), x->type)))
return r; return r;
} }
} }