|
|
|
@ -87,7 +87,7 @@ struct hashmap *hashmap_new_with_allocator(
|
|
|
|
|
_malloc = _malloc ? _malloc : malloc;
|
|
|
|
|
_realloc = _realloc ? _realloc : realloc;
|
|
|
|
|
_free = _free ? _free : free;
|
|
|
|
|
int ncap = 16;
|
|
|
|
|
size_t ncap = 16;
|
|
|
|
|
if (cap < ncap) {
|
|
|
|
|
cap = ncap;
|
|
|
|
|
} else {
|
|
|
|
@ -504,12 +504,12 @@ static uint64_t SIP64(const uint8_t *in, const size_t inlen,
|
|
|
|
|
const int left = inlen & 7;
|
|
|
|
|
uint64_t b = ((uint64_t)inlen) << 56;
|
|
|
|
|
switch (left) {
|
|
|
|
|
case 7: b |= ((uint64_t)in[6]) << 48;
|
|
|
|
|
case 6: b |= ((uint64_t)in[5]) << 40;
|
|
|
|
|
case 5: b |= ((uint64_t)in[4]) << 32;
|
|
|
|
|
case 4: b |= ((uint64_t)in[3]) << 24;
|
|
|
|
|
case 3: b |= ((uint64_t)in[2]) << 16;
|
|
|
|
|
case 2: b |= ((uint64_t)in[1]) << 8;
|
|
|
|
|
case 7: b |= ((uint64_t)in[6]) << 48; /* fall through */
|
|
|
|
|
case 6: b |= ((uint64_t)in[5]) << 40; /* fall through */
|
|
|
|
|
case 5: b |= ((uint64_t)in[4]) << 32; /* fall through */
|
|
|
|
|
case 4: b |= ((uint64_t)in[3]) << 24; /* fall through */
|
|
|
|
|
case 3: b |= ((uint64_t)in[2]) << 16; /* fall through */
|
|
|
|
|
case 2: b |= ((uint64_t)in[1]) << 8; /* fall through */
|
|
|
|
|
case 1: b |= ((uint64_t)in[0]); break;
|
|
|
|
|
case 0: break;
|
|
|
|
|
}
|
|
|
|
@ -564,25 +564,29 @@ static void MM86128(const void *key, const int len, uint32_t seed, void *out) {
|
|
|
|
|
uint32_t k3 = 0;
|
|
|
|
|
uint32_t k4 = 0;
|
|
|
|
|
switch(len & 15) {
|
|
|
|
|
case 15: k4 ^= tail[14] << 16;
|
|
|
|
|
case 14: k4 ^= tail[13] << 8;
|
|
|
|
|
case 15: k4 ^= tail[14] << 16; /* fall through */
|
|
|
|
|
case 14: k4 ^= tail[13] << 8; /* fall through */
|
|
|
|
|
case 13: k4 ^= tail[12] << 0;
|
|
|
|
|
k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
|
|
|
|
|
case 12: k3 ^= tail[11] << 24;
|
|
|
|
|
case 11: k3 ^= tail[10] << 16;
|
|
|
|
|
case 10: k3 ^= tail[ 9] << 8;
|
|
|
|
|
/* fall through */
|
|
|
|
|
case 12: k3 ^= tail[11] << 24; /* fall through */
|
|
|
|
|
case 11: k3 ^= tail[10] << 16; /* fall through */
|
|
|
|
|
case 10: k3 ^= tail[ 9] << 8; /* fall through */
|
|
|
|
|
case 9: k3 ^= tail[ 8] << 0;
|
|
|
|
|
k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
|
|
|
|
|
case 8: k2 ^= tail[ 7] << 24;
|
|
|
|
|
case 7: k2 ^= tail[ 6] << 16;
|
|
|
|
|
case 6: k2 ^= tail[ 5] << 8;
|
|
|
|
|
/* fall through */
|
|
|
|
|
case 8: k2 ^= tail[ 7] << 24; /* fall through */
|
|
|
|
|
case 7: k2 ^= tail[ 6] << 16; /* fall through */
|
|
|
|
|
case 6: k2 ^= tail[ 5] << 8; /* fall through */
|
|
|
|
|
case 5: k2 ^= tail[ 4] << 0;
|
|
|
|
|
k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
|
|
|
|
|
case 4: k1 ^= tail[ 3] << 24;
|
|
|
|
|
case 3: k1 ^= tail[ 2] << 16;
|
|
|
|
|
case 2: k1 ^= tail[ 1] << 8;
|
|
|
|
|
/* fall through */
|
|
|
|
|
case 4: k1 ^= tail[ 3] << 24; /* fall through */
|
|
|
|
|
case 3: k1 ^= tail[ 2] << 16; /* fall through */
|
|
|
|
|
case 2: k1 ^= tail[ 1] << 8; /* fall through */
|
|
|
|
|
case 1: k1 ^= tail[ 0] << 0;
|
|
|
|
|
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
|
|
|
|
|
/* fall through */
|
|
|
|
|
};
|
|
|
|
|
h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len;
|
|
|
|
|
h1 += h2; h1 += h3; h1 += h4;
|
|
|
|
@ -607,6 +611,7 @@ uint64_t hashmap_sip(const void *data, size_t len,
|
|
|
|
|
uint64_t hashmap_murmur(const void *data, size_t len,
|
|
|
|
|
uint64_t seed0, uint64_t seed1)
|
|
|
|
|
{
|
|
|
|
|
(void)seed1;
|
|
|
|
|
char out[16];
|
|
|
|
|
MM86128(data, len, seed0, &out);
|
|
|
|
|
return *(uint64_t*)out;
|
|
|
|
@ -629,9 +634,12 @@ static size_t deepcount(struct hashmap *map) {
|
|
|
|
|
return count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#pragma GCC diagnostic ignored "-Wextra"
|
|
|
|
|
|
|
|
|
|
#ifdef __GNUC__
|
|
|
|
|
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef __clang__
|
|
|
|
|
#pragma GCC diagnostic ignored "-Wcompound-token-split-by-macro"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
@ -682,10 +690,6 @@ static bool iter_ints(const void *item, void *udata) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int compare_ints(const void *a, const void *b) {
|
|
|
|
|
return *(int*)a - *(int*)b;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int compare_ints_udata(const void *a, const void *b, void *udata) {
|
|
|
|
|
return *(int*)a - *(int*)b;
|
|
|
|
|
}
|
|
|
|
@ -731,7 +735,7 @@ static void all() {
|
|
|
|
|
shuffle(vals, N, sizeof(int));
|
|
|
|
|
for (int i = 0; i < N; i++) {
|
|
|
|
|
// // printf("== %d ==\n", vals[i]);
|
|
|
|
|
assert(map->count == i);
|
|
|
|
|
assert(map->count == (size_t)i);
|
|
|
|
|
assert(map->count == hashmap_count(map));
|
|
|
|
|
assert(map->count == deepcount(map));
|
|
|
|
|
int *v;
|
|
|
|
@ -766,7 +770,7 @@ static void all() {
|
|
|
|
|
assert(!hashmap_get(map, &vals[i]));
|
|
|
|
|
assert(!hashmap_delete(map, &vals[i]));
|
|
|
|
|
assert(!hashmap_set(map, &vals[i]));
|
|
|
|
|
assert(map->count == i+1);
|
|
|
|
|
assert(map->count == (size_t)(i+1));
|
|
|
|
|
assert(map->count == hashmap_count(map));
|
|
|
|
|
assert(map->count == deepcount(map));
|
|
|
|
|
}
|
|
|
|
@ -793,7 +797,7 @@ static void all() {
|
|
|
|
|
v = hashmap_delete(map, &vals[i]);
|
|
|
|
|
assert(v && *v == vals[i]);
|
|
|
|
|
assert(!hashmap_get(map, &vals[i]));
|
|
|
|
|
assert(map->count == N-i-1);
|
|
|
|
|
assert(map->count == (size_t)(N-i-1));
|
|
|
|
|
assert(map->count == hashmap_count(map));
|
|
|
|
|
assert(map->count == deepcount(map));
|
|
|
|
|
for (int j = N-1; j > i; j--) {
|
|
|
|
|