#include "config.h" #include #include #include #include #include #include #include #include #include #include "hash.h" #include "logerr.h" #include "tree.h" #include "util.h" #include "vector.h" #include "set.h" struct Set { const struct Vector *table; const size_t value_size; size_t count; }; int set_new(const size_t value_size, const struct Set **const out) { int rc = -1; const struct Set *ret = NULL; const struct Vector *table = NULL; const struct Tree *tree_template = NULL; ret = malloc(sizeof(*ret)); if (ret == NULL) { logerr("malloc(): %s", strerror(errno)); goto out; } if (vector_new(sizeof(struct Tree *), &table)) { logerr("vector_new()"); goto out; } if (tree_new(value_size, &tree_template)) { logerr("tree_new()"); goto out; } for (size_t _i = 0U; _i < vector_capacity(table); _i++) { assert(vector_push_back(table, tree_template) == 0); } memcpy((void *)ret, &(struct Set) { .table = table, .value_size = value_size, .count = 0U, }, sizeof(*ret)); *out = ret; rc = 0; out: if (tree_template != NULL) { tree_free(&tree_template); } if (rc) { if (table != NULL) { vector_free(&table); } if (ret != NULL) { freeit((void *)&ret); } } return rc; } void set_free(const struct Set **const s) { assert((*s) != NULL); const struct Vector *table = (*s)->table; vector_free(&table); freeit((void *)s); } int set_add(const struct Set *const s, const void *const value) { int rc = -1; uint8_t hash_bytes[HASH_OUTPUT_LENGTH]; hash(s->value_size, value, hash_bytes); const uint64_t hash_value = endiannessbs_from_le64(hash_bytes); const size_t idx = hash_value % vector_capacity(s->table); const struct Tree *slot; assert(vector_nth(s->table, idx, (void *)&slot) == 0); if (tree_add(slot, value)) { logerr("tree_add()"); goto out; } rc = 0; out: return rc; }