From 822b842d1ed88cc82257b3f6a9e9010f8888dbc9 Mon Sep 17 00:00:00 2001 From: Samy Al Bahra Date: Tue, 17 Dec 2013 18:01:39 -0500 Subject: [PATCH] ck_ht: Fix bug in ck_ht_gc and backport garbage collector improvements from ck_hs. --- src/ck_ht.c | 68 ++++++++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/src/ck_ht.c b/src/ck_ht.c index 4f201e6..834cb9a 100644 --- a/src/ck_ht.c +++ b/src/ck_ht.c @@ -385,26 +385,31 @@ ck_ht_gc(struct ck_ht *ht, unsigned long cycles, unsigned long seed) { CK_HT_WORD *bounds = NULL; struct ck_ht_map *map = ht->map; - uint64_t maximum = map->probe_maximum; - uint64_t i; + uint64_t maximum, i; uint64_t size = 0; - if (cycles == 0 && map->probe_bound != NULL) { - size = sizeof(CK_HT_WORD) * map->capacity; - bounds = ht->m->malloc(size); - if (bounds == NULL) - return false; + if (cycles == 0) { + maximum = 0; + + if (map->probe_bound != NULL) { + size = sizeof(CK_HT_WORD) * map->capacity; + bounds = ht->m->malloc(size); + if (bounds == NULL) + return false; - memset(bounds, 0, size); + memset(bounds, 0, size); + } + } else { + maximum = map->probe_maximum; } for (i = 0; i < map->capacity; i++) { struct ck_ht_entry *entry, *priority, snapshot; struct ck_ht_hash h; uint64_t probes_wr; - uint64_t offset = (i + seed) & map->mask; + uint64_t offset; - entry = &map->entries[offset]; + entry = &map->entries[(i + seed) & map->mask]; if (entry->key == CK_HT_KEY_EMPTY || entry->key == CK_HT_KEY_TOMBSTONE) { continue; @@ -417,7 +422,7 @@ ck_ht_gc(struct ck_ht *ht, unsigned long cycles, unsigned long seed) ht->h(&h, ck_ht_entry_key(entry), ck_ht_entry_key_length(entry), ht->seed); #endif - ck_ht_map_probe_wr(map, h, &snapshot, &priority, + entry = ck_ht_map_probe_wr(map, h, &snapshot, &priority, ck_ht_entry_key(entry), ck_ht_entry_key_length(entry), NULL, &probes_wr); @@ -427,52 +432,51 @@ ck_ht_gc(struct ck_ht *ht, unsigned long cycles, unsigned long seed) #else ht->h(&h, &entry->key, sizeof(entry->key), ht->seed); #endif - ck_ht_map_probe_wr(map, h, &snapshot, &priority, + entry = ck_ht_map_probe_wr(map, h, &snapshot, &priority, &entry->key, sizeof(entry->key), NULL, &probes_wr); } - if (priority == NULL) - continue; + offset = h.value & map->mask; + if (priority != NULL) { #ifndef CK_HT_PP - ck_pr_store_64(&priority->key_length, entry->key_length); - ck_pr_store_64(&priority->hash, entry->hash); + ck_pr_store_64(&priority->key_length, entry->key_length); + ck_pr_store_64(&priority->hash, entry->hash); #endif - ck_pr_store_ptr(&priority->value, (void *)entry->value); - ck_pr_fence_store(); - ck_pr_store_ptr(&priority->key, (void *)entry->key); - ck_pr_fence_store(); - ck_pr_store_64(&map->deletions, map->deletions + 1); - ck_pr_fence_store(); - ck_pr_store_ptr(&entry->key, (void *)CK_HT_KEY_TOMBSTONE); + ck_pr_store_ptr(&priority->value, (void *)entry->value); + ck_pr_fence_store(); + ck_pr_store_ptr(&priority->key, (void *)entry->key); + ck_pr_fence_store(); + ck_pr_store_64(&map->deletions, map->deletions + 1); + ck_pr_fence_store(); + ck_pr_store_ptr(&entry->key, (void *)CK_HT_KEY_TOMBSTONE); + } if (cycles == 0) { + if (probes_wr > maximum) + maximum = probes_wr; + if (probes_wr >= CK_HT_WORD_MAX) probes_wr = CK_HT_WORD_MAX; if (bounds != NULL && probes_wr > bounds[offset]) bounds[offset] = probes_wr; - - if (probes_wr > maximum) - maximum = probes_wr; } else if (--cycles == 0) break; } - if (bounds != NULL) { - for (i = 0; i < map->capacity; i++) { - if (bounds[i] == 0 && map->probe_bound[i] != 0) - continue; + if (maximum != map->probe_maximum) + ck_pr_store_64(&map->probe_maximum, maximum); + if (bounds != NULL) { + for (i = 0; i < map->capacity; i++) CK_HT_STORE(&map->probe_bound[i], bounds[i]); - } ht->m->free(bounds, size, false); } - ck_pr_store_64(&map->probe_maximum, maximum); return true; }