| 115 // allocate new element |
115 // allocate new element |
| 116 struct cx_hash_map_element_s *e = cxMalloc( |
116 struct cx_hash_map_element_s *e = cxMalloc( |
| 117 allocator, |
117 allocator, |
| 118 sizeof(struct cx_hash_map_element_s) + map->collection.elem_size |
118 sizeof(struct cx_hash_map_element_s) + map->collection.elem_size |
| 119 ); |
119 ); |
| 120 if (e == NULL) return NULL; |
120 if (e == NULL) return NULL; // LCOV_EXCL_LINE |
| 121 |
121 |
| 122 // write the value |
122 // write the value |
| 123 if (value == NULL) { |
123 if (value == NULL) { |
| 124 memset(e->data, 0, map->collection.elem_size); |
124 memset(e->data, 0, map->collection.elem_size); |
| 125 } else if (map->collection.store_pointer) { |
125 } else if (map->collection.store_pointer) { |
| 128 memcpy(e->data, value, map->collection.elem_size); |
128 memcpy(e->data, value, map->collection.elem_size); |
| 129 } |
129 } |
| 130 |
130 |
| 131 // copy the key |
131 // copy the key |
| 132 void *kd = cxMalloc(allocator, key.len); |
132 void *kd = cxMalloc(allocator, key.len); |
| 133 if (kd == NULL) { |
133 if (kd == NULL) { // LCOV_EXCL_START |
| 134 cxFree(allocator, e); |
134 cxFree(allocator, e); |
| 135 return NULL; |
135 return NULL; |
| 136 } |
136 } // LCOV_EXCL_STOP |
| 137 memcpy(kd, key.data, key.len); |
137 memcpy(kd, key.data, key.len); |
| 138 e->key.data = kd; |
138 e->key.data = kd; |
| 139 e->key.len = key.len; |
139 e->key.len = key.len; |
| 140 e->key.hash = hash; |
140 e->key.hash = hash; |
| 141 |
141 |
| 445 struct cx_hash_map_s *hash_map = (struct cx_hash_map_s *) map; |
445 struct cx_hash_map_s *hash_map = (struct cx_hash_map_s *) map; |
| 446 if (map->collection.size > ((hash_map->bucket_count * 3) >> 2)) { |
446 if (map->collection.size > ((hash_map->bucket_count * 3) >> 2)) { |
| 447 |
447 |
| 448 size_t new_bucket_count = (map->collection.size * 5) >> 1; |
448 size_t new_bucket_count = (map->collection.size * 5) >> 1; |
| 449 if (new_bucket_count < hash_map->bucket_count) { |
449 if (new_bucket_count < hash_map->bucket_count) { |
| |
450 // LCOV_EXCL_START |
| 450 errno = EOVERFLOW; |
451 errno = EOVERFLOW; |
| 451 return 1; |
452 return 1; |
| 452 } |
453 } // LCOV_EXCL_STOP |
| 453 struct cx_hash_map_element_s **new_buckets = cxCalloc( |
454 struct cx_hash_map_element_s **new_buckets = cxCalloc( |
| 454 map->collection.allocator, |
455 map->collection.allocator, |
| 455 new_bucket_count, sizeof(struct cx_hash_map_element_s *) |
456 new_bucket_count, sizeof(struct cx_hash_map_element_s *) |
| 456 ); |
457 ); |
| 457 |
458 |
| 458 if (new_buckets == NULL) return 1; |
459 if (new_buckets == NULL) return 1; // LCOV_EXCL_LINE |
| 459 |
460 |
| 460 // iterate through the elements and assign them to their new slots |
461 // iterate through the elements and assign them to their new slots |
| 461 for (size_t slot = 0; slot < hash_map->bucket_count; slot++) { |
462 for (size_t slot = 0; slot < hash_map->bucket_count; slot++) { |
| 462 struct cx_hash_map_element_s *elm = hash_map->buckets[slot]; |
463 struct cx_hash_map_element_s *elm = hash_map->buckets[slot]; |
| 463 while (elm != NULL) { |
464 while (elm != NULL) { |