14 #define HASH_FUNC_COEFF_P 32212254719ULL
17 #define INIT_BUCKETS_NUM 10
20 #define MIN_HASHSET_THRESHOLD 5
23 #define MAX_HASHSET_THRESHOLD 10
41 size_t sz =
sizeof(
struct buckets) +
47 D_RW(hashmap)->seed = seed;
49 D_RW(hashmap)->hash_fun_a = (
uint32_t)rand();
50 }
while (D_RW(hashmap)->hash_fun_a == 0);
51 D_RW(hashmap)->hash_fun_b = (
uint32_t)rand();
54 D_RW(hashmap)->buckets = TX_ZALLOC(
struct buckets, sz);
55 D_RW(D_RW(hashmap)->
buckets)->nbuckets = len;
57 fprintf(stderr,
"%s: create transaction aborted: %s\n", __func__,
79 uint32_t a = D_RO(*hashmap)->hash_fun_a;
80 uint32_t b = D_RO(*hashmap)->hash_fun_b;
81 uint64_t p = D_RO(*hashmap)->hash_fun_p;
82 size_t len = D_RO(*buckets)->nbuckets;
84 return ((a * value + b) % p) % len;
104 TOID(
struct buckets) buckets_old = D_RO(hashmap)->buckets;
107 new_len = D_RO(buckets_old)->nbuckets;
109 size_t sz_old =
sizeof(
struct buckets) +
112 size_t sz_new =
sizeof(
struct buckets) +
116 TX_ADD_FIELD(hashmap,
buckets);
118 TX_ZALLOC(
struct buckets, sz_new);
119 D_RW(buckets_new)->nbuckets = new_len;
120 pmemobj_tx_add_range(buckets_old.oid, 0, sz_old);
122 for (
size_t i = 0; i < D_RO(buckets_old)->
nbuckets; ++i) {
123 while (!TOID_IS_NULL(D_RO(buckets_old)->bucket[i])) {
125 D_RO(buckets_old)->bucket[i];
129 D_RW(buckets_old)->bucket[i] = D_RO(en)->next;
131 TX_ADD_FIELD(en, next);
132 D_RW(en)->next = D_RO(buckets_new)->bucket[h];
133 D_RW(buckets_new)->bucket[h] = en;
137 D_RW(hashmap)->buckets = buckets_new;
138 TX_FREE(buckets_old);
140 fprintf(stderr,
"%s: rebuild transaction aborted: %s\n", __func__,
173 for (var = D_RO(
buckets)->bucket[h];
175 var = D_RO(var)->next) {
176 if (D_RO(var)->key == key)
183 TX_ADD_FIELD(D_RO(hashmap)->
buckets, bucket[h]);
184 TX_ADD_FIELD(hashmap, count);
188 D_RW(e)->value = value;
189 D_RW(e)->next = D_RO(
buckets)->bucket[h];
192 D_RW(hashmap)->count++;
195 fprintf(stderr,
"insert transaction aborted: %s\n",
230 for (var = D_RO(
buckets)->bucket[h];
232 prev = var, var = D_RO(var)->next) {
233 if (D_RO(var)->key == key)
237 if (TOID_IS_NULL(var))
241 MEMoid retoid = D_RO(var)->value;
243 if (TOID_IS_NULL(prev))
244 TX_ADD_FIELD(D_RO(hashmap)->
buckets, bucket[h]);
246 TX_ADD_FIELD(prev, next);
247 TX_ADD_FIELD(hashmap, count);
249 if (TOID_IS_NULL(prev))
250 D_RW(
buckets)->bucket[h] = D_RO(var)->next;
252 D_RW(prev)->next = D_RO(var)->next;
253 D_RW(hashmap)->count--;
256 fprintf(stderr,
"remove transaction aborted: %s\n",
288 for (
size_t i = 0; i < D_RO(
buckets)->nbuckets; ++i) {
289 if (TOID_IS_NULL(D_RO(
buckets)->bucket[i]))
292 for (var = D_RO(
buckets)->bucket[i]; !TOID_IS_NULL(var);
293 var = D_RO(var)->next) {
294 ret = cb(D_RO(var)->key, D_RO(var)->value, arg);
319 fprintf(out,
"a: %u b: %u p: %" PRIu64
"\n", D_RO(hashmap)->hash_fun_a,
320 D_RO(hashmap)->hash_fun_b, D_RO(hashmap)->hash_fun_p);
321 fprintf(out,
"count: %" PRIu64
", buckets: %zu\n",
324 for (
size_t i = 0; i < D_RO(
buckets)->nbuckets; ++i) {
325 if (TOID_IS_NULL(D_RO(
buckets)->bucket[i]))
329 fprintf(out,
"%zu: ", i);
330 for (var = D_RO(
buckets)->bucket[i]; !TOID_IS_NULL(var);
331 var = D_RO(var)->next) {
332 fprintf(out,
"%" PRIu64
" ", D_RO(var)->key);
335 fprintf(out,
"(%d)\n", num);
356 for (var = D_RO(
buckets)->bucket[h];
358 var = D_RO(var)->next)
359 if (D_RO(var)->key == key)
360 return D_RO(var)->value;
384 for (var = D_RO(
buckets)->bucket[h];
386 var = D_RO(var)->next)
387 if (D_RO(var)->key == key)
403 return D_RO(hashmap)->count;
417 srand(D_RO(hashmap)->seed);
439 printf(
"map address %p\n", (*map).oid.off);
446 printf(
"hm create errno = %d\n", errno);
465 return TOID_IS_NULL(hashmap) || !TOID_VALID(hashmap);