libcdsb/src/set/access.c

78 lines
1.8 KiB
C
Raw Normal View History

2022-06-06 11:23:33 +03:00
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
2022-08-19 17:19:22 +03:00
#include "../../include/set.h"
2022-06-06 11:23:33 +03:00
#include "../__internal/rbtree.h"
2022-06-09 16:29:10 +03:00
int libcdsb_vset_find(vtype_set* x, const void* v, vtype t, void* _, vset_access_callback callback, bool cut) {
2022-06-08 20:59:46 +03:00
rbnode_t* c;
void *val;
int cmp;
c = x->root;
while (!rbnode_is_empty(c)) {
val = vnode_peek(&c->value, x->type);
2022-06-10 21:22:52 +03:00
cmp = vtype_compare(v, t, val, x->type);
2022-06-08 20:59:46 +03:00
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;
2022-06-10 21:22:52 +03:00
} else c = (cmp < 0) ? c->left : c->right;
2022-06-08 20:59:46 +03:00
}
return -1;
}
2022-06-09 16:29:10 +03:00
int libcdsb_vset_foreach(set_t* x, void* data, vset_access_callback callback, bool flush) {
stack_t z;
int r;
2022-06-06 23:46:55 +03:00
rbnode_t* c;
2022-06-06 11:23:33 +03:00
stack_init(&z);
stack_push(&z, x->root);
r = 0;
if (rbnode_is_empty(x->root))
return 0;
2022-06-07 21:42:11 +03:00
while ((c = stack_pop(&z))) {
if ((r = callback(vnode_peek(&c->value, x->type), x->type, data)))
2022-06-07 21:42:11 +03:00
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);
}
2022-06-06 11:23:33 +03:00
}
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);
2022-06-07 21:42:11 +03:00
return r;
2022-06-06 11:23:33 +03:00
}