aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjustanothercatgirl <sotov2070@gmail.com>2024-07-09 14:55:44 +0300
committerjustanothercatgirl <sotov2070@gmail.com>2024-07-10 06:03:44 +0300
commit7f8be5510244568f5e71461eab56e4c77ad7f780 (patch)
treee0147bb0d4826150bcd85af00ea7c96b478d412d
parent5fa8a4e0787f23bac8810e41b331d85c540fbe21 (diff)
added function to count elements in hash set
-rw-r--r--include/container.h42
-rw-r--r--tests/hashset.c33
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;
}