Update dict (vtype_variable)
This commit is contained in:
		
							parent
							
								
									c2144f04cf
								
							
						
					
					
						commit
						b21ce2e799
					
				@ -7,7 +7,7 @@
 | 
			
		||||
#ifndef LIBCDSB_DICT_H
 | 
			
		||||
#define LIBCDSB_DICT_H
 | 
			
		||||
 | 
			
		||||
typedef int (*dict_access_callback)(const void* key, vtype key_type, void* value, vtype value_type, void* data);
 | 
			
		||||
typedef int (*dict_access_callback)(vtype_variable key, vtype_variable value, void* data);
 | 
			
		||||
 | 
			
		||||
/*#####################################################################################################################*/
 | 
			
		||||
 | 
			
		||||
@ -17,10 +17,10 @@ inline void dict_init(vtype_dict* x) { x->nodes = (void*)(x->capacity = x->size
 | 
			
		||||
 | 
			
		||||
/*#####################################################################################################################*/
 | 
			
		||||
 | 
			
		||||
#define dict_pop(x, key, data, callback) libcdsb_dict_find        (x, _LIBCDSB_value_pointer(key), _LIBCDSB_vtypeof(key), data, callback, 1)
 | 
			
		||||
#define dict_get(x, key, data, callback) libcdsb_dict_find        (x, _LIBCDSB_value_pointer(key), _LIBCDSB_vtypeof(key), data, callback, 0)
 | 
			
		||||
#define dict_update(x, key, value)       libcdsb_dict_update      (x, _LIBCDSB_value_pointer(key), _LIBCDSB_vtypeof(key), _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value), 0, 0)
 | 
			
		||||
#define dict_inject(x, key, value)       libcdsb_dict_inject      (x, _LIBCDSB_value_pointer(key), _LIBCDSB_vtypeof(key), _LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value), 0, 0)
 | 
			
		||||
#define dict_pop(x, key, data, callback) libcdsb_dict_find        (x, libcdsb_variable_build(_LIBCDSB_value_pointer(key), _LIBCDSB_vtypeof(key)), data, callback, 1)
 | 
			
		||||
#define dict_get(x, key, data, callback) libcdsb_dict_find        (x, libcdsb_variable_build(_LIBCDSB_value_pointer(key), _LIBCDSB_vtypeof(key)), data, callback, 0)
 | 
			
		||||
#define dict_update(x, key, value)       libcdsb_dict_update      (x, libcdsb_variable_build(_LIBCDSB_value_pointer(key), _LIBCDSB_vtypeof(key)), libcdsb_variable_build(_LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value)), 0, 0)
 | 
			
		||||
#define dict_inject(x, key, value)       libcdsb_dict_inject      (x, libcdsb_variable_build(_LIBCDSB_value_pointer(key), _LIBCDSB_vtypeof(key)), libcdsb_variable_build(_LIBCDSB_value_pointer(value), _LIBCDSB_vtypeof(value)), 0, 0)
 | 
			
		||||
#define dict_foreach(x, data, callback)  libcdsb_dict_foreach     (x, data, callback, 0)
 | 
			
		||||
#define dict_remove(x, key)              dict_pop                 (x, key, 0, 0)
 | 
			
		||||
 | 
			
		||||
@ -28,10 +28,10 @@ inline void dict_init(vtype_dict* x) { x->nodes = (void*)(x->capacity = x->size
 | 
			
		||||
 | 
			
		||||
/*#####################################################################################################################*/
 | 
			
		||||
 | 
			
		||||
extern bool libcdsb_dict_update       (vtype_dict* x, const void* key, vtype key_type, const void* value, vtype value_type, void* data, dict_access_callback) Nonnull__(1);
 | 
			
		||||
extern bool libcdsb_dict_inject       (vtype_dict* x, const void* key, vtype key_type, const void* value, vtype value_type, void* data, dict_access_callback) Nonnull__(1);
 | 
			
		||||
extern int  libcdsb_dict_find         (vtype_dict* x, const void* key, vtype key_type, void* data, dict_access_callback, bool cut)                            Nonnull__(1);
 | 
			
		||||
extern int  libcdsb_dict_foreach      (vtype_dict* x, void* data, dict_access_callback, bool flush)                                                           Nonnull__(1,3);
 | 
			
		||||
extern bool libcdsb_dict_shrink_to_fit(vtype_dict* x)                                                                                                         Nonnull__(1);
 | 
			
		||||
extern bool libcdsb_dict_update       (vtype_dict* x, vtype_variable key, vtype_variable value, void* data, dict_access_callback)             Nonnull__(1);
 | 
			
		||||
extern bool libcdsb_dict_inject       (vtype_dict* x, vtype_variable key, vtype_variable value, void* data, dict_access_callback)             Nonnull__(1);
 | 
			
		||||
extern int  libcdsb_dict_find         (vtype_dict* x, vtype_variable key,                       void* data, dict_access_callback, bool cut)   Nonnull__(1);
 | 
			
		||||
extern int  libcdsb_dict_foreach      (vtype_dict* x,                                           void* data, dict_access_callback, bool flush) Nonnull__(1,3);
 | 
			
		||||
extern bool libcdsb_dict_shrink_to_fit(vtype_dict* x)                                                                                         Nonnull__(1);
 | 
			
		||||
 | 
			
		||||
#endif /* LIBCDSB_DICT_H */
 | 
			
		||||
 | 
			
		||||
@ -3,18 +3,19 @@
 | 
			
		||||
 | 
			
		||||
#include "include.h"
 | 
			
		||||
 | 
			
		||||
int libcdsb_dict_find(dict_t* x, const void* k, vtype t, void* dt, dict_access_callback callback, bool cut) {
 | 
			
		||||
int libcdsb_dict_find(dict_t* x, vtype_variable kvar, 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));
 | 
			
		||||
        c = *(p = x->nodes + (vtype_hash(kvar.pointer, kvar.type) % 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 (vtype_compare(kvar.pointer, kvar.type, key, c->key_type) == 0) {
 | 
			
		||||
                r = (callback) ? callback(libcdsb_variable_build(key, c->key_type),
 | 
			
		||||
                                          libcdsb_variable_build(vnode_peek(&c->value, c->value_type), c->value_type), dt) : 0;
 | 
			
		||||
 | 
			
		||||
                if (cut) {
 | 
			
		||||
                    *p = c->prev;
 | 
			
		||||
@ -45,8 +46,8 @@ int libcdsb_dict_foreach(dict_t* x, void* dt, dict_access_callback callback, boo
 | 
			
		||||
        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);
 | 
			
		||||
            r = callback(libcdsb_variable_build(vnode_peek(&c->key,   c->key_type),   c->key_type),
 | 
			
		||||
                         libcdsb_variable_build(vnode_peek(&c->value, c->value_type), c->value_type), dt);
 | 
			
		||||
 | 
			
		||||
            c = c->prev;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -50,22 +50,22 @@ 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, void* dt, dict_access_callback callback) {
 | 
			
		||||
bool libcdsb_dict_update(dict_t* x, vtype_variable key, vtype_variable value, void* dt, dict_access_callback callback) {
 | 
			
		||||
    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));
 | 
			
		||||
    c = *(p = x->nodes + (vtype_hash(key.pointer, key.type) % x->capacity));
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
        if (vtype_compare(key.pointer, key.type, vnode_peek(&c->key, c->key_type), c->key_type) == 0) {
 | 
			
		||||
            if (!callback) callback(libcdsb_variable_build(vnode_peek(&c->key,   c->key_type),   c->key_type),
 | 
			
		||||
                                    libcdsb_variable_build(vnode_peek(&c->value, c->value_type), c->value_type), dt);
 | 
			
		||||
 | 
			
		||||
            vnode_free(&c->value, c->value_type);
 | 
			
		||||
 | 
			
		||||
            c->value = vnode_create(v, c->value_type = vt);
 | 
			
		||||
            c->value = vnode_create(value.pointer, c->value_type = value.type);
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        } else c = c->prev;
 | 
			
		||||
@ -74,8 +74,8 @@ 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, c->key_type   = kt);
 | 
			
		||||
    c->value = vnode_create(v, c->value_type = vt);
 | 
			
		||||
    c->key   = vnode_create(key.pointer,   c->key_type   = key.type);
 | 
			
		||||
    c->value = vnode_create(value.pointer, c->value_type = value.type);
 | 
			
		||||
 | 
			
		||||
    *p = c;
 | 
			
		||||
    ++x->size;
 | 
			
		||||
@ -84,32 +84,32 @@ 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, void* dt, dict_access_callback callback) {
 | 
			
		||||
bool libcdsb_dict_inject(dict_t* x, vtype_variable key, vtype_variable value, void* dt, dict_access_callback callback) {
 | 
			
		||||
    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));
 | 
			
		||||
    c = *(p = x->nodes + (vtype_hash(key.pointer, key.type) % x->capacity));
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
        if (vtype_compare(key.pointer, key.type, vnode_peek(&c->key, c->key_type), c->key_type) == 0) {
 | 
			
		||||
            if (!callback) callback(libcdsb_variable_build(vnode_peek(&c->key,   c->key_type),   c->key_type),
 | 
			
		||||
                                    libcdsb_variable_build(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);
 | 
			
		||||
 | 
			
		||||
            vnode_attach(&c->key,   k, c->key_type   = kt);
 | 
			
		||||
            vnode_attach(&c->value, v, c->value_type = vt);
 | 
			
		||||
            vnode_attach(&c->key,   key.pointer,   c->key_type   = key.type);
 | 
			
		||||
            vnode_attach(&c->value, value.pointer, c->value_type = value.type);
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        } else c = c->prev;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    (c = malloc(sizeof(*c)))->prev = *p;
 | 
			
		||||
    vnode_attach(&c->key,   k, c->key_type   = kt);
 | 
			
		||||
    vnode_attach(&c->value, v, c->value_type = vt);
 | 
			
		||||
    vnode_attach(&c->key,   key.pointer,   c->key_type   = key.type);
 | 
			
		||||
    vnode_attach(&c->value, value.pointer, c->value_type = value.type);
 | 
			
		||||
 | 
			
		||||
    *p = c;
 | 
			
		||||
    ++x->size;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user