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