Restructure hasher implementation
Release / release (push) Successful in 3s

This commit is contained in:
Abdelrahman Said
2026-09-23 00:02:37 +01:00
parent 9881c0ac9a
commit c215486442
9 changed files with 175 additions and 144 deletions
+14 -4
View File
@@ -3,13 +3,23 @@
#include "hasher.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");
return hasher->func(stream, hasher->data);
return hasher->func(stream, hasher->ctx);
}
u64 wpHasherGetHash64(const WpHasher *hasher, WpU8Stream *stream) {
wpDebugAssert(hasher != NULL && stream != NULL, "hasher and stream shouldn't be NULL");
WpU128Hash result = hasher->func(stream, hasher->data);
return result.hash[0] ^ result.hash[1];
WpU128 result = hasher->func(stream, hasher->ctx);
return result.value[0] ^ result.value[1];
}
+33 -8
View File
@@ -4,24 +4,49 @@
#define HASHER_H
#include "../../stream/stream.h"
#include "../../../common/aliases/aliases.h"
#ifdef WP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WP_PLATFORM_CPP
typedef struct WpU128Hash {
u64 hash[2];
} WpU128Hash;
typedef struct WpU128 {
u64 value[2];
} 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 {
WpHashFunc func;
void *data;
WpHashFunc func;
WpHasherCtx ctx;
} WpHasher;
WpU128Hash wpHasherGetHash128(const WpHasher *hasher, WpU8Stream *stream);
u64 wpHasherGetHash64 (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);
#ifdef WP_PLATFORM_CPP
END_C_LINKAGE
+23 -11
View File
@@ -5,22 +5,34 @@
#include "../../../common/aliases/aliases.h"
#include "../../../common/assert/assert.h"
#include "../../../common/misc/misc_utils.h"
#include "../../../prng/xorshift/xorshift.h"
wp_intern inline void validateMur3HasherCtx(const WpMur3HasherCtx *io);
wp_intern inline void validateMur3HasherCtx(const WpHasherCtx *ctx);
wp_intern inline u64 fmix64(u64 k);
WpHasher wpX64Mur3Hasher(WpMur3HasherCtx *data) {
return (WpHasher){ .func = wpX64Mur3Hasher128, .data = (void *)data };
WpHasher wpX64Mur3Hasher(void) {
WpXor256State state = wpPrngXorshiftInit();
u32 seed = (u32)wpPrngXorshift256(&state);
return wpX64Mur3HasherWithSeed(seed);
}
WpU128Hash wpX64Mur3Hasher128(WpU8Stream *bytes, void *hasher_io) {
WpMur3HasherCtx *io = (WpMur3HasherCtx *)hasher_io;
validateMur3HasherCtx(io);
WpHasher wpX64Mur3HasherWithSeed(u32 seed) {
return (WpHasher){
.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;
u64 h1 = io->seed;
u64 h2 = io->seed;
u64 h1 = ctx.murmur3;
u64 h2 = ctx.murmur3;
const u64 c1 = wpU64Const(0x87c37b91114253d5);
const u64 c2 = wpU64Const(0x4cf5ad432745937f);
@@ -96,11 +108,11 @@ WpU128Hash wpX64Mur3Hasher128(WpU8Stream *bytes, void *hasher_io) {
h1 += h2;
h2 += h1;
return (WpU128Hash){ .hash = { [0] = h1, [1] = h2 } };
return (WpU128){ .value = { [0] = h1, [1] = h2 } };
}
wp_intern inline void validateMur3HasherCtx(const WpMur3HasherCtx *ctx) {
wpRuntimeAssert(ctx->magic == WP_MUR3_HASHER_MAGIC, "Invalid Murmur3 hash context");
wp_intern inline void validateMur3HasherCtx(const WpHasherCtx *ctx) {
wpRuntimeAssert(ctx->type == WP_HASHER_CTX_MURMUR3, "Invalid Murmur3 hash context");
}
wp_intern inline u64 fmix64(u64 k) {
+3 -15
View File
@@ -17,21 +17,9 @@
BEGIN_C_LINKAGE
#endif // !WP_PLATFORM_CPP
#define WP_MUR3_HASHER_MAGIC wpU64Const(0x57504d4841534833)
typedef struct WpMur3HasherCtx {
u64 magic;
u32 seed;
} WpMur3HasherCtx;
#ifdef WP_PLATFORM_CPP
#define wpMur3HasherCtx(SEED) (WpMur3HasherCtx{WP_MUR3_HASHER_MAGIC, SEED})
#else
#define wpMur3HasherCtx(SEED) ((WpMur3HasherCtx){ .magic = WP_MUR3_HASHER_MAGIC, .seed = SEED })
#endif
WpHasher wpX64Mur3Hasher(WpMur3HasherCtx *ctx);
WpU128Hash wpX64Mur3Hasher128(WpU8Stream *bytes, void *hasher_io);
WpHasher wpX64Mur3Hasher(void);
WpHasher wpX64Mur3HasherWithSeed(u32 seed);
WpU128 wpX64Mur3GetHash128(WpU8Stream *bytes, WpHasherCtx ctx);
#ifdef WP_PLATFORM_CPP
END_C_LINKAGE
+49 -22
View File
@@ -5,10 +5,11 @@
#include "../../../common/aliases/aliases.h"
#include "../../../common/assert/assert.h"
#include "../../../common/misc/misc_utils.h"
#include "../../../prng/xorshift/xorshift.h"
wp_intern inline void siphash(WpStream *bytes, const WpSipHasherCtx *params, u8 *out, u64 outlen);
wp_intern inline void validateSipHasherCtx(const WpSipHasherCtx *io);
wp_intern inline b8 checkRounds(const WpSipHasherCtx *params);
wp_intern inline void siphash(WpStream *bytes, const WpHasherCtx *ctx, u8 *out, u64 outlen);
wp_intern inline void validateSipHasherCtx(const WpHasherCtx *ctx);
wp_intern inline b8 checkRounds(const WpHasherCtx *ctx);
#define _u32To8LE(p, v) \
(p)[0] = (u8)((v)); \
@@ -44,24 +45,50 @@ wp_intern inline b8 checkRounds(const WpSipHasherCtx *params);
v2 = wpMiscUtilsRotl64(v2, 32); \
} while (0)
WpHasher wpSipHasher(WpSipHasherCtx *data) {
return (WpHasher){ .func = wpSipHasher128, .data = (void *)data };
WpHasher wpSip24Hasher(void) {
WpXor256State state = wpPrngXorshiftInit();
WpU128 key = { .value = { wpPrngXorshift256(&state), wpPrngXorshift256(&state) } };
return wpSip24HasherWithKey(key);
}
WpU128Hash wpSipHasher128(WpStream *bytes, void *hasher_data) {
WpSipHasherCtx *data = (WpSipHasherCtx *)hasher_data;
validateSipHasherCtx(data);
WpU128Hash output = {0};
siphash(bytes, data, (u8 *)&output.hash, sizeof(u64) * 2);
WpHasher wpSip48Hasher(void) {
WpXor256State state = wpPrngXorshiftInit();
WpU128 key = { .value = { wpPrngXorshift256(&state), wpPrngXorshift256(&state) } };
return wpSip48HasherWithKey(key);
}
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;
}
/**
* Implementation of the 128-variant of the siphash algorithm
*/
wp_intern inline void siphash(WpStream *bytes, const WpSipHasherCtx *params, u8 *out,
u64 outlen) {
const u8 *kk = (const u8 *)&params->key;
wp_intern inline void siphash(WpStream *bytes, const WpHasherCtx *ctx, u8 *out, u64 outlen) {
const u8 *kk = (const u8 *)&ctx->siphash.key;
u64 inlen = bytes->count * bytes->item_size;
wpRuntimeAssert(outlen == 16, "outlen should be 16");
@@ -89,7 +116,7 @@ wp_intern inline void siphash(WpStream *bytes, const WpSipHasherCtx *params, u8
m = _u8To64LE(data);
v3 ^= m;
for (i = 0; i < params->compression; ++i) {
for (i = 0; i < ctx->siphash.compression; ++i) {
_sipRound;
}
@@ -125,7 +152,7 @@ wp_intern inline void siphash(WpStream *bytes, const WpSipHasherCtx *params, u8
v3 ^= b;
for (i = 0; i < params->compression; ++i) {
for (i = 0; i < ctx->siphash.compression; ++i) {
_sipRound;
}
@@ -133,7 +160,7 @@ wp_intern inline void siphash(WpStream *bytes, const WpSipHasherCtx *params, u8
v2 ^= 0xee;
for (i = 0; i < params->finalisation; ++i) {
for (i = 0; i < ctx->siphash.finalisation; ++i) {
_sipRound;
}
@@ -142,7 +169,7 @@ wp_intern inline void siphash(WpStream *bytes, const WpSipHasherCtx *params, u8
v1 ^= 0xdd;
for (i = 0; i < params->finalisation; ++i) {
for (i = 0; i < ctx->siphash.finalisation; ++i) {
_sipRound;
}
@@ -150,14 +177,14 @@ wp_intern inline void siphash(WpStream *bytes, const WpSipHasherCtx *params, u8
_u64To8LE(out + 8, b);
}
wp_intern inline void validateSipHasherCtx(const WpSipHasherCtx *ctx) {
b8 magic_match = ctx->magic == WP_SIP_HASHER_MAGIC;
wp_intern inline void validateSipHasherCtx(const WpHasherCtx *ctx) {
b8 magic_match = ctx->type == WP_HASHER_CTX_SIPHASH;
b8 rounds = checkRounds(ctx);
wpRuntimeAssert(magic_match && rounds, "Invalid Siphash context");
}
wp_intern inline b8 checkRounds(const WpSipHasherCtx *ctx) {
b8 rounds24 = ctx->compression == 2 && ctx->finalisation == 4;
b8 rounds48 = ctx->compression == 4 && ctx->finalisation == 8;
wp_intern inline b8 checkRounds(const WpHasherCtx *ctx) {
b8 rounds24 = ctx->siphash.compression == 2 && ctx->siphash.finalisation == 4;
b8 rounds48 = ctx->siphash.compression == 4 && ctx->siphash.finalisation == 8;
return rounds24 || rounds48;
}
+5 -35
View File
@@ -10,47 +10,17 @@
#include "hasher.h"
#include "../../stream/stream.h"
#include "../../../common/aliases/aliases.h"
#include "../../../common/platform/platform.h"
#ifdef WP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WP_PLATFORM_CPP
#define WP_SIP_HASHER_MAGIC wpU64Const(0x5750534950485348)
typedef struct WpSipHasherKey {
u64 lo;
u64 hi;
} WpSipHasherKey;
typedef struct WpSipHasherCtx {
WpSipHasherKey key;
u64 magic;
u64 compression;
u64 finalisation;
} WpSipHasherCtx;
#ifdef WP_PLATFORM_CPP
#define wpSip24HasherCtx(KEY) (WpSipHasherCtx{(KEY), WP_SIP_HASHER_MAGIC, 2, 4})
#define wpSip48HasherCtx(KEY) (WpSipHasherCtx{(KEY), WP_SIP_HASHER_MAGIC, 4, 8})
#else
#define wpSip24HasherCtx(KEY) ((WpSipHasherCtx){ \
.key = (KEY), \
.magic = WP_SIP_HASHER_MAGIC, \
.compression = 2, \
.finalisation = 4, \
})
#define wpSip48HasherCtx(KEY) ((WpSipHasherCtx){ \
.key = (KEY), \
.magic = WP_SIP_HASHER_MAGIC, \
.compression = 4, \
.finalisation = 8, \
})
#endif
WpHasher wpSipHasher(WpSipHasherCtx *ctx);
WpU128Hash wpSipHasher128(WpU8Stream *bytes, void *hasher_io);
WpHasher wpSip24Hasher(void);
WpHasher wpSip48Hasher(void);
WpHasher wpSip24HasherWithKey(WpU128 key);
WpHasher wpSip48HasherWithKey(WpU128 key);
WpU128 wpSipGetHash128(WpU8Stream *bytes, WpHasherCtx ctx);
#ifdef WP_PLATFORM_CPP
END_C_LINKAGE