ck_ht: Fix bug in ck_ht_gc and backport garbage collector improvements from ck_hs.

ck_pring
Samy Al Bahra 11 years ago
parent 4e4c24ba63
commit 822b842d1e

@ -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;
}

Loading…
Cancel
Save