1.1 --- a/src/hash_map.c Fri May 27 14:14:55 2022 +0200 1.2 +++ b/src/hash_map.c Fri May 27 17:40:27 2022 +0200 1.3 @@ -396,3 +396,52 @@ 1.4 1.5 return (CxMap *) map; 1.6 } 1.7 + 1.8 +int cxMapRehash(CxMap *map) { 1.9 + struct cx_hash_map_s *hash_map = (struct cx_hash_map_s *) map; 1.10 + if (map->size > ((hash_map->bucket_count * 3) >> 2)) { 1.11 + 1.12 + size_t new_bucket_count = (map->size * 5) >> 1; 1.13 + struct cx_hash_map_element_s **new_buckets = cxCalloc(map->allocator, 1.14 + new_bucket_count, sizeof(struct cx_hash_map_element_s *)); 1.15 + 1.16 + if (new_buckets == NULL) { 1.17 + return 1; 1.18 + } 1.19 + 1.20 + // iterate through the elements and assign them to their new slots 1.21 + cx_for_n(slot, hash_map->bucket_count) { 1.22 + struct cx_hash_map_element_s *elm = hash_map->buckets[slot]; 1.23 + while (elm != NULL) { 1.24 + struct cx_hash_map_element_s *next = elm->next; 1.25 + size_t new_slot = elm->key.hash % new_bucket_count; 1.26 + 1.27 + // find position where to insert 1.28 + struct cx_hash_map_element_s *bucket_next = new_buckets[new_slot]; 1.29 + struct cx_hash_map_element_s *bucket_prev = NULL; 1.30 + while (bucket_next != NULL && bucket_next->key.hash < elm->key.hash) { 1.31 + bucket_prev = bucket_next; 1.32 + bucket_next = bucket_next->next; 1.33 + } 1.34 + 1.35 + // insert 1.36 + if (bucket_prev == NULL) { 1.37 + elm->next = new_buckets[new_slot]; 1.38 + new_buckets[new_slot] = elm; 1.39 + } else { 1.40 + bucket_prev->next = elm; 1.41 + elm->next = bucket_next; 1.42 + } 1.43 + 1.44 + // advance 1.45 + elm = next; 1.46 + } 1.47 + } 1.48 + 1.49 + // assign result to the map 1.50 + hash_map->bucket_count = new_bucket_count; 1.51 + cxFree(map->allocator, hash_map->buckets); 1.52 + hash_map->buckets = new_buckets; 1.53 + } 1.54 + return 0; 1.55 +}