6 #include "system/stacktrace.h"
7 #include "system/nth_alloc.h"
21 static uint64_t fnv1(const char *data, size_t size)
23 uint64_t hash = 0xcbf29ce484222325;
25 for (size_t i = 0; i < size; ++i) {
26 hash = hash * 0x100000001b3;
27 hash = hash ^ (uint64_t) data[i];
33 HashSet *create_hashset(size_t element_size, size_t n)
40 HashSet *hash_set = PUSH_LT(lt, nth_alloc(sizeof(HashSet)), free);
41 if (hash_set == NULL) {
48 hash_set->element_size = element_size;
50 hash_set->buckets = PUSH_LT(lt, nth_calloc(n, sizeof(Dynarray*)), free);
51 if (hash_set->buckets == NULL) {
55 for (size_t i = 0; i < n; ++i) {
56 hash_set->buckets[i] = PUSH_LT(
58 create_dynarray(element_size),
60 if (hash_set->buckets[i] == NULL) {
65 hash_set->view = PUSH_LT(lt, create_dynarray(element_size), destroy_dynarray);
66 if (hash_set->view == NULL) {
73 void destroy_hashset(HashSet *hashset)
75 trace_assert(hashset);
76 RETURN_LT0(hashset->lt);
79 int hashset_insert(HashSet *hashset, const void *element)
81 trace_assert(hashset);
82 trace_assert(element);
84 const uint64_t hash = fnv1(element, hashset->element_size);
85 const size_t i = hash % hashset->n;
87 if (!dynarray_contains(hashset->buckets[i], element)) {
88 dynarray_push(hashset->buckets[i], element);
95 bool hashset_contains(HashSet *hashset, const void *element)
97 trace_assert(hashset);
98 trace_assert(element);
100 const uint64_t hash = fnv1(element, hashset->element_size);
101 const size_t i = hash % hashset->n;
103 return dynarray_contains(hashset->buckets[i], element);
106 void hashset_clear(HashSet *hashset)
108 trace_assert(hashset);
110 for (size_t i = 0; i < hashset->n; ++i) {
111 dynarray_clear(hashset->buckets[i]);
116 size_t hashset_count(HashSet *hashset)
119 trace_assert(hashset);
120 return hashset->count;
123 void *hashset_values(HashSet *hashset)
125 dynarray_clear(hashset->view);
127 for (size_t i = 0; i < hashset->n; ++i) {
128 size_t n = dynarray_count(hashset->buckets[i]);
129 char *bucket = dynarray_data(hashset->buckets[i]);
131 for (size_t j = 0; j < n; ++j) {
132 dynarray_push(hashset->view, bucket + j * hashset->element_size);
136 return dynarray_data(hashset->view);