Compare commits

...
10 Commits
Author SHA1 Message Date
abdelrahman fe5f13d8ce Make wpLogMakeLogger compile time constant
Release / release (push) Successful in 4s
2026-10-05 01:28:21 +01:00
abdelrahman df03b48319 Update allocator interface
Release / release (push) Successful in 4s
2026-09-30 22:24:46 +01:00
abdelrahman cd93b2e479 Set minimum log length to 128
Release / release (push) Successful in 4s
2026-09-30 21:21:27 +01:00
abdelrahman 66acbaad9e Release v2.5.0
Release / release (push) Successful in 3s
2026-09-24 00:53:36 +01:00
abdelrahman 180292289d Add hash map implementation
Release / release (push) Successful in 3s
2026-09-24 00:52:43 +01:00
abdelrahman 68640dc5e2 Add hash set implementation
Release / release (push) Successful in 4s
2026-09-23 22:34:23 +01:00
Abdelrahman Said 20e890964f Add hash table for default hasher
Release / release (push) Successful in 3s
2026-09-23 00:21:51 +01:00
Abdelrahman Said c215486442 Restructure hasher implementation
Release / release (push) Successful in 3s
2026-09-23 00:02:37 +01:00
Abdelrahman Said 9881c0ac9a Update hasher data to context
Release / release (push) Successful in 4s
2026-09-22 21:47:46 +01:00
abdelrahman 17be4841e6 Update siphash comment
Release / release (push) Successful in 3s
2026-09-22 00:57:46 +01:00
34 changed files with 1655 additions and 214 deletions

No files matched your search

+34 -7
View File
@@ -7,18 +7,45 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
## [3.1.0] - 2026-10-05
### Changed
- `wpLogMakeLogger` to be compile time constant
## [3.0.0] - 2026-09-30
### Added
- `temp_begin` and `temp_end` ops to the `WpAllocator` interface
### Removed
- `wpMemArenaAllocatorTempBegin` and `wpMemArenaAllocatorTempEnd`
## [2.6.0] - 2026-09-30
### Changed
- Minimum length for log messages from 32 to 128
## [2.5.0] - 2026-09-24
### Added ### Added
- `wpMiscUtilsRotl64` utility - `wpMiscUtilsRotl64` utility
- `WpHasher` interface - `WpHasher` interface
- `wpCustomHasher` constructor for custom hasher with user-defined context
- `wpHasherGetHash128` and `wpHasherGetHash64` utilities - `wpHasherGetHash128` and `wpHasherGetHash64` utilities
- `wpMur3HasherData` to setup the MurmurHash3 data struct - `wpX64Mur3Hasher` and `wpX64Mur3HasherWithSeed` constructors for the hasher interface
- `wpX64Mur3Hasher` constructor for the hasher interface - `wpX64Mur3GetHash128` implementation for the x64 128-bit variant of the MurmurHash3 algorithm
- `wpX64Mur3Hasher128` implementation for the x64 128-bit variant of the MurmurHash3 algorithm - `wpSip24Hasher`, `wpSip48Hasher`, `wpSip24HasherWithKey` and `wpSip48HasherWithKey` constructors for the hasher interface
- `wpSip24HasherData` and `wpSip48HasherData` to setup the siphash data structs for the different variants - `wpSipGetHash128` implementation for the 128 variant of siphash
- `wpSipHasher` constructor for the hasher interface - `wpHashSet`, `wpHashSetCustomHasher`, `wpHashSetAlloc` and `wpHashSetCustomHasherAlloc` constructors
- `wpSipHasher128` implementation for the 128 variant of siphash - `wpHashSetFind`, `wpHashSetInsertCapped`, `wpHashSetInsertAlloc`, `wpHashSetRemove`, `wpHashSetItems`, `wpHashSetCapacity`, `wpHashSetCount`, `wpHashSetItemSize`, `wpHashSetClear` and `wpHashSetDealloc` utilities
- Add `wpU8Const`, `wpU16Const`, `wpU32Const`, `wpU64Const`, `wpI8Const`, `wpI16Const`, `wpI32Const`, and `wpI64Const` - `wpHashMap`, `wpHashMapCustomHasher`, `wpHashMapAlloc` and `wpHashMapCustomHasherAlloc` constructors
- `wpHashMapKeys`, `wpHashMapValues`, `wpHashMapCapacity`, `wpHashMapCount`, `wpHashMapKeySize`, `wpHashMapValueSize`, `wpHashMapFind`, `wpHashMapInsertCapped`, `wpHashMapInsertOrUpdateCapped`, `wpHashMapUpdate`, `wpHashMapInsertAlloc`, `wpHashMapInsertOrUpdateAlloc`, `wpHashMapRemove`, `wpHashMapClear` and `wpHashMapDealloc` utilities
- `wpU8Const`, `wpU16Const`, `wpU32Const`, `wpU64Const`, `wpI8Const`, `wpI16Const`, `wpI32Const`, and `wpI64Const` aliases
- `wpPrngXorshiftInitWithSeed` to allow for user control with PRNG - `wpPrngXorshiftInitWithSeed` to allow for user control with PRNG
- `wpPrngXorshift256InRange`, `wpPrngXorshift256ssInRange`, `wpPrngXorshift256pInRange`, `wpPrngXorshift256Choice`, `wpPrngXorshift256ssChoice` and `wpPrngXorshift256pChoice` utilities - `wpPrngXorshift256InRange`, `wpPrngXorshift256ssInRange`, `wpPrngXorshift256pInRange`, `wpPrngXorshift256Choice`, `wpPrngXorshift256ssChoice` and `wpPrngXorshift256pChoice` utilities
- `WpSplitmix64State` - `WpSplitmix64State`
+1 -1
View File
@@ -1 +1 @@
2.4.0 3.1.0
+14 -4
View File
@@ -3,13 +3,23 @@
#include "hasher.h" #include "hasher.h"
#include "../../../common/assert/assert.h" #include "../../../common/assert/assert.h"
WpU128Hash wpHasherGetHash128(const WpHasher *hasher, WpU8Stream *stream) { WpHasher wpCustomHasher(WpHashFunc func, void *ctx) {
return (WpHasher){
.func = func,
.ctx = (WpHasherCtx){
.type = WP_HASHER_CTX_USER_DEFINED,
.user = ctx,
}
};
}
WpU128 wpHasherGetHash128(const WpHasher *hasher, WpU8Stream *stream) {
wpDebugAssert(hasher != NULL && stream != NULL, "hasher and stream shouldn't be NULL"); wpDebugAssert(hasher != NULL && stream != NULL, "hasher and stream shouldn't be NULL");
return hasher->func(stream, hasher->data); return hasher->func(stream, hasher->ctx);
} }
u64 wpHasherGetHash64(const WpHasher *hasher, WpU8Stream *stream) { u64 wpHasherGetHash64(const WpHasher *hasher, WpU8Stream *stream) {
wpDebugAssert(hasher != NULL && stream != NULL, "hasher and stream shouldn't be NULL"); wpDebugAssert(hasher != NULL && stream != NULL, "hasher and stream shouldn't be NULL");
WpU128Hash result = hasher->func(stream, hasher->data); WpU128 result = hasher->func(stream, hasher->ctx);
return result.hash[0] ^ result.hash[1]; return result.value[0] ^ result.value[1];
} }
+31 -6
View File
@@ -4,23 +4,48 @@
#define HASHER_H #define HASHER_H
#include "../../stream/stream.h" #include "../../stream/stream.h"
#include "../../../common/aliases/aliases.h"
#ifdef WP_PLATFORM_CPP #ifdef WP_PLATFORM_CPP
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // !WP_PLATFORM_CPP #endif // !WP_PLATFORM_CPP
typedef struct WpU128Hash { typedef struct WpU128 {
u64 hash[2]; u64 value[2];
} WpU128Hash; } WpU128;
typedef WpU128Hash (*WpHashFunc)(WpU8Stream *stream, void *hasher_data); typedef enum WpHasherCtxType {
WP_HASHER_CTX_MURMUR3,
WP_HASHER_CTX_SIPHASH,
WP_HASHER_CTX_USER_DEFINED,
COUNT_HASHER_CTX,
} WpHasherCtxType;
typedef struct WpSiphashCtx {
WpU128 key;
u64 compression;
u64 finalisation;
} WpSiphashCtx;
typedef struct WpHasherCtx {
WpHasherCtxType type;
union {
WpSiphashCtx siphash;
void *user;
u32 murmur3;
};
} WpHasherCtx;
typedef WpU128 (*WpHashFunc)(WpU8Stream *stream, WpHasherCtx ctx);
typedef struct WpHasher { typedef struct WpHasher {
WpHashFunc func; WpHashFunc func;
void *data; WpHasherCtx ctx;
} WpHasher; } WpHasher;
WpU128Hash wpHasherGetHash128(const WpHasher *hasher, WpU8Stream *stream); WpHasher wpCustomHasher(WpHashFunc func, void *ctx);
WpU128 wpHasherGetHash128(const WpHasher *hasher, WpU8Stream *stream);
u64 wpHasherGetHash64(const WpHasher *hasher, WpU8Stream *stream); u64 wpHasherGetHash64(const WpHasher *hasher, WpU8Stream *stream);
#ifdef WP_PLATFORM_CPP #ifdef WP_PLATFORM_CPP
+23 -11
View File
@@ -5,22 +5,34 @@
#include "../../../common/aliases/aliases.h" #include "../../../common/aliases/aliases.h"
#include "../../../common/assert/assert.h" #include "../../../common/assert/assert.h"
#include "../../../common/misc/misc_utils.h" #include "../../../common/misc/misc_utils.h"
#include "../../../prng/xorshift/xorshift.h"
wp_intern inline void validateMur3HasherData(const WpMur3HasherData *io); wp_intern inline void validateMur3HasherCtx(const WpHasherCtx *ctx);
wp_intern inline u64 fmix64(u64 k); wp_intern inline u64 fmix64(u64 k);
WpHasher wpX64Mur3Hasher(WpMur3HasherData *data) { WpHasher wpX64Mur3Hasher(void) {
return (WpHasher){ .func = wpX64Mur3Hasher128, .data = (void *)data }; WpXor256State state = wpPrngXorshiftInit();
u32 seed = (u32)wpPrngXorshift256(&state);
return wpX64Mur3HasherWithSeed(seed);
} }
WpU128Hash wpX64Mur3Hasher128(WpU8Stream *bytes, void *hasher_io) { WpHasher wpX64Mur3HasherWithSeed(u32 seed) {
WpMur3HasherData *io = (WpMur3HasherData *)hasher_io; return (WpHasher){
validateMur3HasherData(io); .func = wpX64Mur3GetHash128,
.ctx = (WpHasherCtx){
.type = WP_HASHER_CTX_MURMUR3,
.murmur3 = seed,
},
};
}
WpU128 wpX64Mur3GetHash128(WpU8Stream *bytes, WpHasherCtx ctx) {
validateMur3HasherCtx(&ctx);
const i32 nblocks = (bytes->count * bytes->item_size) / 16; const i32 nblocks = (bytes->count * bytes->item_size) / 16;
u64 h1 = io->seed; u64 h1 = ctx.murmur3;
u64 h2 = io->seed; u64 h2 = ctx.murmur3;
const u64 c1 = wpU64Const(0x87c37b91114253d5); const u64 c1 = wpU64Const(0x87c37b91114253d5);
const u64 c2 = wpU64Const(0x4cf5ad432745937f); const u64 c2 = wpU64Const(0x4cf5ad432745937f);
@@ -96,11 +108,11 @@ WpU128Hash wpX64Mur3Hasher128(WpU8Stream *bytes, void *hasher_io) {
h1 += h2; h1 += h2;
h2 += h1; h2 += h1;
return (WpU128Hash){ .hash = { [0] = h1, [1] = h2 } }; return (WpU128){ .value = { [0] = h1, [1] = h2 } };
} }
wp_intern inline void validateMur3HasherData(const WpMur3HasherData *data) { wp_intern inline void validateMur3HasherCtx(const WpHasherCtx *ctx) {
wpRuntimeAssert(data->magic == WP_MUR3_HASHER_MAGIC, "Invalid Murmur3 hash data"); wpRuntimeAssert(ctx->type == WP_HASHER_CTX_MURMUR3, "Invalid Murmur3 hash context");
} }
wp_intern inline u64 fmix64(u64 k) { wp_intern inline u64 fmix64(u64 k) {
+3 -15
View File
@@ -17,21 +17,9 @@
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // !WP_PLATFORM_CPP #endif // !WP_PLATFORM_CPP
#define WP_MUR3_HASHER_MAGIC wpU64Const(0x57504d4841534833) WpHasher wpX64Mur3Hasher(void);
WpHasher wpX64Mur3HasherWithSeed(u32 seed);
typedef struct WpMur3HasherData { WpU128 wpX64Mur3GetHash128(WpU8Stream *bytes, WpHasherCtx ctx);
u64 magic;
u32 seed;
} WpMur3HasherData;
#ifdef WP_PLATFORM_CPP
#define wpMur3HasherData(SEED) (WpMur3HasherData{WP_MUR3_HASHER_MAGIC, SEED})
#else
#define wpMur3HasherData(SEED) ((WpMur3HasherData){ .magic = WP_MUR3_HASHER_MAGIC, .seed = SEED })
#endif
WpHasher wpX64Mur3Hasher(WpMur3HasherData *data);
WpU128Hash wpX64Mur3Hasher128(WpU8Stream *bytes, void *hasher_io);
#ifdef WP_PLATFORM_CPP #ifdef WP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE
+51 -24
View File
@@ -5,10 +5,11 @@
#include "../../../common/aliases/aliases.h" #include "../../../common/aliases/aliases.h"
#include "../../../common/assert/assert.h" #include "../../../common/assert/assert.h"
#include "../../../common/misc/misc_utils.h" #include "../../../common/misc/misc_utils.h"
#include "../../../prng/xorshift/xorshift.h"
wp_intern inline void siphash(WpStream *bytes, const WpSipHasherData *params, u8 *out, u64 outlen); wp_intern inline void siphash(WpStream *bytes, const WpHasherCtx *ctx, u8 *out, u64 outlen);
wp_intern inline void validateSipHasherData(const WpSipHasherData *io); wp_intern inline void validateSipHasherCtx(const WpHasherCtx *ctx);
wp_intern inline b8 checkRounds(const WpSipHasherData *params); wp_intern inline b8 checkRounds(const WpHasherCtx *ctx);
#define _u32To8LE(p, v) \ #define _u32To8LE(p, v) \
(p)[0] = (u8)((v)); \ (p)[0] = (u8)((v)); \
@@ -44,24 +45,50 @@ wp_intern inline b8 checkRounds(const WpSipHasherData *params);
v2 = wpMiscUtilsRotl64(v2, 32); \ v2 = wpMiscUtilsRotl64(v2, 32); \
} while (0) } while (0)
WpHasher wpSipHasher(WpSipHasherData *data) { WpHasher wpSip24Hasher(void) {
return (WpHasher){ .func = wpSipHasher128, .data = (void *)data }; WpXor256State state = wpPrngXorshiftInit();
WpU128 key = { .value = { wpPrngXorshift256(&state), wpPrngXorshift256(&state) } };
return wpSip24HasherWithKey(key);
} }
WpU128Hash wpSipHasher128(WpStream *bytes, void *hasher_data) { WpHasher wpSip48Hasher(void) {
WpSipHasherData *data = (WpSipHasherData *)hasher_data; WpXor256State state = wpPrngXorshiftInit();
validateSipHasherData(data); WpU128 key = { .value = { wpPrngXorshift256(&state), wpPrngXorshift256(&state) } };
WpU128Hash output = {0}; return wpSip48HasherWithKey(key);
siphash(bytes, data, (u8 *)&output.hash, sizeof(u64) * 2); }
WpHasher wpSip24HasherWithKey(WpU128 key) {
return (WpHasher){
.func = wpSipGetHash128,
.ctx = (WpHasherCtx){
.type = WP_HASHER_CTX_SIPHASH,
.siphash = (WpSiphashCtx){ .key = key, .compression = 2, .finalisation = 4 },
},
};
}
WpHasher wpSip48HasherWithKey(WpU128 key) {
return (WpHasher){
.func = wpSipGetHash128,
.ctx = (WpHasherCtx){
.type = WP_HASHER_CTX_SIPHASH,
.siphash = (WpSiphashCtx){ .key = key, .compression = 4, .finalisation = 8 },
},
};
}
WpU128 wpSipGetHash128(WpStream *bytes, WpHasherCtx ctx) {
validateSipHasherCtx(&ctx);
WpU128 output = {0};
siphash(bytes, &ctx, (u8 *)&output.value, sizeof(u64) * 2);
return output; return output;
} }
/** /**
* Implementation of the 128-variant of the siphash algorithm * Implementation of the 128-variant of the siphash algorithm
*/ */
wp_intern inline void siphash(WpStream *bytes, const WpSipHasherData *params, u8 *out, wp_intern inline void siphash(WpStream *bytes, const WpHasherCtx *ctx, u8 *out, u64 outlen) {
u64 outlen) { const u8 *kk = (const u8 *)&ctx->siphash.key;
const u8 *kk = (const u8 *)&params->key;
u64 inlen = bytes->count * bytes->item_size; u64 inlen = bytes->count * bytes->item_size;
wpRuntimeAssert(outlen == 16, "outlen should be 16"); wpRuntimeAssert(outlen == 16, "outlen should be 16");
@@ -89,7 +116,7 @@ wp_intern inline void siphash(WpStream *bytes, const WpSipHasherData *params, u8
m = _u8To64LE(data); m = _u8To64LE(data);
v3 ^= m; v3 ^= m;
for (i = 0; i < params->compression; ++i) { for (i = 0; i < ctx->siphash.compression; ++i) {
_sipRound; _sipRound;
} }
@@ -125,7 +152,7 @@ wp_intern inline void siphash(WpStream *bytes, const WpSipHasherData *params, u8
v3 ^= b; v3 ^= b;
for (i = 0; i < params->compression; ++i) { for (i = 0; i < ctx->siphash.compression; ++i) {
_sipRound; _sipRound;
} }
@@ -133,7 +160,7 @@ wp_intern inline void siphash(WpStream *bytes, const WpSipHasherData *params, u8
v2 ^= 0xee; v2 ^= 0xee;
for (i = 0; i < params->finalisation; ++i) { for (i = 0; i < ctx->siphash.finalisation; ++i) {
_sipRound; _sipRound;
} }
@@ -142,7 +169,7 @@ wp_intern inline void siphash(WpStream *bytes, const WpSipHasherData *params, u8
v1 ^= 0xdd; v1 ^= 0xdd;
for (i = 0; i < params->finalisation; ++i) { for (i = 0; i < ctx->siphash.finalisation; ++i) {
_sipRound; _sipRound;
} }
@@ -150,14 +177,14 @@ wp_intern inline void siphash(WpStream *bytes, const WpSipHasherData *params, u8
_u64To8LE(out + 8, b); _u64To8LE(out + 8, b);
} }
wp_intern inline void validateSipHasherData(const WpSipHasherData *data) { wp_intern inline void validateSipHasherCtx(const WpHasherCtx *ctx) {
b8 magic_match = data->magic == WP_SIP_HASHER_MAGIC; b8 magic_match = ctx->type == WP_HASHER_CTX_SIPHASH;
b8 rounds = checkRounds(data); b8 rounds = checkRounds(ctx);
wpRuntimeAssert(magic_match && rounds, "Invalid Siphash data"); wpRuntimeAssert(magic_match && rounds, "Invalid Siphash context");
} }
wp_intern inline b8 checkRounds(const WpSipHasherData *data) { wp_intern inline b8 checkRounds(const WpHasherCtx *ctx) {
b8 rounds24 = data->compression == 2 && data->finalisation == 4; b8 rounds24 = ctx->siphash.compression == 2 && ctx->siphash.finalisation == 4;
b8 rounds48 = data->compression == 4 && data->finalisation == 8; b8 rounds48 = ctx->siphash.compression == 4 && ctx->siphash.finalisation == 8;
return rounds24 || rounds48; return rounds24 || rounds48;
} }
+7 -37
View File
@@ -1,8 +1,8 @@
// vim:fileencoding=utf-8:foldmethod=marker // vim:fileencoding=utf-8:foldmethod=marker
/** /**
* Implementations of the SipHash-2-4-128, SipHash4-8-128, SipHash-2-4-64 and SipHash4-8-64 * Implementations of the SipHash-2-4-128, SipHash4-8-128 algorithms based on
* algorithms based on https://github.com/veorq/SipHash/blob/master/siphash.c * https://github.com/veorq/SipHash/blob/master/siphash.c
*/ */
#ifndef SIPHASH_H #ifndef SIPHASH_H
@@ -10,47 +10,17 @@
#include "hasher.h" #include "hasher.h"
#include "../../stream/stream.h" #include "../../stream/stream.h"
#include "../../../common/aliases/aliases.h"
#include "../../../common/platform/platform.h" #include "../../../common/platform/platform.h"
#ifdef WP_PLATFORM_CPP #ifdef WP_PLATFORM_CPP
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // !WP_PLATFORM_CPP #endif // !WP_PLATFORM_CPP
#define WP_SIP_HASHER_MAGIC wpU64Const(0x5750534950485348) WpHasher wpSip24Hasher(void);
WpHasher wpSip48Hasher(void);
typedef struct WpSipHasherKey { WpHasher wpSip24HasherWithKey(WpU128 key);
u64 lo; WpHasher wpSip48HasherWithKey(WpU128 key);
u64 hi; WpU128 wpSipGetHash128(WpU8Stream *bytes, WpHasherCtx ctx);
} WpSipHasherKey;
typedef struct WpSipHasherData {
WpSipHasherKey key;
u64 magic;
u64 compression;
u64 finalisation;
} WpSipHasherData;
#ifdef WP_PLATFORM_CPP
#define wpSip24HasherData(KEY) (WpSipHasherData{(KEY), WP_SIP_HASHER_MAGIC, 2, 4})
#define wpSip48HasherData(KEY) (WpSipHasherData{(KEY), WP_SIP_HASHER_MAGIC, 4, 8})
#else
#define wpSip24HasherData(KEY) ((WpSipHasherData){ \
.key = (KEY), \
.magic = WP_SIP_HASHER_MAGIC, \
.compression = 2, \
.finalisation = 4, \
})
#define wpSip48HasherData(KEY) ((WpSipHasherData){ \
.key = (KEY), \
.magic = WP_SIP_HASHER_MAGIC, \
.compression = 4, \
.finalisation = 8, \
})
#endif
WpHasher wpSipHasher(WpSipHasherData *data);
WpU128Hash wpSipHasher128(WpU8Stream *bytes, void *hasher_io);
#ifdef WP_PLATFORM_CPP #ifdef WP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE
+83
View File
@@ -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);
}
}
+134
View File
@@ -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
+51
View File
@@ -0,0 +1,51 @@
// 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);
}
}
+105
View File
@@ -0,0 +1,105 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef SET_H
#define SET_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 WpHashSet;
#ifdef WP_PLATFORM_CPP
#define wpHashSet(TYPE, U8_STREAM_ENCODER, ITEM_EQ_TEST, CAPACITY) \
(WpHashSet{ \
WP_HASH_TABLE_DEFAULT_HASHER, \
U8_STREAM_ENCODER, \
ITEM_EQ_TEST, \
wpArrayWithCapacity(TYPE, wpMiscUtilsU64RoundUpPow2(CAPACITY), WP_ARRAY_INIT_NONE), \
NULL, \
wpArrayWithCapacity(WpHashBucket, wpMiscUtilsU64RoundUpPow2(CAPACITY), WP_ARRAY_INIT_FILLED), \
WP_HASH_TABLE_MAGIC, \
wpMiscUtilsU64RoundUpPow2(CAPACITY) - 1, \
0.0f, \
false, \
})
#define wpHashSetCustomHasher(TYPE, HASHER, U8_STREAM_ENCODER, ITEM_EQ_TEST, CAPACITY) \
(WpHashSet{ \
HASHER, \
U8_STREAM_ENCODER, \
ITEM_EQ_TEST, \
wpArrayWithCapacity(TYPE, wpMiscUtilsU64RoundUpPow2(CAPACITY), WP_ARRAY_INIT_NONE), \
NULL, \
wpArrayWithCapacity(WpHashBucket, wpMiscUtilsU64RoundUpPow2(CAPACITY), WP_ARRAY_INIT_FILLED), \
WP_HASH_TABLE_MAGIC, \
wpMiscUtilsU64RoundUpPow2(CAPACITY) - 1, \
0.0f, \
false, \
})
#else
#define wpHashSet(TYPE, U8_STREAM_ENCODER, ITEM_EQ_TEST, CAPACITY) \
((WpHashSet){ \
.hasher = WP_HASH_TABLE_DEFAULT_HASHER, \
.encoder = U8_STREAM_ENCODER, \
.key_eq = ITEM_EQ_TEST, \
.keys = wpArrayWithCapacity(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, \
})
#define wpHashSetCustomHasher(TYPE, HASHER, U8_STREAM_ENCODER, ITEM_EQ_TEST, CAPACITY) \
((WpHashSet){ \
.hasher = HASHER, \
.encoder = U8_STREAM_ENCODER, \
.key_eq = ITEM_EQ_TEST, \
.keys = wpArrayWithCapacity(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, \
})
#endif
#define wpHashSetAlloc(TYPE, ALLOCATOR_PTR, U8_STREAM_ENCODER, ITEM_EQ_TEST, CAPACITY) \
hashSetAlloc(ALLOCATOR_PTR, U8_STREAM_ENCODER, ITEM_EQ_TEST, CAPACITY, sizeof(TYPE))
#define wpHashSetCustomHasherAlloc(TYPE, ALLOCATOR_PTR, HASHER, U8_STREAM_ENCODER, ITEM_EQ_TEST, \
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 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)
WpHashSet hashSetAlloc(const WpAllocator *allocator, WpU8StreamEncoder encoder,
WpKeyEqualTest key_eq, u64 capacity, u64 key_size);
WpHashSet hashSetAllocWithCustomHasher(const WpAllocator *allocator, WpHasher hasher,
WpU8StreamEncoder encoder, WpKeyEqualTest key_eq,
u64 capacity, u64 key_size);
WpHashLookupResult hashSetFind(WpHashSet *set, void *item, u64 item_size);
void hashSetInsertCapped(WpHashSet *set, void *item, u64 item_size);
void hashSetInsertAlloc(const WpAllocator *allocator, WpHashSet *set, void *item,
u64 item_size);
void hashSetRemove(WpHashSet *set, void *item, u64 item_size);
#ifdef WP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WP_PLATFORM_CPP
#endif // !SET_H
+76 -32
View File
@@ -8,26 +8,62 @@
#include "../../../common/assert/assert.h" #include "../../../common/assert/assert.h"
#include "../../../common/misc/misc_utils.h" #include "../../../common/misc/misc_utils.h"
wp_persist inline void *hashTableGetKeyFromBucket(WpHashTable *table, WpHashBucket bucket, u64 key_size);
wp_persist inline void *hashTableGetValueFromBucket(WpHashTable *table, WpHashBucket bucket, u64 value_size);
wp_persist inline u64 hashTableGetDist(u64 dist_and_tag);
wp_persist inline u64 hashTableNextBucket(WpHashTable *table, u64 bucket_index);
wp_persist inline u64 hashTableDistInc(u64 dist_and_tag);
wp_persist inline u64 hashTableDistDec(u64 dist_and_tag);
wp_persist inline void hashTableValidate(const WpHashTable *table, u64 key_size, u64 value_size); wp_persist inline void hashTableValidate(const WpHashTable *table, u64 key_size, u64 value_size);
void *hashTableKeys(WpHashTable *table) { void hashTableAlloc(const WpAllocator *allocator, WpHashTable *table, WpHasher hasher,
WpU8StreamEncoder encoder, WpKeyEqualTest key_eq, u64 capacity, u64 key_size,
u64 value_size, b8 has_values) {
wpDebugAssert(allocator != NULL && table != NULL && encoder != NULL && key_eq != NULL,
"`allocator`, `table`, `encoder` and `key_eq` should not be NULL");
u64 table_capacity = wpMiscUtilsU64RoundUpPow2(capacity);
table->hasher = hasher;
table->encoder = encoder;
table->key_eq = key_eq;
table->keys = arrayAllocCapacity(allocator, table_capacity, WP_ARRAY_INIT_NONE, key_size);;
table->buckets = wpArrayAllocCapacity(WpHashBucket, allocator, table_capacity, WP_ARRAY_INIT_FILLED);
table->magic = WP_HASH_TABLE_MAGIC;
table->bucket_mask = table_capacity - 1;
table->load_factor = WP_HASH_MAX_LOAD_FACTOR;
table->has_values = has_values;
wpRuntimeAssert(table->keys != NULL && table->buckets != NULL, "Failed to allocate keys, buckets or both");
if (has_values) {
table->values = arrayAllocCapacity(allocator, table_capacity, WP_ARRAY_INIT_NONE, value_size);;
wpRuntimeAssert(table->values != NULL, "Failed to allocate values");
}
}
u64 hashTableCalcHash(WpHashTable *table, void *key, u64 key_size) {
hashTableValidate(table, key_size, 0);
wpDebugAssert(key != NULL, "`key` should not be NULL");
WpU8Stream stream = table->encoder(key);
return wpHasherGetHash64(&table->hasher, &stream);
}
WpHashBucketRef hashTableBucketRef(WpHashTable *table, u64 hash) {
hashTableValidate(table, 0, 0); hashTableValidate(table, 0, 0);
return (WpHashBucketRef){
.dist_and_tag = WP_HASH_DIST_INC | (hash & WP_HASH_TAG_MASK),
.bucket_index = hash & table->bucket_mask,
};
}
void *hashTableKeys(WpHashTable *table, u64 key_size) {
hashTableValidate(table, key_size, 0);
return table->keys; return table->keys;
} }
void *hashTableValues(WpHashTable *table) { void *hashTableValues(WpHashTable *table, u64 value_size) {
hashTableValidate(table, 0, 0);
return table->values;
}
void *hashTableGetKeyFromBucket(WpHashTable *table, WpHashBucket bucket, u64 key_size) {
hashTableValidate(table, key_size, 0);
return arrayGet(table->keys, bucket.item_index, key_size);
}
void *hashTableGetValueFromBucket(WpHashTable *table, WpHashBucket bucket, u64 value_size) {
hashTableValidate(table, 0, value_size); hashTableValidate(table, 0, value_size);
return table->has_values ? arrayGet(table->values, bucket.item_index, value_size) : NULL; return table->values;
} }
void *hashTableGetKeyFromBucketRef(WpHashTable *table, WpHashBucketRef ref, u64 key_size) { void *hashTableGetKeyFromBucketRef(WpHashTable *table, WpHashBucketRef ref, u64 key_size) {
@@ -58,25 +94,21 @@ u64 hashTableValueSize(WpHashTable *table) {
return table->has_values ? wpArrayItemSize(table->values) : 0; return table->has_values ? wpArrayItemSize(table->values) : 0;
} }
u64 hashTableCalcHash(WpHashTable *table, void *key, u64 key_size) { void hashTableGrow(const WpAllocator *allocator, WpHashTable *table, u64 key_size, u64 value_size) {
hashTableValidate(table, key_size, 0);
wpDebugAssert(key != NULL, "`key` should not be NULL");
WpU8Stream stream = table->encoder(key);
return wpHasherGetHash64(&table->hasher, &stream);
}
void hashTableGrow(WpHashTable *table, const WpAllocator *allocator, u64 key_size, u64 value_size) {
hashTableValidate(table, key_size, value_size); hashTableValidate(table, key_size, value_size);
wpDebugAssert(allocator != NULL, "`allocator` should not be NULL"); wpDebugAssert(allocator != NULL, "`allocator` should not be NULL");
u64 capacity = hashTableCapacity(table) * 2; u64 capacity = wpMiscUtilsU64RoundUpPow2(hashTableCapacity(table) * 2);
u64 mask = capacity - wpU64Const(1); u64 mask = capacity - wpU64Const(1);
WpArray keys = arrayAllocCapacity(allocator, capacity, WP_ARRAY_INIT_NONE, key_size); WpArray keys = arrayAllocCapacity(allocator, capacity, WP_ARRAY_INIT_NONE, key_size);
WpArray values = NULL; WpArray values = NULL;
WpHashBucketArray buckets = wpArrayAllocCapacity(WpHashBucket, allocator, capacity, WP_ARRAY_INIT_FILLED); WpHashBucketArray buckets = wpArrayAllocCapacity(WpHashBucket, allocator, capacity, WP_ARRAY_INIT_FILLED);
wpRuntimeAssert(keys != NULL && buckets != NULL, "Failed to allocate keys, buckets or both");
if (table->has_values) { if (table->has_values) {
values = arrayAllocCapacity(allocator, capacity, WP_ARRAY_INIT_NONE, value_size); values = arrayAllocCapacity(allocator, capacity, WP_ARRAY_INIT_NONE, value_size);
wpRuntimeAssert(values != NULL, "Failed to allocate values");
} }
WpArray old_keys = table->keys; WpArray old_keys = table->keys;
@@ -212,27 +244,39 @@ void hashTableClear(WpHashTable *table, u64 key_size, u64 value_size) {
wpArrayZero(WpHashBucket, table->buckets); wpArrayZero(WpHashBucket, table->buckets);
} }
WpHashBucketRef hashTableBucketRef(WpHashTable *table, u64 hash) { void hashTableDealloc(const WpAllocator *allocator, WpHashTable *table, u64 key_size, u64 value_size) {
hashTableValidate(table, 0, 0); wpDebugAssert(allocator != NULL, "`allocator` should not be NULL");
return (WpHashBucketRef){ hashTableValidate(table, key_size, value_size);
.dist_and_tag = WP_HASH_DIST_INC | (hash & WP_HASH_TAG_MASK), arrayDealloc(allocator, table->keys, key_size);
.bucket_index = hash & table->bucket_mask, wpArrayDealloc(WpHashBucket, allocator, table->buckets);
}; if (table->has_values) {
arrayDealloc(allocator, table->values, value_size);
}
} }
u64 hashTableGetDist(u64 dist_and_tag) { wp_persist inline void *hashTableGetKeyFromBucket(WpHashTable *table, WpHashBucket bucket, u64 key_size) {
hashTableValidate(table, key_size, 0);
return arrayGet(table->keys, bucket.item_index, key_size);
}
wp_persist inline void *hashTableGetValueFromBucket(WpHashTable *table, WpHashBucket bucket, u64 value_size) {
hashTableValidate(table, 0, value_size);
return table->has_values ? arrayGet(table->values, bucket.item_index, value_size) : NULL;
}
wp_persist inline u64 hashTableGetDist(u64 dist_and_tag) {
return dist_and_tag & (~WP_HASH_TAG_MASK); return dist_and_tag & (~WP_HASH_TAG_MASK);
} }
u64 hashTableNextBucket(WpHashTable *table, u64 bucket_index) { wp_persist inline u64 hashTableNextBucket(WpHashTable *table, u64 bucket_index) {
return (++bucket_index) & table->bucket_mask; return (++bucket_index) & table->bucket_mask;
} }
u64 hashTableDistInc(u64 dist_and_tag) { wp_persist inline u64 hashTableDistInc(u64 dist_and_tag) {
return dist_and_tag + WP_HASH_DIST_INC; return dist_and_tag + WP_HASH_DIST_INC;
} }
u64 hashTableDistDec(u64 dist_and_tag) { wp_persist inline u64 hashTableDistDec(u64 dist_and_tag) {
return dist_and_tag - WP_HASH_DIST_INC; return dist_and_tag - WP_HASH_DIST_INC;
} }
+13 -11
View File
@@ -19,6 +19,7 @@
#define TABLE_H #define TABLE_H
#include "../hasher/hasher.h" #include "../hasher/hasher.h"
#include "../hasher/murmur3.h"
#include "../../array/array.h" #include "../../array/array.h"
#include "../../mem/allocator/mem_allocator.h" #include "../../mem/allocator/mem_allocator.h"
#include "../../stream/stream.h" #include "../../stream/stream.h"
@@ -34,6 +35,7 @@ BEGIN_C_LINKAGE
#define WP_HASH_DIST_INC (wpU64Const(1) << WP_HASH_TAG_BITS) #define WP_HASH_DIST_INC (wpU64Const(1) << WP_HASH_TAG_BITS)
#define WP_HASH_TAG_MASK (WP_HASH_DIST_INC - wpU64Const(1)) #define WP_HASH_TAG_MASK (WP_HASH_DIST_INC - wpU64Const(1))
#define WP_HASH_MAX_LOAD_FACTOR 0.65f #define WP_HASH_MAX_LOAD_FACTOR 0.65f
#define WP_HASH_TABLE_DEFAULT_HASHER wpX64Mur3Hasher()
typedef WpU8Stream (*WpU8StreamEncoder)(void *data); typedef WpU8Stream (*WpU8StreamEncoder)(void *data);
typedef b8 (*WpKeyEqualTest)(void *a, void *b); typedef b8 (*WpKeyEqualTest)(void *a, void *b);
@@ -67,18 +69,21 @@ typedef struct WpHashLookupResult {
b8 found; b8 found;
} WpHashLookupResult; } WpHashLookupResult;
void *hashTableKeys(WpHashTable *table); void hashTableAlloc(const WpAllocator *allocator, WpHashTable *table,
void *hashTableValues(WpHashTable *table); WpHasher hasher, WpU8StreamEncoder encoder,
void *hashTableGetKeyFromBucket(WpHashTable *table, WpHashBucket bucket, u64 key_size); WpKeyEqualTest key_eq, u64 capacity, u64 key_size,
void *hashTableGetValueFromBucket(WpHashTable *table, WpHashBucket bucket, u64 value_size); u64 value_size, b8 has_values);
u64 hashTableCalcHash(WpHashTable *table, void *key, u64 key_size);
WpHashBucketRef hashTableBucketRef(WpHashTable *table, u64 hash);
void *hashTableKeys(WpHashTable *table, u64 key_size);
void *hashTableValues(WpHashTable *table, u64 value_size);
void *hashTableGetKeyFromBucketRef(WpHashTable *table, WpHashBucketRef ref, u64 key_size); void *hashTableGetKeyFromBucketRef(WpHashTable *table, WpHashBucketRef ref, u64 key_size);
void *hashTableGetValueFromBucketRef(WpHashTable *table, WpHashBucketRef ref, u64 value_size); void *hashTableGetValueFromBucketRef(WpHashTable *table, WpHashBucketRef ref, u64 value_size);
u64 hashTableCapacity(WpHashTable *table); u64 hashTableCapacity(WpHashTable *table);
u64 hashTableCount(WpHashTable *table); u64 hashTableCount(WpHashTable *table);
u64 hashTableKeySize(WpHashTable *table); u64 hashTableKeySize(WpHashTable *table);
u64 hashTableValueSize(WpHashTable *table); u64 hashTableValueSize(WpHashTable *table);
u64 hashTableCalcHash(WpHashTable *table, void *key, u64 key_size); void hashTableGrow(const WpAllocator *allocator, WpHashTable *table, u64 key_size,
void hashTableGrow(WpHashTable *table, const WpAllocator *allocator, u64 key_size,
u64 value_size); u64 value_size);
WpHashLookupResult hashTableLookup(WpHashTable *table, void *key, WpHashBucketRef ref, u64 key_size); WpHashLookupResult hashTableLookup(WpHashTable *table, void *key, WpHashBucketRef ref, u64 key_size);
void hashTableUpdate(WpHashTable *table, void *value, WpHashBucketRef ref, u64 value_size); void hashTableUpdate(WpHashTable *table, void *value, WpHashBucketRef ref, u64 value_size);
@@ -86,11 +91,8 @@ void hashTableInsert(WpHashTable *table, void *key, void *value, W
u64 key_size, u64 value_size); u64 key_size, u64 value_size);
void hashTableRemove(WpHashTable *table, WpHashBucketRef ref, u64 key_size, u64 value_size); void hashTableRemove(WpHashTable *table, WpHashBucketRef ref, u64 key_size, u64 value_size);
void hashTableClear(WpHashTable *table, u64 key_size, u64 value_size); void hashTableClear(WpHashTable *table, u64 key_size, u64 value_size);
WpHashBucketRef hashTableBucketRef(WpHashTable *table, u64 hash); void hashTableDealloc(const WpAllocator *allocator, WpHashTable *table, u64 key_size,
u64 hashTableGetDist(u64 dist_and_tag); u64 value_size);
u64 hashTableNextBucket(WpHashTable *table, u64 bucket_index);
u64 hashTableDistInc(u64 dist_and_tag);
u64 hashTableDistDec(u64 dist_and_tag);
#ifdef WP_PLATFORM_CPP #ifdef WP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE
+24
View File
@@ -56,6 +56,26 @@ void wpMemAllocatorFree(const WpAllocator *allocator, void **ptr, u64 size) {
allocator->free(ptr, size, allocator->obj); allocator->free(ptr, size, allocator->obj);
} }
void wpMemAllocatorTempBegin(const WpAllocator *allocator) {
wpDebugAssert(allocator != NULL, "`allocator` should not be NULL");
if (!wpMemAllocatorOpSupported(allocator, WP_MEM_OP_TEMP_BEGIN)) {
return;
}
allocator->temp_begin(allocator->obj);
}
void wpMemAllocatorTempEnd(const WpAllocator *allocator) {
wpDebugAssert(allocator != NULL, "`allocator` should not be NULL");
if (!wpMemAllocatorOpSupported(allocator, WP_MEM_OP_TEMP_END)) {
return;
}
allocator->temp_end(allocator->obj);
}
b8 wpMemAllocatorOpSupported(const WpAllocator *allocator, WpMemOp op) { b8 wpMemAllocatorOpSupported(const WpAllocator *allocator, WpMemOp op) {
wpDebugAssert(allocator != NULL, "`allocator` should not be NULL"); wpDebugAssert(allocator != NULL, "`allocator` should not be NULL");
@@ -70,6 +90,10 @@ b8 wpMemAllocatorOpSupported(const WpAllocator *allocator, WpMemOp op) {
return allocator->realloc_aligned != NULL; return allocator->realloc_aligned != NULL;
case WP_MEM_OP_FREE: case WP_MEM_OP_FREE:
return allocator->free != NULL; return allocator->free != NULL;
case WP_MEM_OP_TEMP_BEGIN:
return allocator->temp_begin != NULL;
case WP_MEM_OP_TEMP_END:
return allocator->temp_end != NULL;
default: default:
break; break;
} }
+8
View File
@@ -17,6 +17,8 @@ typedef enum WpMemOp {
WP_MEM_OP_REALLOC, WP_MEM_OP_REALLOC,
WP_MEM_OP_REALLOC_ALIGNED, WP_MEM_OP_REALLOC_ALIGNED,
WP_MEM_OP_FREE, WP_MEM_OP_FREE,
WP_MEM_OP_TEMP_BEGIN,
WP_MEM_OP_TEMP_END,
COUNT_MEM_OPS COUNT_MEM_OPS
} WpMemOp; } WpMemOp;
@@ -26,6 +28,8 @@ typedef void *(WpMemAllocAlignedFunc)(u64 size, u64 alignment, void *alloc_obj)
typedef void *(WpMemReallocFunc)(void *ptr, u64 old_size, u64 new_size, void *alloc_obj); typedef void *(WpMemReallocFunc)(void *ptr, u64 old_size, u64 new_size, void *alloc_obj);
typedef void *(WpMemReallocAlignedFunc)(void *ptr, u64 old_size, u64 new_size, u64 alignment, void *alloc_obj); typedef void *(WpMemReallocAlignedFunc)(void *ptr, u64 old_size, u64 new_size, u64 alignment, void *alloc_obj);
typedef void (WpMemFreeFunc)(void **ptr, u64 size, void *alloc_obj); typedef void (WpMemFreeFunc)(void **ptr, u64 size, void *alloc_obj);
typedef void (WpMemTempBeginFunc)(void *alloc_obj);
typedef void (WpMemTempEndFunc)(void *alloc_obj);
typedef struct WpAllocator WpAllocator; typedef struct WpAllocator WpAllocator;
struct WpAllocator { struct WpAllocator {
@@ -35,6 +39,8 @@ struct WpAllocator {
WpMemReallocFunc *realloc; WpMemReallocFunc *realloc;
WpMemReallocAlignedFunc *realloc_aligned; WpMemReallocAlignedFunc *realloc_aligned;
WpMemFreeFunc *free; WpMemFreeFunc *free;
WpMemTempBeginFunc *temp_begin;
WpMemTempEndFunc *temp_end;
}; };
#ifdef WP_PLATFORM_CPP #ifdef WP_PLATFORM_CPP
@@ -52,6 +58,8 @@ void *wpMemAllocatorRealloc(const WpAllocator *allocator, void *ptr, u64 old_siz
void *wpMemAllocatorReallocAligned(const WpAllocator *allocator, void *ptr, u64 old_size, void *wpMemAllocatorReallocAligned(const WpAllocator *allocator, void *ptr, u64 old_size,
u64 new_size, u64 alignment); u64 new_size, u64 alignment);
void wpMemAllocatorFree(const WpAllocator *allocator, void **ptr, u64 size); void wpMemAllocatorFree(const WpAllocator *allocator, void **ptr, u64 size);
void wpMemAllocatorTempBegin(const WpAllocator *allocator);
void wpMemAllocatorTempEnd(const WpAllocator *allocator);
b8 wpMemAllocatorOpSupported(const WpAllocator *allocator, WpMemOp op); b8 wpMemAllocatorOpSupported(const WpAllocator *allocator, WpMemOp op);
#ifdef WP_PLATFORM_CPP #ifdef WP_PLATFORM_CPP
+2
View File
@@ -10,6 +10,8 @@
#include "hash/hasher/murmur3.c" #include "hash/hasher/murmur3.c"
#include "hash/hasher/siphash.c" #include "hash/hasher/siphash.c"
#include "hash/table/table.c" #include "hash/table/table.c"
#include "hash/set/set.c"
#include "hash/map/map.c"
#include "queue/queue.c" #include "queue/queue.c"
#include "stream/stream.c" #include "stream/stream.c"
#include "mem/allocator/mem_allocator.c" #include "mem/allocator/mem_allocator.c"
+2
View File
@@ -9,6 +9,8 @@
#include "hash/hasher/murmur3.h" #include "hash/hasher/murmur3.h"
#include "hash/hasher/siphash.h" #include "hash/hasher/siphash.h"
#include "hash/table/table.h" #include "hash/table/table.h"
#include "hash/set/set.h"
#include "hash/map/map.h"
#include "queue/queue.h" #include "queue/queue.h"
#include "stream/stream.h" #include "stream/stream.h"
#include "mem/allocator/mem_allocator.h" #include "mem/allocator/mem_allocator.h"
+1 -5
View File
@@ -8,7 +8,7 @@
#include "../os/file/file.h" #include "../os/file/file.h"
#include <time.h> #include <time.h>
#define MIN_LOG_MSG_LENGTH 32 #define MIN_LOG_MSG_LENGTH 128
#define TIME_BUF_CAPACITY 70 #define TIME_BUF_CAPACITY 70
wp_intern WpStr8RO L_BRACKET = wpStr8LitRo("["); wp_intern WpStr8RO L_BRACKET = wpStr8LitRo("[");
@@ -48,10 +48,6 @@ void wpLogConfigure(WpFile *outlog, WpFile *errlog, WpLogLevel level) {
LOG_CONFIG.level = level; LOG_CONFIG.level = level;
} }
WpLogger wpLogMakeLogger(WpStr8 name) {
return (WpLogger){ .name = name };
}
void wpLogDebug(const WpLogger *logger, WpStr8 msg) { void wpLogDebug(const WpLogger *logger, WpStr8 msg) {
wpDebugAssert(logger != NULL, "`logger` should not be NULL"); wpDebugAssert(logger != NULL, "`logger` should not be NULL");
if (LOG_CONFIG.level < WP_LOG_LEVEL_DEBUG) { return; } if (LOG_CONFIG.level < WP_LOG_LEVEL_DEBUG) { return; }
+8 -2
View File
@@ -3,6 +3,7 @@
#ifndef LOG_H #ifndef LOG_H
#define LOG_H #define LOG_H
#include "../common/platform/platform.h"
#include "../os/file/file.h" #include "../os/file/file.h"
#include "../base/strings/str8/str8.h" #include "../base/strings/str8/str8.h"
@@ -22,12 +23,17 @@ typedef enum WpLogLevel {
} WpLogLevel; } WpLogLevel;
typedef struct WpLogger { typedef struct WpLogger {
WpStr8 name; WpStr8RO name;
} WpLogger; } WpLogger;
#ifdef WP_PLATFORM_CPP
#define wpLogMakeLogger(NAME) (WpLogger{NAME})
#else
#define wpLogMakeLogger(NAME) ((WpLogger){ .name = NAME })
#endif
void wpLogSetLevel(WpLogLevel level); void wpLogSetLevel(WpLogLevel level);
void wpLogConfigure(WpFile *outlog, WpFile *errlog, WpLogLevel level); void wpLogConfigure(WpFile *outlog, WpFile *errlog, WpLogLevel level);
WpLogger wpLogMakeLogger(WpStr8 name);
void wpLogDebug(const WpLogger *logger, WpStr8 msg); void wpLogDebug(const WpLogger *logger, WpStr8 msg);
void wpLogInfo(const WpLogger *logger, WpStr8 msg); void wpLogInfo(const WpLogger *logger, WpStr8 msg);
void wpLogWarning(const WpLogger *logger, WpStr8 msg); void wpLogWarning(const WpLogger *logger, WpStr8 msg);
+14 -11
View File
@@ -2,7 +2,6 @@
#include "mem_arena_allocator.h" #include "mem_arena_allocator.h"
#include "mem_arena.h" #include "mem_arena.h"
#include "../../mem/mem_os.h"
#include "../../../common/aliases/aliases.h" #include "../../../common/aliases/aliases.h"
#include "../../../common/assert/assert.h" #include "../../../common/assert/assert.h"
@@ -12,6 +11,8 @@ wp_intern void *memArenaAllocAligned(u64 size, u64 alignment, void *alloc_obj);
wp_intern void *memArenaRealloc(void *ptr, u64 old_size, u64 new_size, void *alloc_obj); wp_intern void *memArenaRealloc(void *ptr, u64 old_size, u64 new_size, void *alloc_obj);
wp_intern void *memArenaReallocAligned(void *ptr, u64 old_size, u64 new_size, u64 alignment, wp_intern void *memArenaReallocAligned(void *ptr, u64 old_size, u64 new_size, u64 alignment,
void *alloc_obj); void *alloc_obj);
wp_intern void memArenaTempBegin(void *alloc_obj);
wp_intern void memArenaTempEnd(void *alloc_obj);
WpAllocator wpMemArenaAllocatorInitWithBuffer(u8 *buffer, u64 buffer_size) { WpAllocator wpMemArenaAllocatorInitWithBuffer(u8 *buffer, u64 buffer_size) {
WpAllocator allocator = {0}; WpAllocator allocator = {0};
@@ -37,16 +38,6 @@ WpAllocator wpMemArenaAllocatorInitCustom(u64 base_capacity, WpMemAllocFlags fla
return allocator; return allocator;
} }
void wpMemArenaAllocatorTempBegin(const WpAllocator *allocator) {
wpDebugAssert(allocator != NULL, "`allocator` should not be NULL");
wpMemArenaTempBegin((WpArena *)(allocator->obj));
}
void wpMemArenaAllocatorTempEnd(const WpAllocator *allocator) {
wpDebugAssert(allocator != NULL, "`allocator` should not be NULL");
wpMemArenaTempEnd((WpArena *)(allocator->obj));
}
void wpMemArenaAllocatorClear(WpAllocator *allocator) { void wpMemArenaAllocatorClear(WpAllocator *allocator) {
wpDebugAssert(allocator != NULL, "`allocator` should not be NULL"); wpDebugAssert(allocator != NULL, "`allocator` should not be NULL");
wpMemArenaClear((WpArena *)(allocator->obj)); wpMemArenaClear((WpArena *)(allocator->obj));
@@ -63,6 +54,8 @@ wp_intern void initialiseArenaAllocator(WpAllocator *allocator) {
allocator->alloc_aligned = memArenaAllocAligned; allocator->alloc_aligned = memArenaAllocAligned;
allocator->realloc = memArenaRealloc; allocator->realloc = memArenaRealloc;
allocator->realloc_aligned = memArenaReallocAligned; allocator->realloc_aligned = memArenaReallocAligned;
allocator->temp_begin = memArenaTempBegin;
allocator->temp_end = memArenaTempEnd;
} }
wp_intern void *memArenaAlloc(u64 size, void *alloc_obj) { wp_intern void *memArenaAlloc(u64 size, void *alloc_obj) {
@@ -85,3 +78,13 @@ wp_intern void *memArenaReallocAligned(void *ptr, u64 old_size, u64 new_size, u6
WpArena *arena = (WpArena *)alloc_obj; WpArena *arena = (WpArena *)alloc_obj;
return wpMemArenaReallocAligned(arena, ptr, old_size, new_size, alignment); return wpMemArenaReallocAligned(arena, ptr, old_size, new_size, alignment);
} }
wp_intern void memArenaTempBegin(void *alloc_obj) {
WpArena *arena = (WpArena *)alloc_obj;
wpMemArenaTempBegin(arena);
}
wp_intern void memArenaTempEnd(void *alloc_obj) {
WpArena *arena = (WpArena *)alloc_obj;
wpMemArenaTempEnd(arena);
}
@@ -34,8 +34,6 @@ BEGIN_C_LINKAGE
*/ */
WpAllocator wpMemArenaAllocatorInitCustom(u64 base_capacity, WpMemAllocFlags flags, b8 zero_buffer); WpAllocator wpMemArenaAllocatorInitCustom(u64 base_capacity, WpMemAllocFlags flags, b8 zero_buffer);
WpAllocator wpMemArenaAllocatorInitWithBuffer(u8 *buffer, u64 buffer_size); WpAllocator wpMemArenaAllocatorInitWithBuffer(u8 *buffer, u64 buffer_size);
void wpMemArenaAllocatorTempBegin(const WpAllocator *allocator);
void wpMemArenaAllocatorTempEnd(const WpAllocator *allocator);
void wpMemArenaAllocatorClear(WpAllocator *allocator); void wpMemArenaAllocatorClear(WpAllocator *allocator);
void wpMemArenaAllocatorDestroy(WpAllocator *allocator); void wpMemArenaAllocatorDestroy(WpAllocator *allocator);
+2 -2
View File
@@ -45,7 +45,7 @@ WpTestFuncResult test_arena_allocator_temp_begin(void) {
i32 *num1 = (i32 *)wpMemAllocatorAlloc(&temp_allocator, sizeof(i32)); i32 *num1 = (i32 *)wpMemAllocatorAlloc(&temp_allocator, sizeof(i32));
b8 result = num1 != NULL; b8 result = num1 != NULL;
wpMemArenaAllocatorTempBegin(&temp_allocator); wpMemAllocatorTempBegin(&temp_allocator);
i32 *num2 = (i32 *)wpMemAllocatorAlloc(&temp_allocator, sizeof(i32)); i32 *num2 = (i32 *)wpMemAllocatorAlloc(&temp_allocator, sizeof(i32));
result = result && num2 != NULL; result = result && num2 != NULL;
i32 *num3 = (i32 *)wpMemAllocatorAlloc(&temp_allocator, sizeof(i32)); i32 *num3 = (i32 *)wpMemAllocatorAlloc(&temp_allocator, sizeof(i32));
@@ -55,7 +55,7 @@ WpTestFuncResult test_arena_allocator_temp_begin(void) {
} }
WpTestFuncResult test_arena_allocator_temp_end(void) { WpTestFuncResult test_arena_allocator_temp_end(void) {
wpMemArenaAllocatorTempEnd(&temp_allocator); wpMemAllocatorTempEnd(&temp_allocator);
i32 *num1 = (i32 *)wpMemAllocatorAlloc(&temp_allocator, sizeof(i32)); i32 *num1 = (i32 *)wpMemAllocatorAlloc(&temp_allocator, sizeof(i32));
b8 result = num1 != NULL; b8 result = num1 != NULL;
i32 *num2 = (i32 *)wpMemAllocatorAlloc(&temp_allocator, sizeof(i32)); i32 *num2 = (i32 *)wpMemAllocatorAlloc(&temp_allocator, sizeof(i32));
+2 -2
View File
@@ -45,7 +45,7 @@ WpTestFuncResult test_arena_allocator_temp_begin(void) {
i32 *num1 = (i32 *)wpMemAllocatorAlloc(&temp_allocator, sizeof(i32)); i32 *num1 = (i32 *)wpMemAllocatorAlloc(&temp_allocator, sizeof(i32));
b8 result = num1 != NULL; b8 result = num1 != NULL;
wpMemArenaAllocatorTempBegin(&temp_allocator); wpMemAllocatorTempBegin(&temp_allocator);
i32 *num2 = (i32 *)wpMemAllocatorAlloc(&temp_allocator, sizeof(i32)); i32 *num2 = (i32 *)wpMemAllocatorAlloc(&temp_allocator, sizeof(i32));
result = result && num2 != NULL; result = result && num2 != NULL;
i32 *num3 = (i32 *)wpMemAllocatorAlloc(&temp_allocator, sizeof(i32)); i32 *num3 = (i32 *)wpMemAllocatorAlloc(&temp_allocator, sizeof(i32));
@@ -55,7 +55,7 @@ WpTestFuncResult test_arena_allocator_temp_begin(void) {
} }
WpTestFuncResult test_arena_allocator_temp_end(void) { WpTestFuncResult test_arena_allocator_temp_end(void) {
wpMemArenaAllocatorTempEnd(&temp_allocator); wpMemAllocatorTempEnd(&temp_allocator);
i32 *num1 = (i32 *)wpMemAllocatorAlloc(&temp_allocator, sizeof(i32)); i32 *num1 = (i32 *)wpMemAllocatorAlloc(&temp_allocator, sizeof(i32));
b8 result = num1 != NULL; b8 result = num1 != NULL;
i32 *num2 = (i32 *)wpMemAllocatorAlloc(&temp_allocator, sizeof(i32)); i32 *num2 = (i32 *)wpMemAllocatorAlloc(&temp_allocator, sizeof(i32));
+21 -21
View File
@@ -12,7 +12,7 @@ WpTestFuncResult test_murmur3(void) {
WpI32Array arr = wpArray(i32, 1, 2, 3, 4, 5); WpI32Array arr = wpArray(i32, 1, 2, 3, 4, 5);
u64 num = 287324; u64 num = 287324;
WpMur3HasherData data = wpMur3HasherData(873923); WpHasher hasher = wpX64Mur3HasherWithSeed(873923);
WpU8Stream str_bytes = wpStream(u8, str.buf, str.size); WpU8Stream str_bytes = wpStream(u8, str.buf, str.size);
WpU8Stream arr_bytes = wpStream(u8, (u8 *)arr, wpArrayCount(arr) * wpArrayItemSize(arr)); WpU8Stream arr_bytes = wpStream(u8, (u8 *)arr, wpArrayCount(arr) * wpArrayItemSize(arr));
@@ -21,22 +21,22 @@ WpTestFuncResult test_murmur3(void) {
u64 hash[2] = {0}; u64 hash[2] = {0};
// Sring hash // Sring hash
WpU128Hash mur_hash = wpX64Mur3Hasher128(&str_bytes, (void *)&data); WpU128 mur_hash = hasher.func(&str_bytes, hasher.ctx);
MurmurHash3_x64_128(str_bytes.data, str_bytes.count * str_bytes.item_size, data.seed, (void *)hash); MurmurHash3_x64_128(str_bytes.data, str_bytes.count * str_bytes.item_size, hasher.ctx.murmur3, (void *)hash);
result = result && mur_hash.hash[0] == hash[0] && mur_hash.hash[1] == hash[1]; result = result && mur_hash.value[0] == hash[0] && mur_hash.value[1] == hash[1];
// Array hash // Array hash
mur_hash = wpX64Mur3Hasher128(&arr_bytes, (void *)&data); mur_hash = hasher.func(&arr_bytes, hasher.ctx);
MurmurHash3_x64_128(arr_bytes.data, arr_bytes.count * arr_bytes.item_size, data.seed, (void *)hash); MurmurHash3_x64_128(arr_bytes.data, arr_bytes.count * arr_bytes.item_size, hasher.ctx.murmur3, (void *)hash);
result = result && mur_hash.hash[0] == hash[0] && mur_hash.hash[1] == hash[1]; result = result && mur_hash.value[0] == hash[0] && mur_hash.value[1] == hash[1];
// Number hash // Number hash
mur_hash = wpX64Mur3Hasher128(&num_bytes, (void *)&data); mur_hash = hasher.func(&num_bytes, hasher.ctx);
MurmurHash3_x64_128(num_bytes.data, num_bytes.count * num_bytes.item_size, data.seed, (void *)hash); MurmurHash3_x64_128(num_bytes.data, num_bytes.count * num_bytes.item_size, hasher.ctx.murmur3, (void *)hash);
result = result && mur_hash.hash[0] == hash[0] && mur_hash.hash[1] == hash[1]; result = result && mur_hash.value[0] == hash[0] && mur_hash.value[1] == hash[1];
return wpTesterResult(result); return wpTesterResult(result);
} }
@@ -48,8 +48,8 @@ WpTestFuncResult test_siphash_128(void) {
WpI32Array arr = wpArray(i32, 1, 2, 3, 4, 5); WpI32Array arr = wpArray(i32, 1, 2, 3, 4, 5);
u64 num = 287324; u64 num = 287324;
WpSipHasherKey key = { .lo = 238742, .hi = 671734 }; WpU128 key = { .value = { 238742, 671734 } };
WpSipHasherData data = wpSip24HasherData(key); WpHasher hasher = wpSip24HasherWithKey(key);
WpU8Stream str_bytes = wpStream(u8, str.buf, str.size); WpU8Stream str_bytes = wpStream(u8, str.buf, str.size);
WpU8Stream arr_bytes = wpStream(u8, (u8 *)arr, wpArrayCount(arr) * wpArrayItemSize(arr)); WpU8Stream arr_bytes = wpStream(u8, (u8 *)arr, wpArrayCount(arr) * wpArrayItemSize(arr));
@@ -58,25 +58,25 @@ WpTestFuncResult test_siphash_128(void) {
u64 hash[2] = {0}; u64 hash[2] = {0};
// Sring hash // Sring hash
WpU128Hash sip_hash = wpSipHasher128(&str_bytes, (void *)&data); WpU128 sip_hash = hasher.func(&str_bytes, hasher.ctx);
siphash(str_bytes.data, str_bytes.count * str_bytes.item_size, (void *)&data.key, siphash(str_bytes.data, str_bytes.count * str_bytes.item_size, (void *)&hasher.ctx.siphash.key,
(u8 *)hash, sizeof(u64) * 2); (u8 *)hash, sizeof(u64) * 2);
result = result && sip_hash.hash[0] == hash[0] && sip_hash.hash[1] == hash[1]; result = result && sip_hash.value[0] == hash[0] && sip_hash.value[1] == hash[1];
// Array hash // Array hash
sip_hash = wpSipHasher128(&arr_bytes, (void *)&data); sip_hash = hasher.func(&arr_bytes, hasher.ctx);
siphash(arr_bytes.data, arr_bytes.count * arr_bytes.item_size, (void *)&data.key, siphash(arr_bytes.data, arr_bytes.count * arr_bytes.item_size, (void *)&hasher.ctx.siphash.key,
(u8 *)hash, sizeof(u64) * 2); (u8 *)hash, sizeof(u64) * 2);
result = result && sip_hash.hash[0] == hash[0] && sip_hash.hash[1] == hash[1]; result = result && sip_hash.value[0] == hash[0] && sip_hash.value[1] == hash[1];
// Number hash // Number hash
sip_hash = wpSipHasher128(&num_bytes, (void *)&data); sip_hash = hasher.func(&num_bytes, hasher.ctx);
siphash(num_bytes.data, num_bytes.count * num_bytes.item_size, (void *)&data.key, siphash(num_bytes.data, num_bytes.count * num_bytes.item_size, (void *)&hasher.ctx.siphash.key,
(u8 *)hash, sizeof(u64) * 2); (u8 *)hash, sizeof(u64) * 2);
result = result && sip_hash.hash[0] == hash[0] && sip_hash.hash[1] == hash[1]; result = result && sip_hash.value[0] == hash[0] && sip_hash.value[1] == hash[1];
return wpTesterResult(result); return wpTesterResult(result);
} }
+21 -21
View File
@@ -12,7 +12,7 @@ WpTestFuncResult test_murmur3(void) {
WpI32Array arr = wpArray(i32, 1, 2, 3, 4, 5); WpI32Array arr = wpArray(i32, 1, 2, 3, 4, 5);
u64 num = 287324; u64 num = 287324;
WpMur3HasherData data = wpMur3HasherData(873923); WpHasher hasher = wpX64Mur3HasherWithSeed(873923);
WpU8Stream str_bytes = wpStream(u8, str.buf, str.size); WpU8Stream str_bytes = wpStream(u8, str.buf, str.size);
WpU8Stream arr_bytes = wpStream(u8, (u8 *)arr, wpArrayCount(arr) * wpArrayItemSize(arr)); WpU8Stream arr_bytes = wpStream(u8, (u8 *)arr, wpArrayCount(arr) * wpArrayItemSize(arr));
@@ -21,22 +21,22 @@ WpTestFuncResult test_murmur3(void) {
u64 hash[2] = {0}; u64 hash[2] = {0};
// Sring hash // Sring hash
WpU128Hash mur_hash = wpX64Mur3Hasher128(&str_bytes, (void *)&data); WpU128 mur_hash = hasher.func(&str_bytes, hasher.ctx);
MurmurHash3_x64_128(str_bytes.data, str_bytes.count * str_bytes.item_size, data.seed, (void *)hash); MurmurHash3_x64_128(str_bytes.data, str_bytes.count * str_bytes.item_size, hasher.ctx.murmur3, (void *)hash);
result = result && mur_hash.hash[0] == hash[0] && mur_hash.hash[1] == hash[1]; result = result && mur_hash.value[0] == hash[0] && mur_hash.value[1] == hash[1];
// Array hash // Array hash
mur_hash = wpX64Mur3Hasher128(&arr_bytes, (void *)&data); mur_hash = hasher.func(&arr_bytes, hasher.ctx);
MurmurHash3_x64_128(arr_bytes.data, arr_bytes.count * arr_bytes.item_size, data.seed, (void *)hash); MurmurHash3_x64_128(arr_bytes.data, arr_bytes.count * arr_bytes.item_size, hasher.ctx.murmur3, (void *)hash);
result = result && mur_hash.hash[0] == hash[0] && mur_hash.hash[1] == hash[1]; result = result && mur_hash.value[0] == hash[0] && mur_hash.value[1] == hash[1];
// Number hash // Number hash
mur_hash = wpX64Mur3Hasher128(&num_bytes, (void *)&data); mur_hash = hasher.func(&num_bytes, hasher.ctx);
MurmurHash3_x64_128(num_bytes.data, num_bytes.count * num_bytes.item_size, data.seed, (void *)hash); MurmurHash3_x64_128(num_bytes.data, num_bytes.count * num_bytes.item_size, hasher.ctx.murmur3, (void *)hash);
result = result && mur_hash.hash[0] == hash[0] && mur_hash.hash[1] == hash[1]; result = result && mur_hash.value[0] == hash[0] && mur_hash.value[1] == hash[1];
return wpTesterResult(result); return wpTesterResult(result);
} }
@@ -48,8 +48,8 @@ WpTestFuncResult test_siphash_128(void) {
WpI32Array arr = wpArray(i32, 1, 2, 3, 4, 5); WpI32Array arr = wpArray(i32, 1, 2, 3, 4, 5);
u64 num = 287324; u64 num = 287324;
WpSipHasherKey key = { 238742, 671734 }; WpU128 key = { { 238742, 671734 } };
WpSipHasherData data = wpSip24HasherData(key); WpHasher hasher = wpSip24HasherWithKey(key);
WpU8Stream str_bytes = wpStream(u8, str.buf, str.size); WpU8Stream str_bytes = wpStream(u8, str.buf, str.size);
WpU8Stream arr_bytes = wpStream(u8, (u8 *)arr, wpArrayCount(arr) * wpArrayItemSize(arr)); WpU8Stream arr_bytes = wpStream(u8, (u8 *)arr, wpArrayCount(arr) * wpArrayItemSize(arr));
@@ -58,25 +58,25 @@ WpTestFuncResult test_siphash_128(void) {
u64 hash[2] = {0}; u64 hash[2] = {0};
// Sring hash // Sring hash
WpU128Hash sip_hash = wpSipHasher128(&str_bytes, (void *)&data); WpU128 sip_hash = hasher.func(&str_bytes, hasher.ctx);
siphash(str_bytes.data, str_bytes.count * str_bytes.item_size, (void *)&data.key, siphash(str_bytes.data, str_bytes.count * str_bytes.item_size, (void *)&hasher.ctx.siphash.key,
(u8 *)hash, sizeof(u64) * 2); (u8 *)hash, sizeof(u64) * 2);
result = result && sip_hash.hash[0] == hash[0] && sip_hash.hash[1] == hash[1]; result = result && sip_hash.value[0] == hash[0] && sip_hash.value[1] == hash[1];
// Array hash // Array hash
sip_hash = wpSipHasher128(&arr_bytes, (void *)&data); sip_hash = hasher.func(&arr_bytes, hasher.ctx);
siphash(arr_bytes.data, arr_bytes.count * arr_bytes.item_size, (void *)&data.key, siphash(arr_bytes.data, arr_bytes.count * arr_bytes.item_size, (void *)&hasher.ctx.siphash.key,
(u8 *)hash, sizeof(u64) * 2); (u8 *)hash, sizeof(u64) * 2);
result = result && sip_hash.hash[0] == hash[0] && sip_hash.hash[1] == hash[1]; result = result && sip_hash.value[0] == hash[0] && sip_hash.value[1] == hash[1];
// Number hash // Number hash
sip_hash = wpSipHasher128(&num_bytes, (void *)&data); sip_hash = hasher.func(&num_bytes, hasher.ctx);
siphash(num_bytes.data, num_bytes.count * num_bytes.item_size, (void *)&data.key, siphash(num_bytes.data, num_bytes.count * num_bytes.item_size, (void *)&hasher.ctx.siphash.key,
(u8 *)hash, sizeof(u64) * 2); (u8 *)hash, sizeof(u64) * 2);
result = result && sip_hash.hash[0] == hash[0] && sip_hash.hash[1] == hash[1]; result = result && sip_hash.value[0] == hash[0] && sip_hash.value[1] == hash[1];
return wpTesterResult(result); return wpTesterResult(result);
} }
+266
View File
@@ -0,0 +1,266 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "wapp.h"
#include "test_hashmap.h"
wp_persist inline WpU8Stream encoder(void *data);
wp_persist inline b8 key_eq(void *a, void *b);
WpTestFuncResult test_hashmap(void) {
b8 result = true;
WpHashMap map = wpHashMap(WpStr8, i32, encoder, key_eq, 8);
result = result && wpHashMapCapacity(&map) == 8 && wpHashMapCount(&map) == 0;
map = wpHashMap(WpStr8, i32, encoder, key_eq, 3);
result = result && wpHashMapCapacity(&map) == 4 && wpHashMapCount(&map) == 0;
return wpTesterResult(result);
}
WpTestFuncResult test_hashmap_alloc(void) {
WpAllocator arena = wpMemArenaAllocatorInit(KiB(4));
b8 result = true;
WpHashMap map = wpHashMapAlloc(WpStr8, i32, &arena, encoder, key_eq, 8);
result = result && wpHashMapCapacity(&map) == 8 && wpHashMapCount(&map) == 0;
map = wpHashMapAlloc(WpStr8, i32, &arena, encoder, key_eq, 3);
result = result && wpHashMapCapacity(&map) == 4 && wpHashMapCount(&map) == 0;
wpMemArenaAllocatorDestroy(&arena);
return wpTesterResult(result);
}
WpTestFuncResult test_hashmap_get_key_size(void) {
b8 result = true;
WpHashMap map = wpHashMap(WpStr8, i32, encoder, key_eq, 8);
result = result && wpHashMapKeySize(&map) == sizeof(WpStr8);
return wpTesterResult(result);
}
WpTestFuncResult test_hashmap_get_value_size(void) {
b8 result = true;
WpHashMap map = wpHashMap(WpStr8, i32, encoder, key_eq, 8);
result = result && wpHashMapValueSize(&map) == sizeof(i32);
return wpTesterResult(result);
}
WpTestFuncResult test_hashmap_find(void) {
b8 result = true;
WpHashMap map = wpHashMap(WpStr8, i32, encoder, key_eq, 8);
WpStr8Array keys = wpArray(
WpStr8,
wpStr8Lit("key1"),
wpStr8Lit("key2"),
wpStr8Lit("key3"),
wpStr8Lit("key4")
);
WpI32Array values = wpArray(i32, 1, 2, 3, 4);
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashMapInsertCapped(WpStr8, i32, &map, &keys[i], &values[i]);
}
WpHashLookupResult res = wpHashMapFind(WpStr8, &map, &keys[3]);
result = result && res.found && res.ref.dist_and_tag > 0;
WpStr8 key = wpStr8Lit("key0");
res = wpHashMapFind(WpStr8, &map, &key);
result = result && !res.found;
return wpTesterResult(result);
}
WpTestFuncResult test_hashmap_update(void) {
b8 result = true;
WpHashMap map = wpHashMap(WpStr8, i32, encoder, key_eq, 4);
WpStr8Array keys = wpArray(
WpStr8,
wpStr8Lit("key1"),
wpStr8Lit("key2"),
wpStr8Lit("key3"),
wpStr8Lit("key4")
);
WpI32Array values = wpArray(i32, 1, 2, 3, 4);
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashMapInsertCapped(WpStr8, i32, &map, &keys[i], &values[i]);
}
i32 new_value = 0;
wpHashMapUpdate(WpStr8, i32, &map, &keys[1], &new_value);
result = result && wpHashMapCapacity(&map) == 4 && wpHashMapCount(&map) == 3 &&
wpHashMapValues(i32, &map)[1] == new_value;
return wpTesterResult(result);
}
WpTestFuncResult test_hashmap_insert_capped(void) {
b8 result = true;
WpHashMap map = wpHashMap(WpStr8, i32, encoder, key_eq, 4);
WpStr8Array keys = wpArray(
WpStr8,
wpStr8Lit("key1"),
wpStr8Lit("key2"),
wpStr8Lit("key3"),
wpStr8Lit("key4")
);
WpI32Array values = wpArray(i32, 1, 2, 3, 4);
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashMapInsertCapped(WpStr8, i32, &map, &keys[i], &values[i]);
}
result = result && wpHashMapCapacity(&map) == 4 && wpHashMapCount(&map) == 3;
for (u64 i = 0; i < 3; ++i) {
result = result && wpStr8Equal(wpArrayGet(WpStr8, map.keys, i), &keys[i]);
}
return wpTesterResult(result);
}
WpTestFuncResult test_hashmap_insert_or_update_capped(void) {
b8 result = true;
WpHashMap map = wpHashMap(WpStr8, i32, encoder, key_eq, 4);
WpStr8Array keys = wpArray(
WpStr8,
wpStr8Lit("key1"),
wpStr8Lit("key2"),
wpStr8Lit("key3"),
wpStr8Lit("key4")
);
WpI32Array values = wpArray(i32, 1, 2, 3, 4);
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashMapInsertOrUpdateCapped(WpStr8, i32, &map, &keys[i], &values[i]);
}
result = result && wpHashMapCapacity(&map) == 4 && wpHashMapCount(&map) == 3;
for (u64 i = 0; i < 3; ++i) {
result = result && wpStr8Equal(&wpHashMapKeys(WpStr8, &map)[i], &keys[i]);
}
i32 new_value = 0;
wpHashMapInsertOrUpdateCapped(WpStr8, i32, &map, &keys[1], &new_value);
result = result && wpHashMapCapacity(&map) == 4 && wpHashMapCount(&map) == 3 &&
wpHashMapValues(i32, &map)[1] == new_value;
return wpTesterResult(result);
}
WpTestFuncResult test_hashmap_insert_alloc(void) {
WpAllocator arena = wpMemArenaAllocatorInit(KiB(4));
b8 result = true;
WpHashMap map = wpHashMap(WpStr8, i32, encoder, key_eq, 4);
WpStr8Array keys = wpArray(
WpStr8,
wpStr8Lit("key1"),
wpStr8Lit("key2"),
wpStr8Lit("key3"),
wpStr8Lit("key4")
);
WpI32Array values = wpArray(i32, 1, 2, 3, 4);
WpStr8Array map_keys = map.keys;
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashMapInsertAlloc(WpStr8, i32, &arena, &map, &keys[i], &values[i]);
}
result = result && map.keys != map_keys && wpHashMapCapacity(&map) == 8 && wpHashMapCount(&map) == 4;
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
result = result && wpStr8Equal(&wpHashMapKeys(WpStr8, &map)[i], &keys[i]) &&
wpHashMapValues(i32, &map)[i] == values[i];
}
wpMemArenaAllocatorDestroy(&arena);
return wpTesterResult(result);
}
WpTestFuncResult test_hashmap_insert_or_update_alloc(void) {
WpAllocator arena = wpMemArenaAllocatorInit(KiB(4));
b8 result = true;
WpHashMap map = wpHashMap(WpStr8, i32, encoder, key_eq, 4);
WpStr8Array keys = wpArray(
WpStr8,
wpStr8Lit("key1"),
wpStr8Lit("key2"),
wpStr8Lit("key3"),
wpStr8Lit("key4")
);
WpI32Array values = wpArray(i32, 1, 2, 3, 4);
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashMapInsertOrUpdateAlloc(WpStr8, i32, &arena, &map, &keys[i], &values[i]);
}
result = result && wpHashMapCapacity(&map) == 8 && wpHashMapCount(&map) == 4;
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
result = result && wpStr8Equal(&wpHashMapKeys(WpStr8, &map)[i], &keys[i]);
}
i32 new_value = 0;
wpHashMapInsertOrUpdateAlloc(WpStr8, i32, &arena, &map, &keys[1], &new_value);
result = result && wpHashMapCapacity(&map) == 8 && wpHashMapCount(&map) == 4 &&
wpHashMapValues(i32, &map)[1] == new_value;
wpMemArenaAllocatorDestroy(&arena);
return wpTesterResult(result);
}
WpTestFuncResult test_hashmap_remove(void) {
b8 result = true;
WpHashMap map = wpHashMap(WpStr8, i32, encoder, key_eq, 4);
WpStr8Array keys = wpArray(
WpStr8,
wpStr8Lit("key1"),
wpStr8Lit("key2"),
wpStr8Lit("key3"),
wpStr8Lit("key4")
);
WpI32Array values = wpArray(i32, 1, 2, 3, 4);
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashMapInsertCapped(WpStr8, i32, &map, &keys[i], &values[i]);
}
wpHashMapRemove(WpStr8, i32, &map, &keys[0]);
result = result && wpHashMapCapacity(&map) == 4 && wpHashMapCount(&map) == 2;
return wpTesterResult(result);
}
WpTestFuncResult test_hashmap_clear(void) {
b8 result = true;
WpHashMap map = wpHashMap(WpStr8, i32, encoder, key_eq, 8);
WpStr8Array keys = wpArray(
WpStr8,
wpStr8Lit("key1"),
wpStr8Lit("key2"),
wpStr8Lit("key3"),
wpStr8Lit("key4")
);
WpI32Array values = wpArray(i32, 1, 2, 3, 4);
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashMapInsertCapped(WpStr8, i32, &map, &keys[i], &values[i]);
}
wpHashMapClear(WpStr8, i32, &map);
result = result && wpHashMapCount(&map) == 0;
return wpTesterResult(result);
}
wp_persist inline WpU8Stream encoder(void *data) {
WpStr8 *str = (WpStr8 *)data;
return wpStream(u8, str->buf, str->size);
}
wp_persist inline b8 key_eq(void *a, void *b) {
WpStr8 *a_str = (WpStr8 *)a;
WpStr8 *b_str = (WpStr8 *)b;
return wpStr8Equal(a_str, b_str);
}
+250
View File
@@ -0,0 +1,250 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "wapp.h"
#include "test_hashmap.h"
wp_persist inline WpU8Stream encoder(void *data);
wp_persist inline b8 key_eq(void *a, void *b);
WpTestFuncResult test_hashmap(void) {
b8 result = true;
WpHashMap map = wpHashMap(WpStr8, i32, encoder, key_eq, 8);
result = result && wpHashMapCapacity(&map) == 8 && wpHashMapCount(&map) == 0;
map = wpHashMap(WpStr8, i32, encoder, key_eq, 3);
result = result && wpHashMapCapacity(&map) == 4 && wpHashMapCount(&map) == 0;
return wpTesterResult(result);
}
WpTestFuncResult test_hashmap_alloc(void) {
WpAllocator arena = wpMemArenaAllocatorInit(KiB(4));
b8 result = true;
WpHashMap map = wpHashMapAlloc(WpStr8, i32, &arena, encoder, key_eq, 8);
result = result && wpHashMapCapacity(&map) == 8 && wpHashMapCount(&map) == 0;
map = wpHashMapAlloc(WpStr8, i32, &arena, encoder, key_eq, 3);
result = result && wpHashMapCapacity(&map) == 4 && wpHashMapCount(&map) == 0;
wpMemArenaAllocatorDestroy(&arena);
return wpTesterResult(result);
}
WpTestFuncResult test_hashmap_get_key_size(void) {
b8 result = true;
WpHashMap map = wpHashMap(WpStr8, i32, encoder, key_eq, 8);
result = result && wpHashMapKeySize(&map) == sizeof(WpStr8);
return wpTesterResult(result);
}
WpTestFuncResult test_hashmap_get_value_size(void) {
b8 result = true;
WpHashMap map = wpHashMap(WpStr8, i32, encoder, key_eq, 8);
result = result && wpHashMapValueSize(&map) == sizeof(i32);
return wpTesterResult(result);
}
WpTestFuncResult test_hashmap_find(void) {
b8 result = true;
WpHashMap map = wpHashMap(WpStr8, i32, encoder, key_eq, 8);
WpStr8 key1 = wpStr8Lit("key1");
WpStr8 key2 = wpStr8Lit("key2");
WpStr8 key3 = wpStr8Lit("key3");
WpStr8 key4 = wpStr8Lit("key4");
WpStr8Array keys = wpArray(WpStr8, key1, key2, key3, key4);
WpI32Array values = wpArray(i32, 1, 2, 3, 4);
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashMapInsertCapped(WpStr8, i32, &map, &keys[i], &values[i]);
}
WpHashLookupResult res = wpHashMapFind(WpStr8, &map, &keys[3]);
result = result && res.found && res.ref.dist_and_tag > 0;
WpStr8 key = wpStr8Lit("key0");
res = wpHashMapFind(WpStr8, &map, &key);
result = result && !res.found;
return wpTesterResult(result);
}
WpTestFuncResult test_hashmap_update(void) {
b8 result = true;
WpHashMap map = wpHashMap(WpStr8, i32, encoder, key_eq, 4);
WpStr8 key1 = wpStr8Lit("key1");
WpStr8 key2 = wpStr8Lit("key2");
WpStr8 key3 = wpStr8Lit("key3");
WpStr8 key4 = wpStr8Lit("key4");
WpStr8Array keys = wpArray(WpStr8, key1, key2, key3, key4);
WpI32Array values = wpArray(i32, 1, 2, 3, 4);
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashMapInsertCapped(WpStr8, i32, &map, &keys[i], &values[i]);
}
i32 new_value = 0;
wpHashMapUpdate(WpStr8, i32, &map, &keys[1], &new_value);
result = result && wpHashMapCapacity(&map) == 4 && wpHashMapCount(&map) == 3 &&
wpHashMapValues(i32, &map)[1] == new_value;
return wpTesterResult(result);
}
WpTestFuncResult test_hashmap_insert_capped(void) {
b8 result = true;
WpHashMap map = wpHashMap(WpStr8, i32, encoder, key_eq, 4);
WpStr8 key1 = wpStr8Lit("key1");
WpStr8 key2 = wpStr8Lit("key2");
WpStr8 key3 = wpStr8Lit("key3");
WpStr8 key4 = wpStr8Lit("key4");
WpStr8Array keys = wpArray(WpStr8, key1, key2, key3, key4);
WpI32Array values = wpArray(i32, 1, 2, 3, 4);
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashMapInsertCapped(WpStr8, i32, &map, &keys[i], &values[i]);
}
result = result && wpHashMapCapacity(&map) == 4 && wpHashMapCount(&map) == 3;
for (u64 i = 0; i < 3; ++i) {
result = result && wpStr8Equal(wpArrayGet(WpStr8, map.keys, i), &keys[i]);
}
return wpTesterResult(result);
}
WpTestFuncResult test_hashmap_insert_or_update_capped(void) {
b8 result = true;
WpHashMap map = wpHashMap(WpStr8, i32, encoder, key_eq, 4);
WpStr8 key1 = wpStr8Lit("key1");
WpStr8 key2 = wpStr8Lit("key2");
WpStr8 key3 = wpStr8Lit("key3");
WpStr8 key4 = wpStr8Lit("key4");
WpStr8Array keys = wpArray(WpStr8, key1, key2, key3, key4);
WpI32Array values = wpArray(i32, 1, 2, 3, 4);
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashMapInsertOrUpdateCapped(WpStr8, i32, &map, &keys[i], &values[i]);
}
result = result && wpHashMapCapacity(&map) == 4 && wpHashMapCount(&map) == 3;
for (u64 i = 0; i < 3; ++i) {
result = result && wpStr8Equal(&wpHashMapKeys(WpStr8, &map)[i], &keys[i]);
}
i32 new_value = 0;
wpHashMapInsertOrUpdateCapped(WpStr8, i32, &map, &keys[1], &new_value);
result = result && wpHashMapCapacity(&map) == 4 && wpHashMapCount(&map) == 3 &&
wpHashMapValues(i32, &map)[1] == new_value;
return wpTesterResult(result);
}
WpTestFuncResult test_hashmap_insert_alloc(void) {
WpAllocator arena = wpMemArenaAllocatorInit(KiB(4));
b8 result = true;
WpHashMap map = wpHashMap(WpStr8, i32, encoder, key_eq, 4);
WpStr8 key1 = wpStr8Lit("key1");
WpStr8 key2 = wpStr8Lit("key2");
WpStr8 key3 = wpStr8Lit("key3");
WpStr8 key4 = wpStr8Lit("key4");
WpStr8Array keys = wpArray(WpStr8, key1, key2, key3, key4);
WpI32Array values = wpArray(i32, 1, 2, 3, 4);
WpStr8Array map_keys = (WpStr8Array)map.keys;
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashMapInsertAlloc(WpStr8, i32, &arena, &map, &keys[i], &values[i]);
}
result = result && map.keys != map_keys && wpHashMapCapacity(&map) == 8 && wpHashMapCount(&map) == 4;
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
result = result && wpStr8Equal(&wpHashMapKeys(WpStr8, &map)[i], &keys[i]) &&
wpHashMapValues(i32, &map)[i] == values[i];
}
wpMemArenaAllocatorDestroy(&arena);
return wpTesterResult(result);
}
WpTestFuncResult test_hashmap_insert_or_update_alloc(void) {
WpAllocator arena = wpMemArenaAllocatorInit(KiB(4));
b8 result = true;
WpHashMap map = wpHashMap(WpStr8, i32, encoder, key_eq, 4);
WpStr8 key1 = wpStr8Lit("key1");
WpStr8 key2 = wpStr8Lit("key2");
WpStr8 key3 = wpStr8Lit("key3");
WpStr8 key4 = wpStr8Lit("key4");
WpStr8Array keys = wpArray(WpStr8, key1, key2, key3, key4);
WpI32Array values = wpArray(i32, 1, 2, 3, 4);
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashMapInsertOrUpdateAlloc(WpStr8, i32, &arena, &map, &keys[i], &values[i]);
}
result = result && wpHashMapCapacity(&map) == 8 && wpHashMapCount(&map) == 4;
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
result = result && wpStr8Equal(&wpHashMapKeys(WpStr8, &map)[i], &keys[i]);
}
i32 new_value = 0;
wpHashMapInsertOrUpdateAlloc(WpStr8, i32, &arena, &map, &keys[1], &new_value);
result = result && wpHashMapCapacity(&map) == 8 && wpHashMapCount(&map) == 4 &&
wpHashMapValues(i32, &map)[1] == new_value;
wpMemArenaAllocatorDestroy(&arena);
return wpTesterResult(result);
}
WpTestFuncResult test_hashmap_remove(void) {
b8 result = true;
WpHashMap map = wpHashMap(WpStr8, i32, encoder, key_eq, 4);
WpStr8 key1 = wpStr8Lit("key1");
WpStr8 key2 = wpStr8Lit("key2");
WpStr8 key3 = wpStr8Lit("key3");
WpStr8 key4 = wpStr8Lit("key4");
WpStr8Array keys = wpArray(WpStr8, key1, key2, key3, key4);
WpI32Array values = wpArray(i32, 1, 2, 3, 4);
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashMapInsertCapped(WpStr8, i32, &map, &keys[i], &values[i]);
}
wpHashMapRemove(WpStr8, i32, &map, &keys[0]);
result = result && wpHashMapCapacity(&map) == 4 && wpHashMapCount(&map) == 2;
return wpTesterResult(result);
}
WpTestFuncResult test_hashmap_clear(void) {
b8 result = true;
WpHashMap map = wpHashMap(WpStr8, i32, encoder, key_eq, 8);
WpStr8 key1 = wpStr8Lit("key1");
WpStr8 key2 = wpStr8Lit("key2");
WpStr8 key3 = wpStr8Lit("key3");
WpStr8 key4 = wpStr8Lit("key4");
WpStr8Array keys = wpArray(WpStr8, key1, key2, key3, key4);
WpI32Array values = wpArray(i32, 1, 2, 3, 4);
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashMapInsertCapped(WpStr8, i32, &map, &keys[i], &values[i]);
}
wpHashMapClear(WpStr8, i32, &map);
result = result && wpHashMapCount(&map) == 0;
return wpTesterResult(result);
}
wp_persist inline WpU8Stream encoder(void *data) {
WpStr8 *str = (WpStr8 *)data;
return wpStream(u8, str->buf, str->size);
}
wp_persist inline b8 key_eq(void *a, void *b) {
WpStr8 *a_str = (WpStr8 *)a;
WpStr8 *b_str = (WpStr8 *)b;
return wpStr8Equal(a_str, b_str);
}
+21
View File
@@ -0,0 +1,21 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef TEST_HASHMAP_H
#define TEST_HASHMAP_H
#include "wapp.h"
WpTestFuncResult test_hashmap(void);
WpTestFuncResult test_hashmap_alloc(void);
WpTestFuncResult test_hashmap_get_key_size(void);
WpTestFuncResult test_hashmap_get_value_size(void);
WpTestFuncResult test_hashmap_find(void);
WpTestFuncResult test_hashmap_update(void);
WpTestFuncResult test_hashmap_insert_capped(void);
WpTestFuncResult test_hashmap_insert_or_update_capped(void);
WpTestFuncResult test_hashmap_insert_alloc(void);
WpTestFuncResult test_hashmap_insert_or_update_alloc(void);
WpTestFuncResult test_hashmap_remove(void);
WpTestFuncResult test_hashmap_clear(void);
#endif // !TEST_HASHMAP_H
+168
View File
@@ -0,0 +1,168 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "wapp.h"
#include "test_hashset.h"
wp_persist inline WpU8Stream encoder(void *data);
wp_persist inline b8 key_eq(void *a, void *b);
WpTestFuncResult test_hashset(void) {
b8 result = true;
WpHashSet set = wpHashSet(WpStr8, encoder, key_eq, 8);
result = result && wpHashSetCapacity(&set) == 8 && wpHashSetCount(&set) == 0;
set = wpHashSet(WpStr8, encoder, key_eq, 3);
result = result && wpHashSetCapacity(&set) == 4 && wpHashSetCount(&set) == 0;
return wpTesterResult(result);
}
WpTestFuncResult test_hashset_alloc(void) {
WpAllocator arena = wpMemArenaAllocatorInit(KiB(4));
b8 result = true;
WpHashSet set = wpHashSetAlloc(WpStr8, &arena, encoder, key_eq, 8);
result = result && wpHashSetCapacity(&set) == 8 && wpHashSetCount(&set) == 0;
set = wpHashSetAlloc(WpStr8, &arena, encoder, key_eq, 3);
result = result && wpHashSetCapacity(&set) == 4 && wpHashSetCount(&set) == 0;
wpMemArenaAllocatorDestroy(&arena);
return wpTesterResult(result);
}
WpTestFuncResult test_hashset_get_item_size(void) {
b8 result = true;
WpHashSet set = wpHashSet(WpStr8, encoder, key_eq, 8);
result = result && wpHashSetItemSize(&set) == sizeof(WpStr8);
return wpTesterResult(result);
}
WpTestFuncResult test_hashset_find(void) {
b8 result = true;
WpHashSet set = wpHashSet(WpStr8, encoder, key_eq, 8);
WpStr8Array keys = wpArray(
WpStr8,
wpStr8Lit("key1"),
wpStr8Lit("key2"),
wpStr8Lit("key3"),
wpStr8Lit("key4")
);
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashSetInsertCapped(WpStr8, &set, &keys[i]);
}
WpHashLookupResult res = wpHashSetFind(WpStr8, &set, &keys[3]);
result = result && res.found && res.ref.dist_and_tag > 0;
WpStr8 key = wpStr8Lit("key0");
res = wpHashSetFind(WpStr8, &set, &key);
result = result && !res.found;
return wpTesterResult(result);
}
WpTestFuncResult test_hashset_insert_capped(void) {
b8 result = true;
WpHashSet set = wpHashSet(WpStr8, encoder, key_eq, 4);
WpStr8Array keys = wpArray(
WpStr8,
wpStr8Lit("key1"),
wpStr8Lit("key2"),
wpStr8Lit("key3"),
wpStr8Lit("key4")
);
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashSetInsertCapped(WpStr8, &set, &keys[i]);
}
result = result && wpHashSetCapacity(&set) == 4 && wpHashSetCount(&set) == 3;
for (u64 i = 0; i < 3; ++i) {
result = result && wpStr8Equal(&wpHashSetItems(WpStr8, &set)[i], &keys[i]);
}
return wpTesterResult(result);
}
WpTestFuncResult test_hashset_insert_alloc(void) {
WpAllocator arena = wpMemArenaAllocatorInit(KiB(4));
b8 result = true;
WpHashSet set = wpHashSet(WpStr8, encoder, key_eq, 4);
WpStr8Array keys = wpArray(
WpStr8,
wpStr8Lit("key1"),
wpStr8Lit("key2"),
wpStr8Lit("key3"),
wpStr8Lit("key4")
);
WpStr8Array set_keys = set.keys;
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashSetInsertAlloc(WpStr8, &arena, &set, &keys[i]);
}
result = result && set.keys != set_keys && wpHashSetCapacity(&set) == 8 && wpHashSetCount(&set) == 4;
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
result = result && wpStr8Equal(&wpHashSetItems(WpStr8, &set)[i], &keys[i]);
}
wpMemArenaAllocatorDestroy(&arena);
return wpTesterResult(result);
}
WpTestFuncResult test_hashset_remove(void) {
b8 result = true;
WpHashSet set = wpHashSet(WpStr8, encoder, key_eq, 4);
WpStr8Array keys = wpArray(
WpStr8,
wpStr8Lit("key1"),
wpStr8Lit("key2"),
wpStr8Lit("key3"),
wpStr8Lit("key4")
);
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashSetInsertCapped(WpStr8, &set, &keys[i]);
}
wpHashSetRemove(WpStr8, &set, &keys[0]);
result = result && wpHashSetCapacity(&set) == 4 && wpHashSetCount(&set) == 2;
return wpTesterResult(result);
}
WpTestFuncResult test_hashset_clear(void) {
b8 result = true;
WpHashSet set = wpHashSet(WpStr8, encoder, key_eq, 8);
WpStr8Array keys = wpArray(
WpStr8,
wpStr8Lit("key1"),
wpStr8Lit("key2"),
wpStr8Lit("key3"),
wpStr8Lit("key4")
);
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashSetInsertCapped(WpStr8, &set, &keys[i]);
}
wpHashSetClear(WpStr8, &set);
result = result && wpHashSetCount(&set) == 0;
return wpTesterResult(result);
}
wp_persist inline WpU8Stream encoder(void *data) {
WpStr8 *str = (WpStr8 *)data;
return wpStream(u8, str->buf, str->size);
}
wp_persist inline b8 key_eq(void *a, void *b) {
WpStr8 *a_str = (WpStr8 *)a;
WpStr8 *b_str = (WpStr8 *)b;
return wpStr8Equal(a_str, b_str);
}
+158
View File
@@ -0,0 +1,158 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "wapp.h"
#include "test_hashset.h"
wp_persist inline WpU8Stream encoder(void *data);
wp_persist inline b8 key_eq(void *a, void *b);
WpTestFuncResult test_hashset(void) {
b8 result = true;
WpHashSet set = wpHashSet(WpStr8, encoder, key_eq, 8);
result = result && wpHashSetCapacity(&set) == 8 && wpHashSetCount(&set) == 0;
set = wpHashSet(WpStr8, encoder, key_eq, 3);
result = result && wpHashSetCapacity(&set) == 4 && wpHashSetCount(&set) == 0;
return wpTesterResult(result);
}
WpTestFuncResult test_hashset_alloc(void) {
WpAllocator arena = wpMemArenaAllocatorInit(KiB(4));
b8 result = true;
WpHashSet set = wpHashSetAlloc(WpStr8, &arena, encoder, key_eq, 8);
result = result && wpHashSetCapacity(&set) == 8 && wpHashSetCount(&set) == 0;
set = wpHashSetAlloc(WpStr8, &arena, encoder, key_eq, 3);
result = result && wpHashSetCapacity(&set) == 4 && wpHashSetCount(&set) == 0;
wpMemArenaAllocatorDestroy(&arena);
return wpTesterResult(result);
}
WpTestFuncResult test_hashset_get_item_size(void) {
b8 result = true;
WpHashSet set = wpHashSet(WpStr8, encoder, key_eq, 8);
result = result && wpHashSetItemSize(&set) == sizeof(WpStr8);
return wpTesterResult(result);
}
WpTestFuncResult test_hashset_find(void) {
b8 result = true;
WpHashSet set = wpHashSet(WpStr8, encoder, key_eq, 8);
WpStr8 key1 = wpStr8Lit("key1");
WpStr8 key2 = wpStr8Lit("key2");
WpStr8 key3 = wpStr8Lit("key3");
WpStr8 key4 = wpStr8Lit("key4");
WpStr8Array keys = wpArray(WpStr8, key1, key2, key3, key4);
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashSetInsertCapped(WpStr8, &set, &keys[i]);
}
WpHashLookupResult res = wpHashSetFind(WpStr8, &set, &keys[3]);
result = result && res.found && res.ref.dist_and_tag > 0;
WpStr8 key = wpStr8Lit("key0");
res = wpHashSetFind(WpStr8, &set, &key);
result = result && !res.found;
return wpTesterResult(result);
}
WpTestFuncResult test_hashset_insert_capped(void) {
b8 result = true;
WpHashSet set = wpHashSet(WpStr8, encoder, key_eq, 4);
WpStr8 key1 = wpStr8Lit("key1");
WpStr8 key2 = wpStr8Lit("key2");
WpStr8 key3 = wpStr8Lit("key3");
WpStr8 key4 = wpStr8Lit("key4");
WpStr8Array keys = wpArray(WpStr8, key1, key2, key3, key4);
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashSetInsertCapped(WpStr8, &set, &keys[i]);
}
result = result && wpHashSetCapacity(&set) == 4 && wpHashSetCount(&set) == 3;
for (u64 i = 0; i < 3; ++i) {
result = result && wpStr8Equal(&wpHashSetItems(WpStr8, &set)[i], &keys[i]);
}
return wpTesterResult(result);
}
WpTestFuncResult test_hashset_insert_alloc(void) {
WpAllocator arena = wpMemArenaAllocatorInit(KiB(4));
b8 result = true;
WpHashSet set = wpHashSet(WpStr8, encoder, key_eq, 4);
WpStr8 key1 = wpStr8Lit("key1");
WpStr8 key2 = wpStr8Lit("key2");
WpStr8 key3 = wpStr8Lit("key3");
WpStr8 key4 = wpStr8Lit("key4");
WpStr8Array keys = wpArray(WpStr8, key1, key2, key3, key4);
WpStr8Array set_keys = (WpStr8Array)set.keys;
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashSetInsertAlloc(WpStr8, &arena, &set, &keys[i]);
}
result = result && set.keys != set_keys && wpHashSetCapacity(&set) == 8 && wpHashSetCount(&set) == 4;
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
result = result && wpStr8Equal(&wpHashSetItems(WpStr8, &set)[i], &keys[i]);
}
wpMemArenaAllocatorDestroy(&arena);
return wpTesterResult(result);
}
WpTestFuncResult test_hashset_remove(void) {
b8 result = true;
WpHashSet set = wpHashSet(WpStr8, encoder, key_eq, 4);
WpStr8 key1 = wpStr8Lit("key1");
WpStr8 key2 = wpStr8Lit("key2");
WpStr8 key3 = wpStr8Lit("key3");
WpStr8 key4 = wpStr8Lit("key4");
WpStr8Array keys = wpArray(WpStr8, key1, key2, key3, key4);
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashSetInsertCapped(WpStr8, &set, &keys[i]);
}
wpHashSetRemove(WpStr8, &set, &keys[0]);
result = result && wpHashSetCapacity(&set) == 4 && wpHashSetCount(&set) == 2;
return wpTesterResult(result);
}
WpTestFuncResult test_hashset_clear(void) {
b8 result = true;
WpHashSet set = wpHashSet(WpStr8, encoder, key_eq, 8);
WpStr8 key1 = wpStr8Lit("key1");
WpStr8 key2 = wpStr8Lit("key2");
WpStr8 key3 = wpStr8Lit("key3");
WpStr8 key4 = wpStr8Lit("key4");
WpStr8Array keys = wpArray(WpStr8, key1, key2, key3, key4);
for (u64 i = 0; i < wpArrayCount(keys); ++i) {
wpHashSetInsertCapped(WpStr8, &set, &keys[i]);
}
wpHashSetClear(WpStr8, &set);
result = result && wpHashSetCount(&set) == 0;
return wpTesterResult(result);
}
wp_persist inline WpU8Stream encoder(void *data) {
WpStr8 *str = (WpStr8 *)data;
return wpStream(u8, str->buf, str->size);
}
wp_persist inline b8 key_eq(void *a, void *b) {
WpStr8 *a_str = (WpStr8 *)a;
WpStr8 *b_str = (WpStr8 *)b;
return wpStr8Equal(a_str, b_str);
}
+17
View File
@@ -0,0 +1,17 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef TEST_HASHSET_H
#define TEST_HASHSET_H
#include "wapp.h"
WpTestFuncResult test_hashset(void);
WpTestFuncResult test_hashset_alloc(void);
WpTestFuncResult test_hashset_get_item_size(void);
WpTestFuncResult test_hashset_find(void);
WpTestFuncResult test_hashset_insert_capped(void);
WpTestFuncResult test_hashset_insert_alloc(void);
WpTestFuncResult test_hashset_remove(void);
WpTestFuncResult test_hashset_clear(void);
#endif // !TEST_HASHSET_H
+22
View File
@@ -9,6 +9,8 @@
#include "test_cpath.h" #include "test_cpath.h"
#include "test_file.h" #include "test_file.h"
#include "test_hasher.h" #include "test_hasher.h"
#include "test_hashset.h"
#include "test_hashmap.h"
#include "test_shell_commander.h" #include "test_shell_commander.h"
#include "wapp.h" #include "wapp.h"
#include <stdlib.h> #include <stdlib.h>
@@ -105,6 +107,26 @@ int main(void) {
test_wapp_file_remove, test_wapp_file_remove,
test_murmur3, test_murmur3,
test_siphash_128, test_siphash_128,
test_hashset,
test_hashset_alloc,
test_hashset_get_item_size,
test_hashset_find,
test_hashset_insert_capped,
test_hashset_insert_alloc,
test_hashset_remove,
test_hashset_clear,
test_hashmap,
test_hashmap_alloc,
test_hashmap_get_key_size,
test_hashmap_get_value_size,
test_hashmap_find,
test_hashmap_update,
test_hashmap_insert_capped,
test_hashmap_insert_or_update_capped,
test_hashmap_insert_alloc,
test_hashmap_insert_or_update_alloc,
test_hashmap_remove,
test_hashmap_clear,
test_commander_cmd_success, test_commander_cmd_success,
test_commander_cmd_failure, test_commander_cmd_failure,
test_commander_cmd_out_buf_success, test_commander_cmd_out_buf_success,
+22
View File
@@ -9,6 +9,8 @@
#include "test_cpath.h" #include "test_cpath.h"
#include "test_file.h" #include "test_file.h"
#include "test_hasher.h" #include "test_hasher.h"
#include "test_hashset.h"
#include "test_hashmap.h"
#include "test_shell_commander.h" #include "test_shell_commander.h"
#include "wapp.h" #include "wapp.h"
#include <stdlib.h> #include <stdlib.h>
@@ -105,6 +107,26 @@ int main(void) {
test_wapp_file_remove, test_wapp_file_remove,
test_murmur3, test_murmur3,
test_siphash_128, test_siphash_128,
test_hashset,
test_hashset_alloc,
test_hashset_get_item_size,
test_hashset_find,
test_hashset_insert_capped,
test_hashset_insert_alloc,
test_hashset_remove,
test_hashset_clear,
test_hashmap,
test_hashmap_alloc,
test_hashmap_get_key_size,
test_hashmap_get_value_size,
test_hashmap_find,
test_hashmap_update,
test_hashmap_insert_capped,
test_hashmap_insert_or_update_capped,
test_hashmap_insert_alloc,
test_hashmap_insert_or_update_alloc,
test_hashmap_remove,
test_hashmap_clear,
test_commander_cmd_success, test_commander_cmd_success,
test_commander_cmd_failure, test_commander_cmd_failure,
test_commander_cmd_out_buf_success, test_commander_cmd_out_buf_success,