ck_hs: Add ck_hs_gc, mechanism for tombstone clean-up.

This is treated as an explicit garbage collection step
which will block writers.
ck_pring
Samy Al Bahra 11 years ago
parent 5d4f9ae23d
commit f7eff4d61b

@ -124,6 +124,7 @@ bool ck_hs_fas(ck_hs_t *, unsigned long, const void *, void **);
void *ck_hs_remove(ck_hs_t *, unsigned long, const void *); void *ck_hs_remove(ck_hs_t *, unsigned long, const void *);
bool ck_hs_grow(ck_hs_t *, unsigned long); bool ck_hs_grow(ck_hs_t *, unsigned long);
bool ck_hs_rebuild(ck_hs_t *); bool ck_hs_rebuild(ck_hs_t *);
bool ck_hs_gc(ck_hs_t *);
unsigned long ck_hs_count(ck_hs_t *); unsigned long ck_hs_count(ck_hs_t *);
bool ck_hs_reset(ck_hs_t *); bool ck_hs_reset(ck_hs_t *);
bool ck_hs_reset_size(ck_hs_t *, unsigned long); bool ck_hs_reset_size(ck_hs_t *, unsigned long);

@ -492,6 +492,48 @@ ck_hs_marshal(unsigned int mode, const void *key, unsigned long h)
return insert; return insert;
} }
bool
ck_hs_gc(struct ck_hs *hs)
{
unsigned long i;
struct ck_hs_map *map = hs->map;
unsigned long size = sizeof(CK_HS_WORD) * map->capacity;
CK_HS_WORD *bounds;
if (map->probe_bound == NULL)
return true;
bounds = hs->m->malloc(size);
if (bounds == NULL)
return false;
memset(bounds, 0, size);
for (i = 0; i < map->capacity; i++) {
void **first, *object, *entry;
unsigned long n_probes, offset, h;
entry = map->entries[i & map->mask];
if (entry == CK_HS_EMPTY || entry == CK_HS_TOMBSTONE)
continue;
h = hs->hf(entry, hs->seed);
offset = h & map->mask;
ck_hs_map_probe(hs, map, &n_probes, &first, h, entry, &object, map->probe_maximum, CK_HS_PROBE);
if (n_probes > CK_HS_WORD_MAX)
n_probes = CK_HS_WORD_MAX;
if (n_probes > bounds[offset])
bounds[offset] = n_probes;
}
for (i = 0; i < map->capacity; i++)
CK_HS_STORE(&map->probe_bound[i], bounds[i]);
hs->m->free(bounds, size, false);
return true;
}
bool bool
ck_hs_fas(struct ck_hs *hs, ck_hs_fas(struct ck_hs *hs,
unsigned long h, unsigned long h,

Loading…
Cancel
Save