// vim:fileencoding=utf-8:foldmethod=marker #include "map.h" #include "../table/table.h" WpHashMap hashMapAlloc(const WpAllocator *allocator, WpU8StreamEncoder encoder, WpKeyEqualTest key_eq, u64 capacity, u64 key_size, u64 value_size) { return hashMapAllocWithCustomHasher(allocator, WP_HASH_TABLE_DEFAULT_HASHER, encoder, key_eq, capacity, key_size, value_size); } WpHashMap hashMapAllocWithCustomHasher(const WpAllocator *allocator, WpHasher hasher, WpU8StreamEncoder encoder, WpKeyEqualTest key_eq, u64 capacity, u64 key_size, u64 value_size) { WpHashMap map = {0}; hashTableAlloc(allocator, &map, hasher, encoder, key_eq, capacity, key_size, value_size, true); return map; } WpHashLookupResult hashMapFind(WpHashMap *map, void *key, u64 key_size) { u64 hash = hashTableCalcHash(map, key, key_size); WpHashBucketRef ref = hashTableBucketRef(map, hash); return hashTableLookup(map, key, ref, key_size); } void hashMapUpdate(WpHashMap *map, void *key, void *value, u64 key_size, u64 value_size) { WpHashLookupResult result = hashMapFind(map, key, key_size); if (result.found) { hashTableUpdate(map, value, result.ref, value_size); } } void hashMapInsertCapped(WpHashMap *map, void *key, void *value, u64 key_size, u64 value_size) { WpHashLookupResult result = hashMapFind(map, key, key_size); if (!result.found && map->load_factor < WP_HASH_MAX_LOAD_FACTOR) { hashTableInsert(map, key, value, result.ref, key_size, value_size); } } void hashMapInsertOrUpdateCapped(WpHashMap *map, void *key, void *value, u64 key_size, u64 value_size) { WpHashLookupResult result = hashMapFind(map, key, key_size); if (result.found) { hashTableUpdate(map, value, result.ref, value_size); } else if (map->load_factor < WP_HASH_MAX_LOAD_FACTOR) { hashTableInsert(map, key, value, result.ref, key_size, value_size); } } void hashMapInsertAlloc(const WpAllocator *allocator, WpHashMap *map, void *key, void *value, u64 key_size, u64 value_size) { WpHashLookupResult result = hashMapFind(map, key, key_size); if (!result.found) { if (map->load_factor >= WP_HASH_MAX_LOAD_FACTOR) { hashTableGrow(allocator, map, key_size, value_size); // Rerun key lookup after growing result = hashMapFind(map, key, key_size); } hashTableInsert(map, key, value, result.ref, key_size, value_size); } } void hashMapInsertOrUpdateAlloc(const WpAllocator *allocator, WpHashMap *map, void *key, void *value, u64 key_size, u64 value_size) { WpHashLookupResult result = hashMapFind(map, key, key_size); if (result.found) { hashTableUpdate(map, value, result.ref, value_size); } else { if (map->load_factor >= WP_HASH_MAX_LOAD_FACTOR) { hashTableGrow(allocator, map, key_size, value_size); // Rerun key lookup after growing result = hashMapFind(map, key, key_size); } hashTableInsert(map, key, value, result.ref, key_size, value_size); } } void hashMapRemove(WpHashMap *map, void *key, u64 key_size, u64 value_size) { WpHashLookupResult result = hashMapFind(map, key, key_size); if (result.found) { hashTableRemove(map, result.ref, key_size, value_size); } }