52 lines
1.9 KiB
C
52 lines
1.9 KiB
C
// vim:fileencoding=utf-8:foldmethod=marker
|
|
|
|
#include "set.h"
|
|
#include "../table/table.h"
|
|
|
|
WpHashSet hashSetAlloc(const WpAllocator *allocator, WpU8StreamEncoder encoder, WpKeyEqualTest key_eq,
|
|
u64 capacity, u64 key_size) {
|
|
return hashSetAllocWithCustomHasher(allocator, WP_HASH_TABLE_DEFAULT_HASHER, encoder, key_eq,
|
|
capacity, key_size);
|
|
}
|
|
|
|
WpHashSet hashSetAllocWithCustomHasher(const WpAllocator *allocator, WpHasher hasher,
|
|
WpU8StreamEncoder encoder, WpKeyEqualTest key_eq, u64 capacity,
|
|
u64 key_size) {
|
|
WpHashSet set = {0};
|
|
hashTableAlloc(allocator, &set, hasher, encoder, key_eq, capacity, key_size, 0, false);
|
|
return set;
|
|
}
|
|
|
|
WpHashLookupResult hashSetFind(WpHashSet *set, void *item, u64 item_size) {
|
|
u64 hash = hashTableCalcHash(set, item, item_size);
|
|
WpHashBucketRef ref = hashTableBucketRef(set, hash);
|
|
return hashTableLookup(set, item, ref, item_size);
|
|
}
|
|
|
|
void hashSetInsertCapped(WpHashSet *set, void *item, u64 item_size) {
|
|
WpHashLookupResult result = hashSetFind(set, item, item_size);
|
|
if (!result.found && set->load_factor < WP_HASH_MAX_LOAD_FACTOR) {
|
|
hashTableInsert(set, item, NULL, result.ref, item_size, 0);
|
|
}
|
|
}
|
|
|
|
void hashSetInsertAlloc(const WpAllocator *allocator, WpHashSet *set, void *item, u64 item_size) {
|
|
WpHashLookupResult result = hashSetFind(set, item, item_size);
|
|
if (!result.found) {
|
|
if (set->load_factor >= WP_HASH_MAX_LOAD_FACTOR) {
|
|
hashTableGrow(allocator, set, item_size, 0);
|
|
// Rerun item lookup after growing
|
|
result = hashSetFind(set, item, item_size);
|
|
}
|
|
|
|
hashTableInsert(set, item, NULL, result.ref, item_size, 0);
|
|
}
|
|
}
|
|
|
|
void hashSetRemove(WpHashSet *set, void *item, u64 item_size) {
|
|
WpHashLookupResult result = hashSetFind(set, item, item_size);
|
|
if (result.found) {
|
|
hashTableRemove(set, result.ref, item_size, 0);
|
|
}
|
|
}
|