88 lines
2.3 KiB
C
88 lines
2.3 KiB
C
/* 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;
|
|
}
|