98 } |
98 } |
99 |
99 |
100 if (elm != NULL && elm->key.hash == hash && elm->key.len == key.len && |
100 if (elm != NULL && elm->key.hash == hash && elm->key.len == key.len && |
101 memcmp(elm->key.data.obj, key.data.obj, key.len) == 0) { |
101 memcmp(elm->key.data.obj, key.data.obj, key.len) == 0) { |
102 // overwrite existing element |
102 // overwrite existing element |
103 if (map->store_pointers) { |
103 if (map->store_pointer) { |
104 memcpy(elm->data, &value, sizeof(void *)); |
104 memcpy(elm->data, &value, sizeof(void *)); |
105 } else { |
105 } else { |
106 memcpy(elm->data, value, map->item_size); |
106 memcpy(elm->data, value, map->item_size); |
107 } |
107 } |
108 } else { |
108 } else { |
192 struct cx_hash_map_element_s *prev = NULL; |
192 struct cx_hash_map_element_s *prev = NULL; |
193 while (elm && elm->key.hash <= hash) { |
193 while (elm && elm->key.hash <= hash) { |
194 if (elm->key.hash == hash && elm->key.len == key.len) { |
194 if (elm->key.hash == hash && elm->key.len == key.len) { |
195 if (memcmp(elm->key.data.obj, key.data.obj, key.len) == 0) { |
195 if (memcmp(elm->key.data.obj, key.data.obj, key.len) == 0) { |
196 void *data = NULL; |
196 void *data = NULL; |
197 if (map->store_pointers) { |
197 if (map->store_pointer) { |
198 data = *(void **) elm->data; |
198 data = *(void **) elm->data; |
199 } else if (!remove) { |
199 } else if (!remove) { |
200 data = elm->data; |
200 data = elm->data; |
201 } |
201 } |
202 if (remove) { |
202 if (remove) { |
241 |
241 |
242 static void *cx_hash_map_iter_current_value(void const *it) { |
242 static void *cx_hash_map_iter_current_value(void const *it) { |
243 struct cx_iterator_s const *iter = it; |
243 struct cx_iterator_s const *iter = it; |
244 struct cx_hash_map_s const *map = iter->src_handle; |
244 struct cx_hash_map_s const *map = iter->src_handle; |
245 struct cx_hash_map_element_s *elm = iter->elem_handle; |
245 struct cx_hash_map_element_s *elm = iter->elem_handle; |
246 if (map->base.store_pointers) { |
246 if (map->base.store_pointer) { |
247 return *(void **) elm->data; |
247 return *(void **) elm->data; |
248 } else { |
248 } else { |
249 return elm->data; |
249 return elm->data; |
250 } |
250 } |
251 } |
251 } |
302 if (elm == NULL) { |
302 if (elm == NULL) { |
303 iter->kv_data.key = NULL; |
303 iter->kv_data.key = NULL; |
304 iter->kv_data.value = NULL; |
304 iter->kv_data.value = NULL; |
305 } else { |
305 } else { |
306 iter->kv_data.key = &elm->key; |
306 iter->kv_data.key = &elm->key; |
307 if (map->base.store_pointers) { |
307 if (map->base.store_pointer) { |
308 iter->kv_data.value = *(void **) elm->data; |
308 iter->kv_data.value = *(void **) elm->data; |
309 } else { |
309 } else { |
310 iter->kv_data.value = elm->data; |
310 iter->kv_data.value = elm->data; |
311 } |
311 } |
312 } |
312 } |
342 while (elm == NULL) { |
342 while (elm == NULL) { |
343 elm = hash_map->buckets[++iter.slot]; |
343 elm = hash_map->buckets[++iter.slot]; |
344 } |
344 } |
345 iter.elem_handle = elm; |
345 iter.elem_handle = elm; |
346 iter.kv_data.key = &elm->key; |
346 iter.kv_data.key = &elm->key; |
347 if (map->store_pointers) { |
347 if (map->store_pointer) { |
348 iter.kv_data.value = *(void **) elm->data; |
348 iter.kv_data.value = *(void **) elm->data; |
349 } else { |
349 } else { |
350 iter.kv_data.value = elm->data; |
350 iter.kv_data.value = elm->data; |
351 } |
351 } |
352 } else { |
352 } else { |
414 if (buckets == 0) { |
414 if (buckets == 0) { |
415 // implementation defined default |
415 // implementation defined default |
416 buckets = 16; |
416 buckets = 16; |
417 } |
417 } |
418 |
418 |
419 struct cx_hash_map_s *map = cxMalloc(allocator, sizeof(struct cx_hash_map_s)); |
419 struct cx_hash_map_s *map = cxCalloc(allocator, 1, sizeof(struct cx_hash_map_s)); |
420 if (map == NULL) return NULL; |
420 if (map == NULL) return NULL; |
421 |
421 |
422 // initialize hash map members |
422 // initialize hash map members |
423 map->bucket_count = buckets; |
423 map->bucket_count = buckets; |
424 map->buckets = cxCalloc(allocator, buckets, sizeof(struct cx_hash_map_element_s *)); |
424 map->buckets = cxCalloc(allocator, buckets, sizeof(struct cx_hash_map_element_s *)); |
428 } |
428 } |
429 |
429 |
430 // initialize base members |
430 // initialize base members |
431 map->base.cl = &cx_hash_map_class; |
431 map->base.cl = &cx_hash_map_class; |
432 map->base.allocator = allocator; |
432 map->base.allocator = allocator; |
433 map->base.size = 0; |
|
434 |
433 |
435 if (itemsize > 0) { |
434 if (itemsize > 0) { |
436 map->base.store_pointers = false; |
435 map->base.store_pointer = false; |
437 map->base.item_size = itemsize; |
436 map->base.item_size = itemsize; |
438 } else { |
437 } else { |
439 map->base.store_pointers = true; |
438 map->base.store_pointer = true; |
440 map->base.item_size = sizeof(void *); |
439 map->base.item_size = sizeof(void *); |
441 } |
440 } |
442 |
441 |
443 return (CxMap *) map; |
442 return (CxMap *) map; |
444 } |
443 } |