Add callback support on value update (#61)

This commit is contained in:
2022-08-26 17:54:27 +03:00
parent 38bef70bc5
commit 932849a062
6 changed files with 66 additions and 132 deletions
+18 -89
View File
@@ -50,7 +50,7 @@ bool libcdsb_dict_shrink_to_fit(dict_t* s) {
}
bool libcdsb_dict_update(dict_t* x, const void* k, vtype kt, const void* v, vtype vt) {
bool libcdsb_dict_update(dict_t* x, const void* k, vtype kt, const void* v, vtype vt, void* dt, dict_access_callback callback) {
dnode_t *c, **p;
if (!x->capacity || (double)x->size / x->capacity > REBUILD_POINT_MAX)
@@ -60,10 +60,12 @@ bool libcdsb_dict_update(dict_t* x, const void* k, vtype kt, const void* v, vtyp
while (!is_null(c)) {
if (vtype_compare(k, kt, vnode_peek(&c->key, c->key_type), c->key_type) == 0) {
if (!callback) callback(vnode_peek(&c->key, c->key_type), c->key_type,
vnode_peek(&c->value, c->value_type), c->value_type, dt);
vnode_free(&c->value, c->value_type);
c->value = vnode_create(v, vt);
c->value_type = vt;
c->value = vnode_create(v, c->value_type = vt);
return true;
} else c = c->prev;
@@ -71,11 +73,9 @@ bool libcdsb_dict_update(dict_t* x, const void* k, vtype kt, const void* v, vtyp
c = malloc(sizeof(*c));
c->prev = *p;
c->key = vnode_create(k, kt);
c->value = vnode_create(v, vt);
c->key_type = kt;
c->value_type = vt;
c->prev = *p;
c->key = vnode_create(k, c->key_type = kt);
c->value = vnode_create(v, c->value_type = vt);
*p = c;
++x->size;
@@ -84,7 +84,7 @@ bool libcdsb_dict_update(dict_t* x, const void* k, vtype kt, const void* v, vtyp
}
bool libcdsb_dict_inject(dict_t* x, const void* k, vtype kt, const void* v, vtype vt) {
bool libcdsb_dict_inject(dict_t* x, const void* k, vtype kt, const void* v, vtype vt, void* dt, dict_access_callback callback) {
dnode_t *c, **p;
if (!x->capacity || (double)x->size / x->capacity > REBUILD_POINT_MAX)
@@ -94,93 +94,22 @@ bool libcdsb_dict_inject(dict_t* x, const void* k, vtype kt, const void* v, vtyp
while (!is_null(c)) {
if (vtype_compare(k, kt, vnode_peek(&c->key, c->key_type), c->key_type) == 0) {
if (!callback) callback(vnode_peek(&c->key, c->key_type), c->key_type,
vnode_peek(&c->value, c->value_type), c->value_type, dt);
vnode_free(&c->key, c->key_type);
vnode_free(&c->value, c->value_type);
c->value = vnode_create(v, vt);
c->value_type = vt;
vnode_attach(&c->key, k, c->key_type = kt);
vnode_attach(&c->value, v, c->value_type = vt);
return true;
} else c = c->prev;
}
c = malloc(sizeof(*c));
c->prev = *p;
c->key_type = kt;
c->value_type = vt;
vnode_attach(&c->key, k, kt);
vnode_attach(&c->value, v, vt);
*p = c;
++x->size;
return false;
}
bool libcdsb_dict_inject_key(dict_t* x, const void* k, vtype kt, const void* v, vtype vt) {
dnode_t *c, **p;
if (!x->capacity || (double)x->size / x->capacity > REBUILD_POINT_MAX)
libcdsb_builtin_rehash(x, x->capacity + CAPACITY_BLOCK);
c = *(p = x->nodes + (vtype_hash(k, kt) % x->capacity));
while (!is_null(c)) {
if (vtype_compare(k, kt, vnode_peek(&c->key, c->key_type), c->key_type) == 0) {
vnode_free(&c->value, c->value_type);
c->value = vnode_create(v, vt);
c->value_type = vt;
return true;
} else c = c->prev;
}
c = malloc(sizeof(*c));
c->prev = *p;
c->value = vnode_create(v, vt);
c->key_type = kt;
c->value_type = vt;
vnode_attach(&c->key, k, kt);
*p = c;
++x->size;
return false;
}
bool libcdsb_dict_inject_value(dict_t* x, const void* k, vtype kt, const void* v, vtype vt) {
dnode_t *c, **p;
if (!x->capacity || (double)x->size / x->capacity > REBUILD_POINT_MAX)
libcdsb_builtin_rehash(x, x->capacity + CAPACITY_BLOCK);
c = *(p = x->nodes + (vtype_hash(k, kt) % x->capacity));
while (!is_null(c)) {
if (vtype_compare(k, kt, vnode_peek(&c->key, c->key_type), c->key_type) == 0) {
vnode_free(&c->value, c->value_type);
c->value = vnode_create(v, vt);
c->value_type = vt;
return true;
} else c = c->prev;
}
c = malloc(sizeof(*c));
c->prev = *p;
c->key = vnode_create(k, kt);
c->key_type = kt;
c->value_type = vt;
vnode_attach(&c->value, v, vt);
(c = malloc(sizeof(*c)))->prev = *p;
vnode_attach(&c->key, k, c->key_type = kt);
vnode_attach(&c->value, v, c->value_type = vt);
*p = c;
++x->size;
+10 -6
View File
@@ -3,7 +3,7 @@
#include "include.h"
bool libcdsb_list_insert(list_t* x, ssize_t i, const void* v, vtype t, int ins) {
bool libcdsb_list_insert(list_t* x, ssize_t i, const void* v, vtype t, int ins, void* dt, list_access_callback callback) {
ldir_t dir;
lnode_t* c;
@@ -41,8 +41,10 @@ bool libcdsb_list_insert(list_t* x, ssize_t i, const void* v, vtype t, int ins)
} else ldir_inv((lnode_t*)x, dir) = c;
ldir_dir(ldir_inv(c, dir), dir) = c;
} else vnode_free(&c->node, c->type);
} else {
if (callback) callback(vnode_peek(&c->node, c->type), -1, c->type, dt);
vnode_free(&c->node, c->type);
}
c->node = vnode_create(v, t);
c->type = t;
@@ -51,7 +53,7 @@ bool libcdsb_list_insert(list_t* x, ssize_t i, const void* v, vtype t, int ins)
}
bool libcdsb_list_attach(list_t* x, ssize_t i, const void* v, vtype t, int ins) {
bool libcdsb_list_attach(list_t* x, ssize_t i, const void* v, vtype t, int ins, void* dt, list_access_callback callback) {
ldir_t dir;
lnode_t* c;
@@ -89,8 +91,10 @@ bool libcdsb_list_attach(list_t* x, ssize_t i, const void* v, vtype t, int ins)
} else ldir_inv((lnode_t*)x, dir) = c;
ldir_dir(ldir_inv(c, dir), dir) = c;
} else vnode_free(&c->node, c->type);
} else {
if (callback) callback(vnode_peek(&c->node, c->type), -1, c->type, dt);
vnode_free(&c->node, c->type);
}
vnode_attach(&c->node, v, c->type = t);
+9 -4
View File
@@ -3,7 +3,7 @@
#include "include.h"
bool libcdsb_map_update(map_t* x, const void* k, vtype kt, const void* v, vtype vt) {
bool libcdsb_map_update(map_t* x, const void* k, vtype kt, const void* v, vtype vt, void* dt, map_access_callback callback) {
int cmp;
mnode_t* n;
mnode_t* p;
@@ -14,10 +14,12 @@ bool libcdsb_map_update(map_t* x, const void* k, vtype kt, const void* v, vtype
cmp = vtype_compare(k, kt, vnode_peek(&n->key, kt), kt);
if (cmp == 0) {
if (callback) callback(vnode_peek(&n->key, x->type), x->type,
vnode_peek(&n->value, n->type), n->type, dt);
vnode_free(&n->value, n->type);
n->value = vnode_create(v, vt);
n->type = vt;
n->value = vnode_create(v, n->type = vt);
return true;
}
@@ -43,7 +45,7 @@ bool libcdsb_map_update(map_t* x, const void* k, vtype kt, const void* v, vtype
}
bool libcdsb_map_inject(map_t* x, const void* k, vtype kt, const void* v, vtype vt) {
bool libcdsb_map_inject(map_t* x, const void* k, vtype kt, const void* v, vtype vt, void* dt, map_access_callback callback) {
int cmp;
mnode_t* n;
mnode_t* p;
@@ -60,6 +62,9 @@ bool libcdsb_map_inject(map_t* x, const void* k, vtype kt, const void* v, vtype
cmp = vtype_compare(k, kt, vnode_peek(&n->key, kt), kt);
if (cmp == 0) {
if (callback) callback(vnode_peek(&n->key, x->type), x->type,
vnode_peek(&n->value, n->type), n->type, dt);
vnode_free(&n->key, x->type);
vnode_free(&n->value, n->type);