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; |     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) { | 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) { | static void dict_rehash(dict_t* s, size_t capacity) { | ||||||
|     stack_t z; |     stack_t    z; | ||||||
|     int cmp; |     int      cmp; | ||||||
|     dnode_t *c, *p, *n, **r; |     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--) { |     z.prev  = 0; | ||||||
|         if (!dnode_is_empty(s->nodes[s->capacity])) |     z.value = 0; | ||||||
|             stack_push(&z, s->nodes[s->capacity]); |     index   = s->capacity; | ||||||
|  | 
 | ||||||
|  |     while (index--) { | ||||||
|  |         if (!dnode_is_empty(s->nodes[index])) | ||||||
|  |             stack_push(&z, s->nodes[index]); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     while ((c = stack_pop(&z))) { |     while ((c = stack_pop(&z))) { | ||||||
| @ -29,9 +34,10 @@ static void dict_rehash(dict_t* s, size_t capacity) { | |||||||
|             c->left = dnode_empty; |             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 { |             do { | ||||||
|                 p   = n; |                 p   = n; | ||||||
|                 cmp = vnode_compare(&c->key, c->key_type, &n->key, n->key_type); |                 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; |             c->colored = 1; | ||||||
| 
 | 
 | ||||||
|             if (!dnode_is_root(p)) |             if (!dnode_is_root(p)) | ||||||
|                 dnode_fixup(r, n); |                 dnode_fixup(nodes + index, n); | ||||||
| 
 | 
 | ||||||
|         } else { |         } else { | ||||||
|             *r         = c; |             nodes[index] = c; | ||||||
|             c->colored = 0; |             c->colored   = 0; | ||||||
|             c->parent  = dnode_empty; |             c->parent    = dnode_empty; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     free(s->nodes); |     free(s->nodes); | ||||||
| 
 | 
 | ||||||
|     s->capacity = capacity; |  | ||||||
|     s->nodes    = nodes; |     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) { | 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; |     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); |         dict_rehash(x, x->capacity + CAPACITY_BLOCK); | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     n  = *(r = &x->nodes[vnode_hash(k, kt) / x->capacity]); |     index = vtype_hash(k, kt) % x->capacity; | ||||||
|     kn = vnode_create(k, kt); |     n     = x->nodes[index]; | ||||||
|     vn = vnode_create(v, vt); |     kn    = vnode_create(k, kt); | ||||||
|  |     vn    = vnode_create(v, vt); | ||||||
| 
 | 
 | ||||||
|     if (!dnode_is_empty(n)) { |     if (!dnode_is_empty(n)) { | ||||||
|         do { |         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; |         else         p->right = n; | ||||||
| 
 | 
 | ||||||
|         if (!dnode_is_root(p)) |         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->value    = vn; | ||||||
|     n->key_type = kt; |     n->key_type = kt; | ||||||
|     n->val_type = vt; |     n->val_type = vt; | ||||||
| 
 | 
 | ||||||
|  |     ++x->size; | ||||||
|  | 
 | ||||||
|     return false; |     return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| int libcdsb_dict_get(dict_t* x, const void* k, vtype t, void* _, dict_access_callback callback, bool cut) { | int libcdsb_dict_get(dict_t* x, const void* k, vtype t, void* _, dict_access_callback callback, bool cut) { | ||||||
| 
 | 
 | ||||||
|     dnode_t *c, **r; |     dnode_t   *c; | ||||||
|     void* key; |     void*    key; | ||||||
|     int cmp; |     int      cmp; | ||||||
|  |     size_t index; | ||||||
| 
 | 
 | ||||||
|     if (x->capacity) { |     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)) { |         while (!dnode_is_empty(c)) { | ||||||
|             key = vnode_peek(&c->key, c->key_type); |             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; |                 cmp = (callback) ? callback(key, t, vnode_peek(&c->value, c->val_type), c->val_type, _) : 0; | ||||||
| 
 | 
 | ||||||
|                 if (cut) { |                 if (cut) { | ||||||
|                     c = dnode_delete(r, c); |                     c = dnode_delete(x->nodes + index, c); | ||||||
|                     dnode_free(c, nullptr); |                     dnode_free(c, nullptr); | ||||||
|                     free(c); |                     free(c); | ||||||
|  |                     --x->size; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 return cmp; |                 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))) { |     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; |             break; | ||||||
| 
 | 
 | ||||||
|         if (!dnode_is_empty(c->right)) stack_push(&z, c->right); |         if (!dnode_is_empty(c->right)) stack_push(&z, c->right); | ||||||
|  | |||||||
| @ -8,9 +8,12 @@ | |||||||
| #ifndef LIBCDSB_SRC_DICT_INCLUDE_H | #ifndef LIBCDSB_SRC_DICT_INCLUDE_H | ||||||
| #define LIBCDSB_SRC_DICT_INCLUDE_H | #define LIBCDSB_SRC_DICT_INCLUDE_H | ||||||
| 
 | 
 | ||||||
|  | #ifndef DICT_CAPACITY_BLOCK | ||||||
| #define CAPACITY_BLOCK   100 | #define CAPACITY_BLOCK   100 | ||||||
|  | #else | ||||||
|  | #define CAPACITY_BLOCK DICT_CAPACITY_BLOCK | ||||||
|  | #endif | ||||||
| #define REBUILD_POINT_MAX 0.65 | #define REBUILD_POINT_MAX 0.65 | ||||||
| #define REBUILD_POINT_MIN  1 |  | ||||||
| 
 | 
 | ||||||
| typedef struct libcdsb_dict_node { | typedef struct libcdsb_dict_node { | ||||||
|     struct libcdsb_dict_node* left; |     struct libcdsb_dict_node* left; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user