99 while (elm != NULL && elm->key.hash < hash) { |
99 while (elm != NULL && elm->key.hash < hash) { |
100 prev = elm; |
100 prev = elm; |
101 elm = elm->next; |
101 elm = elm->next; |
102 } |
102 } |
103 |
103 |
104 if (elm != NULL && elm->key.hash == hash && elm->key.len == key.len && |
104 if (elm != NULL && cx_hash_key_cmp(&elm->key, &key) == 0) { |
105 memcmp(elm->key.data, key.data, key.len) == 0) { |
|
106 // overwrite existing element, but call destructors first |
105 // overwrite existing element, but call destructors first |
107 cx_invoke_destructor(map, elm->data); |
106 cx_invoke_destructor(map, elm->data); |
108 if (value == NULL) { |
107 if (value == NULL) { |
109 memset(elm->data, 0, map->collection.elem_size); |
108 memset(elm->data, 0, map->collection.elem_size); |
110 } else if (map->collection.store_pointer) { |
109 } else if (map->collection.store_pointer) { |
212 |
211 |
213 size_t slot = hash % hash_map->bucket_count; |
212 size_t slot = hash % hash_map->bucket_count; |
214 struct cx_hash_map_element_s *elm = hash_map->buckets[slot]; |
213 struct cx_hash_map_element_s *elm = hash_map->buckets[slot]; |
215 struct cx_hash_map_element_s *prev = NULL; |
214 struct cx_hash_map_element_s *prev = NULL; |
216 while (elm && elm->key.hash <= hash) { |
215 while (elm && elm->key.hash <= hash) { |
217 if (elm->key.hash == hash && elm->key.len == key.len) { |
216 if (cx_hash_key_cmp(&elm->key, &key) == 0) { |
218 if (memcmp(elm->key.data, key.data, key.len) == 0) { |
217 if (remove) { |
219 if (remove) { |
218 if (targetbuf == NULL) { |
220 if (targetbuf == NULL) { |
219 cx_invoke_destructor(map, elm->data); |
221 cx_invoke_destructor(map, elm->data); |
|
222 } else { |
|
223 memcpy(targetbuf, elm->data, map->collection.elem_size); |
|
224 } |
|
225 cx_hash_map_unlink(hash_map, slot, prev, elm); |
|
226 } else { |
220 } else { |
227 assert(targetbuf != NULL); |
221 memcpy(targetbuf, elm->data, map->collection.elem_size); |
228 void *data = NULL; |
|
229 if (map->collection.store_pointer) { |
|
230 data = *(void **) elm->data; |
|
231 } else { |
|
232 data = elm->data; |
|
233 } |
|
234 memcpy(targetbuf, &data, sizeof(void *)); |
|
235 } |
222 } |
236 return 0; |
223 cx_hash_map_unlink(hash_map, slot, prev, elm); |
|
224 } else { |
|
225 assert(targetbuf != NULL); |
|
226 void *data = NULL; |
|
227 if (map->collection.store_pointer) { |
|
228 data = *(void **) elm->data; |
|
229 } else { |
|
230 data = elm->data; |
|
231 } |
|
232 memcpy(targetbuf, &data, sizeof(void *)); |
237 } |
233 } |
|
234 return 0; |
238 } |
235 } |
239 prev = elm; |
236 prev = elm; |
240 elm = prev->next; |
237 elm = prev->next; |
241 } |
238 } |
242 |
239 |