diff options
author | justanothercatgirl <sotov2070@gmail.com> | 2024-07-09 14:55:44 +0300 |
---|---|---|
committer | justanothercatgirl <sotov2070@gmail.com> | 2024-07-10 06:03:44 +0300 |
commit | 7f8be5510244568f5e71461eab56e4c77ad7f780 (patch) | |
tree | e0147bb0d4826150bcd85af00ea7c96b478d412d | |
parent | 5fa8a4e0787f23bac8810e41b331d85c540fbe21 (diff) |
added function to count elements in hash set
-rw-r--r-- | include/container.h | 42 | ||||
-rw-r--r-- | tests/hashset.c | 33 |
2 files changed, 53 insertions, 22 deletions
diff --git a/include/container.h b/include/container.h index b3294c4..6ac9054 100644 --- a/include/container.h +++ b/include/container.h @@ -2,10 +2,10 @@ #define JUSTANOTHERCATGIRL_HEADERS_CONTAINER #include <stdint.h> +#include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <stdarg.h> /* ----------------------------------------------------------------- */ /* -----------------UTILITY HEADER---------------------------------- */ @@ -312,9 +312,9 @@ struct hash_map_iter { struct linked_list_node* current_node; }; typedef struct hash_map_iter hmap_iter; -struct hash_map hmap_create(const size_t key_size, const size_t val_size, hmap_equal_fn eq, hmap_hash_fn hash); +struct hash_map hmap_new(const size_t key_size, const size_t val_size, hmap_equal_fn eq, hmap_hash_fn hash); /// copies data from pointers -struct hash_map hmap_create_from_buffer(size_t key_size, size_t val_size, hmap_equal_fn eq, hmap_hash_fn hash, const struct hmap_pair* buf, size_t buf_len); +struct hash_map hmap_new_from_buffer(size_t key_size, size_t val_size, hmap_equal_fn eq, hmap_hash_fn hash, const struct hmap_pair* buf, size_t buf_len); void hmap_free(struct hash_map* map); /// copy the contents of the pair into hash map (using `memcpy`). /// The element is left unchanged, the memory pointed to by `element` may be anything, from stack to FFI allocator @@ -377,8 +377,8 @@ typedef int(*hset_equal_fn)(const void*, const void*); typedef size_t(*hset_hash_fn)(const void*); struct hash_set { struct linked_list* buckets; - hmap_equal_fn eq; - hmap_hash_fn hash; + hset_equal_fn eq; + hset_hash_fn hash; size_t elem_size; }; enum hseti_cmp_res { @@ -393,9 +393,10 @@ struct hash_set_iter { struct linked_list_node* current_node; }; typedef struct hash_set_iter hset_iter; -struct hash_set hset_create(const size_t el_size, hset_equal_fn eq, hset_hash_fn hash); +struct hash_set hset_new(const size_t el_size, hset_equal_fn eq, hset_hash_fn hash); /// copies data from pointers -struct hash_set hset_create_from_buffer(size_t el_size, hset_equal_fn eq, hset_hash_fn hash, const void* buf, size_t buf_len); +struct hash_set hset_new_from_buffer(size_t el_size, hset_equal_fn eq, hset_hash_fn hash, const void* buf, size_t buf_len); +char hset_ok(struct hash_set set); void hset_free(struct hash_set* set); /// copy the contents of the pair into hash map (using `memcpy`). /// The element is left unchanged, the memory pointed to by `element` may be anything, from stack to FFI allocator @@ -409,6 +410,7 @@ void hset_remove(struct hash_set* set, void* elem); /// double the size of a hash set void hset_rehash(struct hash_set* set); void hset_rehash_to_size(struct hash_set* set, size_t new_size); +size_t hset_count(struct hash_set* set); /// initialize iterator `iter`. void hseti_begin(const struct hash_set* map, struct hash_set_iter* iter); @@ -1029,7 +1031,7 @@ void __hmap_ll_custom_free(void* data) { free(pair->val); free(data); } -struct hash_map hmap_create(const size_t key_size, const size_t val_size, hmap_equal_fn eq, hmap_hash_fn hash) { +struct hash_map hmap_new(const size_t key_size, const size_t val_size, hmap_equal_fn eq, hmap_hash_fn hash) { struct hash_map ret = { .buckets = array_new(struct linked_list, HMAP_INIT_SIZE), .key_size = key_size, @@ -1049,8 +1051,8 @@ struct hash_map hmap_create(const size_t key_size, const size_t val_size, hmap_e for (size_t i = 0; i < HMAP_INIT_SIZE; ++i) ret.buckets[i] = def; return ret; } -struct hash_map hmap_create_from_buffer(size_t key_size, size_t val_size, hmap_equal_fn eq, hmap_hash_fn hash, const struct hmap_pair* buf, size_t buf_len) { - struct hash_map ret = hmap_create(key_size, val_size, eq, hash); +struct hash_map hmap_new_from_buffer(size_t key_size, size_t val_size, hmap_equal_fn eq, hmap_hash_fn hash, const struct hmap_pair* buf, size_t buf_len) { + struct hash_map ret = hmap_new(key_size, val_size, eq, hash); hmap_rehash_to_size(&ret, buf_len / HMAP_MAX_BUCKET_SIZE); for (size_t i = 0; i < buf_len; ++i) hmap_insert_copy(&ret, buf[i]); return ret; @@ -1218,7 +1220,7 @@ char hmapi_end(const struct hash_map_iter* iter) { /* ----------------------------------------------------------------- */ -struct hash_set hset_create(const size_t el_size, hset_equal_fn eq, hset_hash_fn hash) { +struct hash_set hset_new(const size_t el_size, hset_equal_fn eq, hset_hash_fn hash) { struct hash_set ret = { .buckets = array_new(struct linked_list, HMAP_INIT_SIZE), .elem_size = el_size, @@ -1237,12 +1239,15 @@ struct hash_set hset_create(const size_t el_size, hset_equal_fn eq, hset_hash_fn for (size_t i = 0; i < HSET_INIT_SIZE; ++i) ret.buckets[i] = def; return ret; } -struct hash_set hset_create_from_buffer(size_t el_size, hset_equal_fn eq, hset_hash_fn hash, const void* buf, size_t buf_len) { - struct hash_set ret = hset_create(el_size, eq, hash); +struct hash_set hset_new_from_buffer(size_t el_size, hset_equal_fn eq, hset_hash_fn hash, const void* buf, size_t buf_len) { + struct hash_set ret = hset_new(el_size, eq, hash); hset_rehash_to_size(&ret, buf_len / HSET_MAX_BUCKET_SIZE); for (size_t i = 0; i < buf_len; ++i) hset_insert_copy(&ret, (byte*)buf + i * el_size); return ret; } +char hset_ok(struct hash_set set) { + return set.buckets != NULL && set.elem_size != 0; +} void hset_free(struct hash_set* set) { for (size_t i = 0; i < array_size(set->buckets); ++i) ll_free(set->buckets + i); array_free(set->buckets); @@ -1288,8 +1293,8 @@ void hset_rehash(struct hash_set* set) { void hset_rehash_to_size(struct hash_set* set, size_t new_size) { struct linked_list* new_buckets = array_new(struct linked_list, new_size); for (size_t i = 0; i < new_size; ++i) { - new_buckets[i] = ll_create(sizeof(struct hmap_pair)); - new_buckets[i].meta.free_function = __hmap_ll_custom_free; + new_buckets[i] = ll_create(set->elem_size); + /* new_buckets[i].meta.free_function = free; */ } struct hash_set_iter iter; for (hseti_begin(set, &iter); !hseti_end(&iter); hseti_next(&iter)) { @@ -1303,6 +1308,13 @@ void hset_rehash_to_size(struct hash_set* set, size_t new_size) { array_free(set->buckets); set->buckets = new_buckets; } +size_t hset_count(struct hash_set* set) { + size_t res = 0; + for (size_t i = 0; i < array_size(set->buckets); ++i) { + res += (set->buckets)[i].meta.assumed_size; + } + return res; +} void hseti_begin(const struct hash_set* set, struct hash_set_iter* iter) { memset(iter, 0, sizeof(struct hash_map_iter)); diff --git a/tests/hashset.c b/tests/hashset.c index d98e317..b438d22 100644 --- a/tests/hashset.c +++ b/tests/hashset.c @@ -22,9 +22,17 @@ struct user user(int id, const char* name) { void printuser(struct user* u) { printf("(struct user) {.id=%i, .name=\"%s\"};\n", u->id, u->name); } +void printhset(struct hash_set* set) { + printf("hash set at %p:\n", set); + hset_iter iter; + for (hseti_begin(set, &iter); !hseti_end(&iter); hseti_next(&iter)) { + struct user* u = hseti_get(&iter); + printuser(u); + } +} int main(void) { - struct hash_set set = hset_create(sizeof(struct user), (hset_equal_fn)user_eq, (hset_hash_fn)user_hash); + struct hash_set set = hset_new(sizeof(struct user), (hset_equal_fn)user_eq, (hset_hash_fn)user_hash); struct user u0 = user(0, "Jhon"); struct user u1 = user(1, "John"); struct user u2 = user(2, "John"); @@ -41,13 +49,24 @@ int main(void) { hset_insert_copy(&set, &ud); hset_insert_copy(&set, &ud); hset_insert_copy(&set, &ud); - - hset_iter iter; - for (hseti_begin(&set, &iter); !hseti_end(&iter); hseti_next(&iter)) { - struct user* u = hseti_get(&iter); - printuser(u); + hset_remove(&set, &ud); + hset_remove(&set, &ud); + hset_remove(&set, &ud); + hset_remove(&set, &ud); + hset_remove(&set, &ud); + hset_remove(&set, &ud); + hset_remove(&set, &ud); + hset_remove(&set, &uw); + for (int i = 100; i < 160; ++i) { + struct user tmp = user(i, ""); + hset_insert_copy(&set, &tmp); } + hset_rehash_to_size(&set, 1000); + printf("count of elements in set: %zu (supposed to be 62)\n", hset_count(&set)); + int retval; + if (hset_count(&set) == 62) retval = EXIT_SUCCESS; + else retval = EXIT_FAILURE; hset_free(&set); - return 0; + return retval; } |