// 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); } }