113 // allocate new element |
113 // allocate new element |
114 struct cx_hash_map_element_s *e = cxMalloc( |
114 struct cx_hash_map_element_s *e = cxMalloc( |
115 allocator, |
115 allocator, |
116 sizeof(struct cx_hash_map_element_s) + map->collection.elem_size |
116 sizeof(struct cx_hash_map_element_s) + map->collection.elem_size |
117 ); |
117 ); |
118 if (e == NULL) { |
118 if (e == NULL) return -1; |
119 return -1; |
|
120 } |
|
121 |
119 |
122 // write the value |
120 // write the value |
123 if (map->collection.store_pointer) { |
121 if (map->collection.store_pointer) { |
124 memcpy(e->data, &value, sizeof(void *)); |
122 memcpy(e->data, &value, sizeof(void *)); |
125 } else { |
123 } else { |
126 memcpy(e->data, value, map->collection.elem_size); |
124 memcpy(e->data, value, map->collection.elem_size); |
127 } |
125 } |
128 |
126 |
129 // copy the key |
127 // copy the key |
130 void *kd = cxMalloc(allocator, key.len); |
128 void *kd = cxMalloc(allocator, key.len); |
131 if (kd == NULL) { |
129 if (kd == NULL) return -1; |
132 return -1; |
|
133 } |
|
134 memcpy(kd, key.data, key.len); |
130 memcpy(kd, key.data, key.len); |
135 e->key.data = kd; |
131 e->key.data = kd; |
136 e->key.len = key.len; |
132 e->key.len = key.len; |
137 e->key.hash = hash; |
133 e->key.hash = hash; |
138 |
134 |
361 case CX_MAP_ITERATOR_VALUES: |
357 case CX_MAP_ITERATOR_VALUES: |
362 iter.elem_size = map->collection.elem_size; |
358 iter.elem_size = map->collection.elem_size; |
363 iter.base.current = cx_hash_map_iter_current_value; |
359 iter.base.current = cx_hash_map_iter_current_value; |
364 break; |
360 break; |
365 default: |
361 default: |
366 assert(false); |
362 assert(false); // LCOV_EXCL_LINE |
367 } |
363 } |
368 |
364 |
369 iter.base.valid = cx_hash_map_iter_valid; |
365 iter.base.valid = cx_hash_map_iter_valid; |
370 iter.base.next = cx_hash_map_iter_next; |
366 iter.base.next = cx_hash_map_iter_next; |
371 iter.base.remove = false; |
367 iter.base.remove = false; |
425 |
421 |
426 // initialize hash map members |
422 // initialize hash map members |
427 map->bucket_count = buckets; |
423 map->bucket_count = buckets; |
428 map->buckets = cxCalloc(allocator, buckets, |
424 map->buckets = cxCalloc(allocator, buckets, |
429 sizeof(struct cx_hash_map_element_s *)); |
425 sizeof(struct cx_hash_map_element_s *)); |
430 if (map->buckets == NULL) { |
426 if (map->buckets == NULL) { // LCOV_EXCL_START |
431 cxFree(allocator, map); |
427 cxFree(allocator, map); |
432 return NULL; |
428 return NULL; |
433 } |
429 } // LCOV_EXCL_STOP |
434 |
430 |
435 // initialize base members |
431 // initialize base members |
436 map->base.cl = &cx_hash_map_class; |
432 map->base.cl = &cx_hash_map_class; |
437 map->base.collection.allocator = allocator; |
433 map->base.collection.allocator = allocator; |
438 |
434 |
459 struct cx_hash_map_element_s **new_buckets = cxCalloc( |
455 struct cx_hash_map_element_s **new_buckets = cxCalloc( |
460 map->collection.allocator, |
456 map->collection.allocator, |
461 new_bucket_count, sizeof(struct cx_hash_map_element_s *) |
457 new_bucket_count, sizeof(struct cx_hash_map_element_s *) |
462 ); |
458 ); |
463 |
459 |
464 if (new_buckets == NULL) { |
460 if (new_buckets == NULL) return 1; |
465 return 1; |
|
466 } |
|
467 |
461 |
468 // iterate through the elements and assign them to their new slots |
462 // iterate through the elements and assign them to their new slots |
469 for (size_t slot = 0; slot < hash_map->bucket_count; slot++) { |
463 for (size_t slot = 0; slot < hash_map->bucket_count; slot++) { |
470 struct cx_hash_map_element_s *elm = hash_map->buckets[slot]; |
464 struct cx_hash_map_element_s *elm = hash_map->buckets[slot]; |
471 while (elm != NULL) { |
465 while (elm != NULL) { |