aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hash.c157
1 files changed, 115 insertions, 42 deletions
diff --git a/src/hash.c b/src/hash.c
index 8940d70..2feeee8 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -1,62 +1,135 @@
-// murmur3 originally by Austin Appleby
-// Copyright (c) 2013, ksss
-// Copyright (c) 2023, Marvin Borner <dev@marvinborner.de>
-// SPDX-License-Identifier: MIT
+//-----------------------------------------------------------------------------
+// xxHash Library
+// Copyright (c) 2012-2021 Yann Collet
+// All rights reserved.
+//
+// BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php)
+//
+// xxHash3
+//-----------------------------------------------------------------------------
#include <stdint.h>
+#include <string.h>
#include <hash.h>
-hash_t hash(const void *key, int len, uint64_t seed)
+#define XXH_PRIME_1 11400714785074694791ULL
+#define XXH_PRIME_2 14029467366897019727ULL
+#define XXH_PRIME_3 1609587929392839161ULL
+#define XXH_PRIME_4 9650029242287828579ULL
+#define XXH_PRIME_5 2870177450012600261ULL
+
+static uint64_t XXH_read64(const void *memptr)
{
- const uint64_t m = 0xc6a4a7935bd1e995ULL;
- const int r = 47;
+ uint64_t val;
+ memcpy(&val, memptr, sizeof(val));
+ return val;
+}
- uint64_t h = seed ^ (len * m);
+static uint32_t XXH_read32(const void *memptr)
+{
+ uint32_t val;
+ memcpy(&val, memptr, sizeof(val));
+ return val;
+}
- const uint64_t *data = (const uint64_t *)key;
- const uint64_t *end = data + (len / 8);
+static uint64_t XXH_rotl64(uint64_t x, int r)
+{
+ return (x << r) | (x >> (64 - r));
+}
- while (data != end) {
- uint64_t k = *data++;
+hash_t hash(const void *data, size_t len, uint64_t seed)
+{
+ const uint8_t *p = (const uint8_t *)data;
+ const uint8_t *const end = p + len;
+ uint64_t h64;
- k *= m;
- k ^= k >> r;
- k *= m;
+ if (len >= 32) {
+ const uint8_t *const limit = end - 32;
+ uint64_t v1 = seed + XXH_PRIME_1 + XXH_PRIME_2;
+ uint64_t v2 = seed + XXH_PRIME_2;
+ uint64_t v3 = seed + 0;
+ uint64_t v4 = seed - XXH_PRIME_1;
- h ^= k;
- h *= m;
- }
+ do {
+ v1 += XXH_read64(p) * XXH_PRIME_2;
+ v1 = XXH_rotl64(v1, 31);
+ v1 *= XXH_PRIME_1;
- const unsigned char *data2 = (const unsigned char *)data;
+ v2 += XXH_read64(p + 8) * XXH_PRIME_2;
+ v2 = XXH_rotl64(v2, 31);
+ v2 *= XXH_PRIME_1;
- int b = len & 7;
- if (b >= 7) {
- h ^= ((uint64_t)data2[6]) << 48;
- }
- if (b >= 6) {
- h ^= ((uint64_t)data2[5]) << 40;
- }
- if (b >= 5) {
- h ^= ((uint64_t)data2[4]) << 32;
- }
- if (b >= 4) {
- h ^= ((uint64_t)data2[3]) << 24;
+ v3 += XXH_read64(p + 16) * XXH_PRIME_2;
+ v3 = XXH_rotl64(v3, 31);
+ v3 *= XXH_PRIME_1;
+
+ v4 += XXH_read64(p + 24) * XXH_PRIME_2;
+ v4 = XXH_rotl64(v4, 31);
+ v4 *= XXH_PRIME_1;
+
+ p += 32;
+ } while (p <= limit);
+
+ h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) +
+ XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
+
+ v1 *= XXH_PRIME_2;
+ v1 = XXH_rotl64(v1, 31);
+ v1 *= XXH_PRIME_1;
+ h64 ^= v1;
+ h64 = h64 * XXH_PRIME_1 + XXH_PRIME_4;
+
+ v2 *= XXH_PRIME_2;
+ v2 = XXH_rotl64(v2, 31);
+ v2 *= XXH_PRIME_1;
+ h64 ^= v2;
+ h64 = h64 * XXH_PRIME_1 + XXH_PRIME_4;
+
+ v3 *= XXH_PRIME_2;
+ v3 = XXH_rotl64(v3, 31);
+ v3 *= XXH_PRIME_1;
+ h64 ^= v3;
+ h64 = h64 * XXH_PRIME_1 + XXH_PRIME_4;
+
+ v4 *= XXH_PRIME_2;
+ v4 = XXH_rotl64(v4, 31);
+ v4 *= XXH_PRIME_1;
+ h64 ^= v4;
+ h64 = h64 * XXH_PRIME_1 + XXH_PRIME_4;
+ } else {
+ h64 = seed + XXH_PRIME_5;
}
- if (b >= 3) {
- h ^= ((uint64_t)data2[2]) << 16;
+
+ h64 += (uint64_t)len;
+
+ while (p + 8 <= end) {
+ uint64_t k1 = XXH_read64(p);
+ k1 *= XXH_PRIME_2;
+ k1 = XXH_rotl64(k1, 31);
+ k1 *= XXH_PRIME_1;
+ h64 ^= k1;
+ h64 = XXH_rotl64(h64, 27) * XXH_PRIME_1 + XXH_PRIME_4;
+ p += 8;
}
- if (b >= 2) {
- h ^= ((uint64_t)data2[1]) << 8;
+
+ if (p + 4 <= end) {
+ h64 ^= (uint64_t)(XXH_read32(p)) * XXH_PRIME_1;
+ h64 = XXH_rotl64(h64, 23) * XXH_PRIME_2 + XXH_PRIME_3;
+ p += 4;
}
- if (b >= 1) {
- h ^= ((uint64_t)data2[0]);
- h *= m;
+
+ while (p < end) {
+ h64 ^= (*p) * XXH_PRIME_5;
+ h64 = XXH_rotl64(h64, 11) * XXH_PRIME_1;
+ p++;
}
- h ^= h >> r;
- h *= m;
- h ^= h >> r;
+ h64 ^= h64 >> 33;
+ h64 *= XXH_PRIME_2;
+ h64 ^= h64 >> 29;
+ h64 *= XXH_PRIME_3;
+ h64 ^= h64 >> 32;
- return h;
+ return h64;
}