@@ -0,0 +1,83 @@
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
// vim:fileencoding=utf-8:foldmethod=marker
|
||||
|
||||
#ifndef MAP_H
|
||||
#define MAP_H
|
||||
|
||||
#include "../table/table.h"
|
||||
#include "../../../common/misc/misc_utils.h"
|
||||
#include "../../../common/platform/platform.h"
|
||||
|
||||
#ifdef WP_PLATFORM_CPP
|
||||
BEGIN_C_LINKAGE
|
||||
#endif // !WP_PLATFORM_CPP
|
||||
|
||||
typedef WpHashTable WpHashMap;
|
||||
|
||||
#ifdef WP_PLATFORM_CPP
|
||||
#define wpHashMap(KEY_TYPE, VALUE_TYPE, U8_STREAM_ENCODER, KEY_EQ_TEST, CAPACITY) \
|
||||
(WpHashMap{ \
|
||||
WP_HASH_TABLE_DEFAULT_HASHER, \
|
||||
U8_STREAM_ENCODER, \
|
||||
KEY_EQ_TEST, \
|
||||
wpArrayWithCapacity(KEY_TYPE, wpMiscUtilsU64RoundUpPow2(CAPACITY), WP_ARRAY_INIT_NONE), \
|
||||
wpArrayWithCapacity(VALUE_TYPE, wpMiscUtilsU64RoundUpPow2(CAPACITY), WP_ARRAY_INIT_NONE), \
|
||||
wpArrayWithCapacity(WpHashBucket, wpMiscUtilsU64RoundUpPow2(CAPACITY), WP_ARRAY_INIT_FILLED), \
|
||||
WP_HASH_TABLE_MAGIC, \
|
||||
wpMiscUtilsU64RoundUpPow2(CAPACITY) - 1, \
|
||||
0.0f, \
|
||||
true, \
|
||||
})
|
||||
#define wpHashMapCustomHasher(KEY_TYPE, VALUE_TYPE, HASHER, U8_STREAM_ENCODER, KEY_EQ_TEST, \
|
||||
CAPACITY) \
|
||||
(WpHashMap{ \
|
||||
HASHER, \
|
||||
U8_STREAM_ENCODER, \
|
||||
KEY_EQ_TEST, \
|
||||
wpArrayWithCapacity(KEY_TYPE, wpMiscUtilsU64RoundUpPow2(CAPACITY), WP_ARRAY_INIT_NONE), \
|
||||
wpArrayWithCapacity(VALUE_TYPE, wpMiscUtilsU64RoundUpPow2(CAPACITY), WP_ARRAY_INIT_NONE), \
|
||||
wpArrayWithCapacity(WpHashBucket, wpMiscUtilsU64RoundUpPow2(CAPACITY), WP_ARRAY_INIT_FILLED), \
|
||||
WP_HASH_TABLE_MAGIC, \
|
||||
wpMiscUtilsU64RoundUpPow2(CAPACITY) - 1, \
|
||||
0.0f, \
|
||||
true, \
|
||||
})
|
||||
#else
|
||||
#define wpHashMap(KEY_TYPE, VALUE_TYPE, U8_STREAM_ENCODER, KEY_EQ_TEST, CAPACITY) \
|
||||
((WpHashMap){ \
|
||||
.hasher = WP_HASH_TABLE_DEFAULT_HASHER, \
|
||||
.encoder = U8_STREAM_ENCODER, \
|
||||
.key_eq = KEY_EQ_TEST, \
|
||||
.keys = wpArrayWithCapacity(KEY_TYPE, wpMiscUtilsU64RoundUpPow2(CAPACITY), \
|
||||
WP_ARRAY_INIT_NONE), \
|
||||
.values = wpArrayWithCapacity(VALUE_TYPE, wpMiscUtilsU64RoundUpPow2(CAPACITY), \
|
||||
WP_ARRAY_INIT_NONE), \
|
||||
.buckets = wpArrayWithCapacity(WpHashBucket, wpMiscUtilsU64RoundUpPow2(CAPACITY), \
|
||||
WP_ARRAY_INIT_FILLED), \
|
||||
.magic = WP_HASH_TABLE_MAGIC, \
|
||||
.bucket_mask = wpMiscUtilsU64RoundUpPow2(CAPACITY) - 1, \
|
||||
.has_values = true, \
|
||||
})
|
||||
#define wpHashMapCustomHasher(KEY_TYPE, VALUE_TYPE, HASHER, U8_STREAM_ENCODER, KEY_EQ_TEST, \
|
||||
CAPACITY) \
|
||||
((WpHashMap){ \
|
||||
.hasher = HASHER, \
|
||||
.encoder = U8_STREAM_ENCODER, \
|
||||
.key_eq = KEY_EQ_TEST, \
|
||||
.keys = wpArrayWithCapacity(KEY_TYPE, wpMiscUtilsU64RoundUpPow2(CAPACITY), \
|
||||
WP_ARRAY_INIT_NONE), \
|
||||
.values = wpArrayWithCapacity(VALUE_TYPE, wpMiscUtilsU64RoundUpPow2(CAPACITY), \
|
||||
WP_ARRAY_INIT_NONE), \
|
||||
.buckets = wpArrayWithCapacity(WpHashBucket, wpMiscUtilsU64RoundUpPow2(CAPACITY), \
|
||||
WP_ARRAY_INIT_FILLED), \
|
||||
.magic = WP_HASH_TABLE_MAGIC, \
|
||||
.bucket_mask = wpMiscUtilsU64RoundUpPow2(CAPACITY) - 1, \
|
||||
.has_values = true, \
|
||||
})
|
||||
#endif
|
||||
|
||||
#define wpHashMapAlloc(KEY_TYPE, VALUE_TYPE, ALLOCATOR_PTR, U8_STREAM_ENCODER, KEY_EQ_TEST, \
|
||||
CAPACITY) \
|
||||
hashMapAlloc(ALLOCATOR_PTR, U8_STREAM_ENCODER, KEY_EQ_TEST, CAPACITY, sizeof(KEY_TYPE), \
|
||||
sizeof(VALUE_TYPE))
|
||||
#define wpHashMapCustomHasherAlloc(KEY_TYPE, VALUE_TYPE, ALLOCATOR_PTR, HASHER, U8_STREAM_ENCODER, \
|
||||
KEY_EQ_TEST, CAPACITY) \
|
||||
hashMapAllocWithCustomHasher(ALLOCATOR_PTR, HASHER, U8_STREAM_ENCODER, KEY_EQ_TEST, CAPACITY, \
|
||||
sizeof(KEY_TYPE), sizeof(VALUE_TYPE))
|
||||
#define wpHashMapKeys(KEY_TYPE, MAP_PTR) ((KEY_TYPE *)hashTableKeys(MAP_PTR, sizeof(KEY_TYPE)))
|
||||
#define wpHashMapValues(VALUE_TYPE, MAP_PTR) \
|
||||
((VALUE_TYPE *)hashTableValues(MAP_PTR, sizeof(VALUE_TYPE)))
|
||||
#define wpHashMapCapacity(MAP_PTR) hashTableCapacity(MAP_PTR)
|
||||
#define wpHashMapCount(MAP_PTR) hashTableCount(MAP_PTR)
|
||||
#define wpHashMapKeySize(MAP_PTR) hashTableKeySize(MAP_PTR)
|
||||
#define wpHashMapValueSize(MAP_PTR) hashTableValueSize(MAP_PTR)
|
||||
#define wpHashMapFind(KEY_TYPE, MAP_PTR, KEY_PTR) hashMapFind(MAP_PTR, KEY_PTR, sizeof(KEY_TYPE))
|
||||
#define wpHashMapInsertCapped(KEY_TYPE, VALUE_TYPE, MAP_PTR, KEY_PTR, VALUE_PTR) \
|
||||
hashMapInsertCapped(MAP_PTR, KEY_PTR, VALUE_PTR, sizeof(KEY_TYPE), sizeof(VALUE_TYPE))
|
||||
#define wpHashMapInsertOrUpdateCapped(KEY_TYPE, VALUE_TYPE, MAP_PTR, KEY_PTR, VALUE_PTR) \
|
||||
hashMapInsertOrUpdateCapped(MAP_PTR, KEY_PTR, VALUE_PTR, sizeof(KEY_TYPE), sizeof(VALUE_TYPE))
|
||||
#define wpHashMapUpdate(KEY_TYPE, VALUE_TYPE, MAP_PTR, KEY_PTR, VALUE_PTR) \
|
||||
hashMapUpdate(MAP_PTR, KEY_PTR, VALUE_PTR, sizeof(KEY_TYPE), sizeof(VALUE_TYPE))
|
||||
#define wpHashMapInsertAlloc(KEY_TYPE, VALUE_TYPE, ALLOCATOR_PTR, MAP_PTR, KEY_PTR, VALUE_PTR) \
|
||||
hashMapInsertAlloc(ALLOCATOR_PTR, MAP_PTR, KEY_PTR, VALUE_PTR, sizeof(KEY_TYPE), \
|
||||
sizeof(VALUE_TYPE))
|
||||
#define wpHashMapInsertOrUpdateAlloc(KEY_TYPE, VALUE_TYPE, ALLOCATOR_PTR, MAP_PTR, KEY_PTR, \
|
||||
VALUE_PTR) \
|
||||
hashMapInsertOrUpdateAlloc(ALLOCATOR_PTR, MAP_PTR, KEY_PTR, VALUE_PTR, sizeof(KEY_TYPE), \
|
||||
sizeof(VALUE_TYPE))
|
||||
#define wpHashMapRemove(KEY_TYPE, VALUE_TYPE, MAP_PTR, KEY_PTR) \
|
||||
hashMapRemove(MAP_PTR, KEY_PTR, sizeof(KEY_TYPE), sizeof(VALUE_TYPE))
|
||||
#define wpHashMapClear(KEY_TYPE, VALUE_TYPE, MAP_PTR) \
|
||||
hashTableClear(MAP_PTR, sizeof(KEY_TYPE), sizeof(VALUE_TYPE))
|
||||
#define wpHashMapDealloc(KEY_TYPE, VALUE_TYPE, ALLOCATOR_PTR, MAP_PTR) \
|
||||
hashTableDealloc(ALLOCATOR_PTR, MAP_PTR, sizeof(KEY_TYPE), sizeof(VALUE_TYPE))
|
||||
|
||||
WpHashMap hashMapAlloc(const WpAllocator *allocator, WpU8StreamEncoder encoder,
|
||||
WpKeyEqualTest key_eq, u64 capacity, u64 key_size, u64 value_size);
|
||||
WpHashMap hashMapAllocWithCustomHasher(const WpAllocator *allocator, WpHasher hasher,
|
||||
WpU8StreamEncoder encoder, WpKeyEqualTest key_eq,
|
||||
u64 capacity, u64 key_size, u64 value_size);
|
||||
WpHashLookupResult hashMapFind(WpHashMap *map, void *key, u64 key_size);
|
||||
void hashMapUpdate(WpHashMap *map, void *key, void *value, u64 key_size, u64 value_size);
|
||||
void hashMapInsertCapped(WpHashMap *map, void *key, void *value, u64 key_size, u64 value_size);
|
||||
void hashMapInsertOrUpdateCapped(WpHashMap *map, void *key, void *value, u64 key_size,
|
||||
u64 value_size);
|
||||
void hashMapInsertAlloc(const WpAllocator *allocator, WpHashMap *map, void *key,
|
||||
void *value, u64 key_size, u64 value_size);
|
||||
void hashMapInsertOrUpdateAlloc(const WpAllocator *allocator, WpHashMap *map, void *key,
|
||||
void *value, u64 key_size, u64 value_size);
|
||||
void hashMapRemove(WpHashMap *map, void *key, u64 key_size, u64 value_size);
|
||||
|
||||
#ifdef WP_PLATFORM_CPP
|
||||
END_C_LINKAGE
|
||||
#endif // !WP_PLATFORM_CPP
|
||||
|
||||
#endif // !MAP_H
|
||||
@@ -73,16 +73,16 @@ typedef WpHashTable WpHashSet;
|
||||
CAPACITY) \
|
||||
hashSetAllocWithCustomHasher(ALLOCATOR_PTR, HASHER, U8_STREAM_ENCODER, ITEM_EQ_TEST, CAPACITY, \
|
||||
sizeof(TYPE))
|
||||
#define wpHashSetItems(TYPE, SET_PTR) ((TYPE *)hashTableKeys(SET_PTR, sizeof(TYPE)))
|
||||
#define wpHashSetCapacity(SET_PTR) hashTableCapacity(SET_PTR)
|
||||
#define wpHashSetCount(SET_PTR) hashTableCount(SET_PTR)
|
||||
#define wpHashSetItemSize(SET_PTR) hashTableKeySize(SET_PTR)
|
||||
#define wpHashSetFind(TYPE, SET_PTR, ITEM_PTR) hashSetFind(SET_PTR, ITEM_PTR, sizeof(TYPE))
|
||||
#define wpHashSetInsertCapped(TYPE, SET_PTR, ITEM_PTR) \
|
||||
hashSetInsertCapped(SET_PTR, ITEM_PTR, sizeof(TYPE))
|
||||
#define wpHashSetInsertAlloc(TYPE, ALLOCATOR_PTR, SET_PTR, ITEM_PTR) \
|
||||
hashSetInsertAlloc(ALLOCATOR_PTR, SET_PTR, ITEM_PTR, sizeof(TYPE))
|
||||
#define wpHashSetRemove(TYPE, SET_PTR, ITEM_PTR) hashSetRemove(SET_PTR, ITEM_PTR, sizeof(TYPE))
|
||||
#define wpHashSetItems(TYPE, SET_PTR) ((TYPE *)hashTableKeys(SET_PTR, sizeof(TYPE)))
|
||||
#define wpHashSetCapacity(SET_PTR) hashTableCapacity(SET_PTR)
|
||||
#define wpHashSetCount(SET_PTR) hashTableCount(SET_PTR)
|
||||
#define wpHashSetItemSize(SET_PTR) hashTableKeySize(SET_PTR)
|
||||
#define wpHashSetClear(TYPE, SET_PTR) hashTableClear(SET_PTR, sizeof(TYPE), 0)
|
||||
#define wpHashSetDealloc(TYPE, ALLOCATOR_PTR, SET_PTR) \
|
||||
hashTableDealloc(ALLOCATOR_PTR, SET_PTR, sizeof(TYPE), 0)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "hash/hasher/siphash.c"
|
||||
#include "hash/table/table.c"
|
||||
#include "hash/set/set.c"
|
||||
#include "hash/map/map.c"
|
||||
#include "queue/queue.c"
|
||||
#include "stream/stream.c"
|
||||
#include "mem/allocator/mem_allocator.c"
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "hash/hasher/siphash.h"
|
||||
#include "hash/table/table.h"
|
||||
#include "hash/set/set.h"
|
||||
#include "hash/map/map.h"
|
||||
#include "queue/queue.h"
|
||||
#include "stream/stream.h"
|
||||
#include "mem/allocator/mem_allocator.h"
|
||||
|
||||
Reference in New Issue
Block a user