Fix dict extra
This commit is contained in:
		
							parent
							
								
									d42dcc4a07
								
							
						
					
					
						commit
						a1293af307
					
				@ -23,10 +23,6 @@ static int dnode_compare(const dnode_t *s0, const dnode_t *s1, void* not_used) {
 | 
			
		||||
    return (!c) ? vnode_compare(&s0->value, s1->val_type, &s1->value, s1->val_type) : c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static hash_t dnode_hash(const dnode_t* s, void* not_used) {
 | 
			
		||||
    return vnode_hash(s->key, s->key_type) + vnode_hash(s->value, s->val_type) + s->key_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*#####################################################################################################################*/
 | 
			
		||||
 | 
			
		||||
static int dict_compare_equal_capacity(const dict_t* s0, const dict_t* s1) {
 | 
			
		||||
 | 
			
		||||
@ -6,15 +6,20 @@
 | 
			
		||||
/*#####################################################################################################################*/
 | 
			
		||||
 | 
			
		||||
static void dict_rehash(dict_t* s, size_t capacity) {
 | 
			
		||||
    stack_t z;
 | 
			
		||||
    int cmp;
 | 
			
		||||
    dnode_t *c, *p, *n, **r;
 | 
			
		||||
    stack_t    z;
 | 
			
		||||
    int      cmp;
 | 
			
		||||
    size_t index;
 | 
			
		||||
    dnode_t *c, *p, *n;
 | 
			
		||||
 | 
			
		||||
    dnode_t **nodes = malloc(capacity * sizeof(*nodes));
 | 
			
		||||
    dnode_t **nodes = calloc(capacity, sizeof(*nodes));
 | 
			
		||||
 | 
			
		||||
    while (s->capacity--) {
 | 
			
		||||
        if (!dnode_is_empty(s->nodes[s->capacity]))
 | 
			
		||||
            stack_push(&z, s->nodes[s->capacity]);
 | 
			
		||||
    z.prev  = 0;
 | 
			
		||||
    z.value = 0;
 | 
			
		||||
    index   = s->capacity;
 | 
			
		||||
 | 
			
		||||
    while (index--) {
 | 
			
		||||
        if (!dnode_is_empty(s->nodes[index]))
 | 
			
		||||
            stack_push(&z, s->nodes[index]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    while ((c = stack_pop(&z))) {
 | 
			
		||||
@ -29,9 +34,10 @@ static void dict_rehash(dict_t* s, size_t capacity) {
 | 
			
		||||
            c->left = dnode_empty;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        n = *(r = &nodes[vnode_hash(c->key, c->key_type) / capacity]);
 | 
			
		||||
        index = vnode_hash(&c->key, c->key_type) % capacity;
 | 
			
		||||
        n     = nodes[index];
 | 
			
		||||
 | 
			
		||||
        if (!dnode_is_empty(*r)) {
 | 
			
		||||
        if (!is_null(nodes[index])) {
 | 
			
		||||
            do {
 | 
			
		||||
                p   = n;
 | 
			
		||||
                cmp = vnode_compare(&c->key, c->key_type, &n->key, n->key_type);
 | 
			
		||||
@ -45,19 +51,27 @@ static void dict_rehash(dict_t* s, size_t capacity) {
 | 
			
		||||
            c->colored = 1;
 | 
			
		||||
 | 
			
		||||
            if (!dnode_is_root(p))
 | 
			
		||||
                dnode_fixup(r, n);
 | 
			
		||||
                dnode_fixup(nodes + index, n);
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
            *r         = c;
 | 
			
		||||
            c->colored = 0;
 | 
			
		||||
            c->parent  = dnode_empty;
 | 
			
		||||
            nodes[index] = c;
 | 
			
		||||
            c->colored   = 0;
 | 
			
		||||
            c->parent    = dnode_empty;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    free(s->nodes);
 | 
			
		||||
 | 
			
		||||
    s->capacity = capacity;
 | 
			
		||||
    s->nodes    = nodes;
 | 
			
		||||
 | 
			
		||||
    if (capacity > s->capacity) {
 | 
			
		||||
        s->capacity = capacity;
 | 
			
		||||
        while (capacity--) {
 | 
			
		||||
            if (is_null(*nodes))
 | 
			
		||||
                *nodes = dnode_empty;
 | 
			
		||||
            ++nodes;
 | 
			
		||||
        }
 | 
			
		||||
    } else s->capacity = capacity;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*#####################################################################################################################*/
 | 
			
		||||
@ -83,17 +97,18 @@ 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) {
 | 
			
		||||
 | 
			
		||||
    dnode_t **r, *n, *p;
 | 
			
		||||
    dnode_t *n, *p;
 | 
			
		||||
    vnode_t kn, vn;
 | 
			
		||||
    int cmp;
 | 
			
		||||
    int        cmp;
 | 
			
		||||
    size_t   index;
 | 
			
		||||
 | 
			
		||||
    if (!x->capacity || (double)x->size / x->capacity > REBUILD_POINT_MAX) {
 | 
			
		||||
    if (!x->capacity || (double)x->size / x->capacity > REBUILD_POINT_MAX)
 | 
			
		||||
        dict_rehash(x, x->capacity + CAPACITY_BLOCK);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    n  = *(r = &x->nodes[vnode_hash(k, kt) / x->capacity]);
 | 
			
		||||
    kn = vnode_create(k, kt);
 | 
			
		||||
    vn = vnode_create(v, vt);
 | 
			
		||||
    index = vtype_hash(k, kt) % x->capacity;
 | 
			
		||||
    n     = x->nodes[index];
 | 
			
		||||
    kn    = vnode_create(k, kt);
 | 
			
		||||
    vn    = vnode_create(v, vt);
 | 
			
		||||
 | 
			
		||||
    if (!dnode_is_empty(n)) {
 | 
			
		||||
        do {
 | 
			
		||||
@ -120,26 +135,30 @@ bool libcdsb_dict_update(dict_t* x, const void* k, vtype kt, const void* v, vtyp
 | 
			
		||||
        else         p->right = n;
 | 
			
		||||
 | 
			
		||||
        if (!dnode_is_root(p))
 | 
			
		||||
            dnode_fixup(r, n);
 | 
			
		||||
            dnode_fixup(x->nodes + index, n);
 | 
			
		||||
 | 
			
		||||
    } else n = *r = dnode_create(kn, dnode_empty, 0);
 | 
			
		||||
    } else x->nodes[index] = n = dnode_create(kn, dnode_empty, 0);
 | 
			
		||||
 | 
			
		||||
    n->value    = vn;
 | 
			
		||||
    n->key_type = kt;
 | 
			
		||||
    n->val_type = vt;
 | 
			
		||||
 | 
			
		||||
    ++x->size;
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int libcdsb_dict_get(dict_t* x, const void* k, vtype t, void* _, dict_access_callback callback, bool cut) {
 | 
			
		||||
 | 
			
		||||
    dnode_t *c, **r;
 | 
			
		||||
    void* key;
 | 
			
		||||
    int cmp;
 | 
			
		||||
    dnode_t   *c;
 | 
			
		||||
    void*    key;
 | 
			
		||||
    int      cmp;
 | 
			
		||||
    size_t index;
 | 
			
		||||
 | 
			
		||||
    if (x->capacity) {
 | 
			
		||||
        c = *(r = &x->nodes[vnode_hash(k, t) / x->capacity]);
 | 
			
		||||
        index = vtype_hash(k, t) % x->capacity;
 | 
			
		||||
        c     = x->nodes[index];
 | 
			
		||||
 | 
			
		||||
        while (!dnode_is_empty(c)) {
 | 
			
		||||
            key = vnode_peek(&c->key, c->key_type);
 | 
			
		||||
@ -149,9 +168,10 @@ int libcdsb_dict_get(dict_t* x, const void* k, vtype t, void* _, dict_access_cal
 | 
			
		||||
                cmp = (callback) ? callback(key, t, vnode_peek(&c->value, c->val_type), c->val_type, _) : 0;
 | 
			
		||||
 | 
			
		||||
                if (cut) {
 | 
			
		||||
                    c = dnode_delete(r, c);
 | 
			
		||||
                    c = dnode_delete(x->nodes + index, c);
 | 
			
		||||
                    dnode_free(c, nullptr);
 | 
			
		||||
                    free(c);
 | 
			
		||||
                    --x->size;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return cmp;
 | 
			
		||||
@ -178,7 +198,10 @@ int libcdsb_dict_foreach(dict_t* x, void* dt, dict_access_callback callback, boo
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    while ((c = stack_pop(&z))) {
 | 
			
		||||
        if ((r = callback(vnode_peek(&c->key, c->key_type), c->key_type, vnode_peek(&c->value, c->val_type), c->val_type, dt)))
 | 
			
		||||
        void* k = vnode_peek(&c->key,   c->key_type);
 | 
			
		||||
        void* v = vnode_peek(&c->value, c->val_type);
 | 
			
		||||
 | 
			
		||||
        if ((r = callback(k, c->key_type, v, c->val_type, dt)))
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        if (!dnode_is_empty(c->right)) stack_push(&z, c->right);
 | 
			
		||||
 | 
			
		||||
@ -8,9 +8,12 @@
 | 
			
		||||
#ifndef LIBCDSB_SRC_DICT_INCLUDE_H
 | 
			
		||||
#define LIBCDSB_SRC_DICT_INCLUDE_H
 | 
			
		||||
 | 
			
		||||
#ifndef DICT_CAPACITY_BLOCK
 | 
			
		||||
#define CAPACITY_BLOCK   100
 | 
			
		||||
#else
 | 
			
		||||
#define CAPACITY_BLOCK DICT_CAPACITY_BLOCK
 | 
			
		||||
#endif
 | 
			
		||||
#define REBUILD_POINT_MAX 0.65
 | 
			
		||||
#define REBUILD_POINT_MIN  1
 | 
			
		||||
 | 
			
		||||
typedef struct libcdsb_dict_node {
 | 
			
		||||
    struct libcdsb_dict_node* left;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user