diff -r 1f40ca07ae1b -r 839fefbdedc7 ucx/hash_map.c --- a/ucx/hash_map.c Sat Apr 20 13:01:58 2024 +0200 +++ b/ucx/hash_map.c Thu May 23 22:35:45 2024 +0200 @@ -53,9 +53,9 @@ // invoke the destructor cx_invoke_destructor(map, elem->data); // free the key data - cxFree(map->allocator, (void *) elem->key.data); + cxFree(map->collection.allocator, (void *) elem->key.data); // free the node - cxFree(map->allocator, elem); + cxFree(map->collection.allocator, elem); // proceed elem = next; } while (elem != NULL); @@ -64,7 +64,7 @@ hash_map->buckets[i] = NULL; } } - map->size = 0; + map->collection.size = 0; } static void cx_hash_map_destructor(struct cx_map_s *map) { @@ -72,10 +72,10 @@ // free the buckets cx_hash_map_clear(map); - cxFree(map->allocator, hash_map->buckets); + cxFree(map->collection.allocator, hash_map->buckets); // free the map structure - cxFree(map->allocator, map); + cxFree(map->collection.allocator, map); } static int cx_hash_map_put( @@ -84,7 +84,7 @@ void *value ) { struct cx_hash_map_s *hash_map = (struct cx_hash_map_s *) map; - CxAllocator const *allocator = map->allocator; + CxAllocator const *allocator = map->collection.allocator; unsigned hash = key.hash; if (hash == 0) { @@ -104,26 +104,26 @@ if (elm != NULL && elm->key.hash == hash && elm->key.len == key.len && memcmp(elm->key.data, key.data, key.len) == 0) { // overwrite existing element - if (map->store_pointer) { + if (map->collection.store_pointer) { memcpy(elm->data, &value, sizeof(void *)); } else { - memcpy(elm->data, value, map->item_size); + memcpy(elm->data, value, map->collection.elem_size); } } else { // allocate new element struct cx_hash_map_element_s *e = cxMalloc( allocator, - sizeof(struct cx_hash_map_element_s) + map->item_size + sizeof(struct cx_hash_map_element_s) + map->collection.elem_size ); if (e == NULL) { return -1; } // write the value - if (map->store_pointer) { + if (map->collection.store_pointer) { memcpy(e->data, &value, sizeof(void *)); } else { - memcpy(e->data, value, map->item_size); + memcpy(e->data, value, map->collection.elem_size); } // copy the key @@ -145,7 +145,7 @@ e->next = elm; // increase the size - map->size++; + map->collection.size++; } return 0; @@ -164,10 +164,10 @@ prev->next = elm->next; } // free element - cxFree(hash_map->base.allocator, (void *) elm->key.data); - cxFree(hash_map->base.allocator, elm); + cxFree(hash_map->base.collection.allocator, (void *) elm->key.data); + cxFree(hash_map->base.collection.allocator, elm); // decrease size - hash_map->base.size--; + hash_map->base.collection.size--; } /** @@ -203,7 +203,7 @@ if (destroy) { cx_invoke_destructor(map, elm->data); } else { - if (map->store_pointer) { + if (map->collection.store_pointer) { data = *(void **) elm->data; } else { data = elm->data; @@ -252,9 +252,9 @@ static void *cx_hash_map_iter_current_value(void const *it) { struct cx_iterator_s const *iter = it; - struct cx_hash_map_s const *map = iter->src_handle; + struct cx_hash_map_s const *map = iter->src_handle.c; struct cx_hash_map_element_s *elm = iter->elem_handle; - if (map->base.store_pointer) { + if (map->base.collection.store_pointer) { return *(void **) elm->data; } else { return elm->data; @@ -269,12 +269,10 @@ static void cx_hash_map_iter_next(void *it) { struct cx_iterator_s *iter = it; struct cx_hash_map_element_s *elm = iter->elem_handle; + struct cx_hash_map_s *map = iter->src_handle.m; // remove current element, if asked if (iter->base.remove) { - // obtain mutable pointer to the map - struct cx_mut_iterator_s *miter = it; - struct cx_hash_map_s *map = miter->src_handle; // clear the flag iter->base.remove = false; @@ -306,7 +304,6 @@ } // search the next bucket, if required - struct cx_hash_map_s const *map = iter->src_handle; while (elm == NULL && ++iter->slot < map->bucket_count) { elm = map->buckets[iter->slot]; } @@ -318,7 +315,7 @@ iter->kv_data.value = NULL; } else { iter->kv_data.key = &elm->key; - if (map->base.store_pointer) { + if (map->base.collection.store_pointer) { iter->kv_data.value = *(void **) elm->data; } else { iter->kv_data.value = elm->data; @@ -326,48 +323,41 @@ } } -static bool cx_hash_map_iter_flag_rm(void *it) { - struct cx_iterator_base_s *iter = it; - if (iter->mutating) { - iter->remove = true; - return true; - } else { - return false; - } -} - static CxIterator cx_hash_map_iterator( CxMap const *map, enum cx_map_iterator_type type ) { CxIterator iter; - iter.src_handle = map; - iter.base.valid = cx_hash_map_iter_valid; - iter.base.next = cx_hash_map_iter_next; + iter.src_handle.c = map; + iter.elem_count = map->collection.size; switch (type) { case CX_MAP_ITERATOR_PAIRS: + iter.elem_size = sizeof(CxMapEntry); iter.base.current = cx_hash_map_iter_current_entry; break; case CX_MAP_ITERATOR_KEYS: + iter.elem_size = sizeof(CxHashKey); iter.base.current = cx_hash_map_iter_current_key; break; case CX_MAP_ITERATOR_VALUES: + iter.elem_size = map->collection.elem_size; iter.base.current = cx_hash_map_iter_current_value; break; default: assert(false); } - iter.base.flag_removal = cx_hash_map_iter_flag_rm; + iter.base.valid = cx_hash_map_iter_valid; + iter.base.next = cx_hash_map_iter_next; iter.base.remove = false; iter.base.mutating = false; iter.slot = 0; iter.index = 0; - if (map->size > 0) { + if (map->collection.size > 0) { struct cx_hash_map_s *hash_map = (struct cx_hash_map_s *) map; struct cx_hash_map_element_s *elm = hash_map->buckets[0]; while (elm == NULL) { @@ -375,7 +365,7 @@ } iter.elem_handle = elm; iter.kv_data.key = &elm->key; - if (map->store_pointer) { + if (map->collection.store_pointer) { iter.kv_data.value = *(void **) elm->data; } else { iter.kv_data.value = elm->data; @@ -423,14 +413,14 @@ // initialize base members map->base.cl = &cx_hash_map_class; - map->base.allocator = allocator; + map->base.collection.allocator = allocator; if (itemsize > 0) { - map->base.store_pointer = false; - map->base.item_size = itemsize; + map->base.collection.store_pointer = false; + map->base.collection.elem_size = itemsize; } else { - map->base.store_pointer = true; - map->base.item_size = sizeof(void *); + map->base.collection.store_pointer = true; + map->base.collection.elem_size = sizeof(void *); } return (CxMap *) map; @@ -438,11 +428,11 @@ int cxMapRehash(CxMap *map) { struct cx_hash_map_s *hash_map = (struct cx_hash_map_s *) map; - if (map->size > ((hash_map->bucket_count * 3) >> 2)) { + if (map->collection.size > ((hash_map->bucket_count * 3) >> 2)) { - size_t new_bucket_count = (map->size * 5) >> 1; + size_t new_bucket_count = (map->collection.size * 5) >> 1; struct cx_hash_map_element_s **new_buckets = cxCalloc( - map->allocator, + map->collection.allocator, new_bucket_count, sizeof(struct cx_hash_map_element_s *) ); @@ -482,7 +472,7 @@ // assign result to the map hash_map->bucket_count = new_bucket_count; - cxFree(map->allocator, hash_map->buckets); + cxFree(map->collection.allocator, hash_map->buckets); hash_map->buckets = new_buckets; } return 0;