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; CK_HT_WORD *bounds = NULL;
struct ck_ht_map *map = ht->map; struct ck_ht_map *map = ht->map;
uint64_t maximum = map->probe_maximum; uint64_t maximum, i;
uint64_t i;
uint64_t size = 0; uint64_t size = 0;
if (cycles == 0 && map->probe_bound != NULL) { if (cycles == 0) {
size = sizeof(CK_HT_WORD) * map->capacity; maximum = 0;
bounds = ht->m->malloc(size);
if (bounds == NULL) if (map->probe_bound != NULL) {
return false; 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++) { for (i = 0; i < map->capacity; i++) {
struct ck_ht_entry *entry, *priority, snapshot; struct ck_ht_entry *entry, *priority, snapshot;
struct ck_ht_hash h; struct ck_ht_hash h;
uint64_t probes_wr; 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 || if (entry->key == CK_HT_KEY_EMPTY ||
entry->key == CK_HT_KEY_TOMBSTONE) { entry->key == CK_HT_KEY_TOMBSTONE) {
continue; 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->h(&h, ck_ht_entry_key(entry), ck_ht_entry_key_length(entry),
ht->seed); ht->seed);
#endif #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(entry),
ck_ht_entry_key_length(entry), ck_ht_entry_key_length(entry),
NULL, &probes_wr); NULL, &probes_wr);
@ -427,52 +432,51 @@ ck_ht_gc(struct ck_ht *ht, unsigned long cycles, unsigned long seed)
#else #else
ht->h(&h, &entry->key, sizeof(entry->key), ht->seed); ht->h(&h, &entry->key, sizeof(entry->key), ht->seed);
#endif #endif
ck_ht_map_probe_wr(map, h, &snapshot, &priority, entry = ck_ht_map_probe_wr(map, h, &snapshot, &priority,
&entry->key, &entry->key,
sizeof(entry->key), sizeof(entry->key),
NULL, &probes_wr); NULL, &probes_wr);
} }
if (priority == NULL) offset = h.value & map->mask;
continue;
if (priority != NULL) {
#ifndef CK_HT_PP #ifndef CK_HT_PP
ck_pr_store_64(&priority->key_length, entry->key_length); ck_pr_store_64(&priority->key_length, entry->key_length);
ck_pr_store_64(&priority->hash, entry->hash); ck_pr_store_64(&priority->hash, entry->hash);
#endif #endif
ck_pr_store_ptr(&priority->value, (void *)entry->value); ck_pr_store_ptr(&priority->value, (void *)entry->value);
ck_pr_fence_store(); ck_pr_fence_store();
ck_pr_store_ptr(&priority->key, (void *)entry->key); ck_pr_store_ptr(&priority->key, (void *)entry->key);
ck_pr_fence_store(); ck_pr_fence_store();
ck_pr_store_64(&map->deletions, map->deletions + 1); ck_pr_store_64(&map->deletions, map->deletions + 1);
ck_pr_fence_store(); ck_pr_fence_store();
ck_pr_store_ptr(&entry->key, (void *)CK_HT_KEY_TOMBSTONE); ck_pr_store_ptr(&entry->key, (void *)CK_HT_KEY_TOMBSTONE);
}
if (cycles == 0) { if (cycles == 0) {
if (probes_wr > maximum)
maximum = probes_wr;
if (probes_wr >= CK_HT_WORD_MAX) if (probes_wr >= CK_HT_WORD_MAX)
probes_wr = CK_HT_WORD_MAX; probes_wr = CK_HT_WORD_MAX;
if (bounds != NULL && probes_wr > bounds[offset]) if (bounds != NULL && probes_wr > bounds[offset])
bounds[offset] = probes_wr; bounds[offset] = probes_wr;
if (probes_wr > maximum)
maximum = probes_wr;
} else if (--cycles == 0) } else if (--cycles == 0)
break; break;
} }
if (bounds != NULL) { if (maximum != map->probe_maximum)
for (i = 0; i < map->capacity; i++) { ck_pr_store_64(&map->probe_maximum, maximum);
if (bounds[i] == 0 && map->probe_bound[i] != 0)
continue;
if (bounds != NULL) {
for (i = 0; i < map->capacity; i++)
CK_HT_STORE(&map->probe_bound[i], bounds[i]); CK_HT_STORE(&map->probe_bound[i], bounds[i]);
}
ht->m->free(bounds, size, false); ht->m->free(bounds, size, false);
} }
ck_pr_store_64(&map->probe_maximum, maximum);
return true; return true;
} }

Loading…
Cancel
Save