ck_hs: Drop ck_hs_hash_t abstraction.

No need for opaque type anymore.
ck_pring
Samy Al Bahra 13 years ago
parent b4ab193944
commit ece2895e9e

@ -36,11 +36,6 @@
#include <stdbool.h>
#include <stddef.h>
struct ck_hs_hash {
unsigned long value;
};
typedef struct ck_hs_hash ck_hs_hash_t;
#define CK_HS_MODE_SPMC 1
#define CK_HS_MODE_DIRECT 2
#define CK_HS_MODE_OBJECT 8
@ -51,7 +46,7 @@ typedef struct ck_hs_hash ck_hs_hash_t;
/*
* Hash callback function.
*/
typedef ck_hs_hash_t ck_hs_hash_cb_t(const void *, unsigned long);
typedef unsigned long ck_hs_hash_cb_t(const void *, unsigned long);
/*
* Returns pointer to object if objects are equivalent.
@ -92,10 +87,10 @@ void ck_hs_iterator_init(ck_hs_iterator_t *);
bool ck_hs_next(ck_hs_t *, ck_hs_iterator_t *, void **);
bool ck_hs_init(ck_hs_t *, unsigned int, ck_hs_hash_cb_t *, ck_hs_compare_cb_t *, struct ck_malloc *, unsigned long, unsigned long);
void ck_hs_destroy(ck_hs_t *);
void *ck_hs_get(ck_hs_t *, ck_hs_hash_t, const void *);
bool ck_hs_put(ck_hs_t *, ck_hs_hash_t, const void *);
bool ck_hs_set(ck_hs_t *, ck_hs_hash_t, const void *, void **);
void *ck_hs_remove(ck_hs_t *, ck_hs_hash_t, const void *);
void *ck_hs_get(ck_hs_t *, unsigned long, const void *);
bool ck_hs_put(ck_hs_t *, unsigned long, const void *);
bool ck_hs_set(ck_hs_t *, unsigned long, const void *, void **);
void *ck_hs_remove(ck_hs_t *, unsigned long, const void *);
bool ck_hs_grow(ck_hs_t *, unsigned long);
unsigned long ck_hs_count(ck_hs_t *);
bool ck_hs_reset(ck_hs_t *);

@ -78,13 +78,13 @@ alarm_handler(int s)
return;
}
static ck_hs_hash_t
static unsigned long
hs_hash(const void *object, unsigned long seed)
{
const char *c = object;
ck_hs_hash_t h;
unsigned long h;
h.value = (unsigned long)MurmurHash64A(c, strlen(c), seed);
h = (unsigned long)MurmurHash64A(c, strlen(c), seed);
return h;
}
@ -152,29 +152,29 @@ set_init(void)
static bool
set_remove(const char *value)
{
ck_hs_hash_t h;
unsigned long h;
h.value = (unsigned long)MurmurHash64A(value, strlen(value), hs.seed);
h = (unsigned long)MurmurHash64A(value, strlen(value), hs.seed);
return (bool)ck_hs_remove(&hs, h, value);
}
static bool
set_replace(const char *value)
{
ck_hs_hash_t h;
unsigned long h;
void *previous;
h.value = (unsigned long)MurmurHash64A(value, strlen(value), hs.seed);
h = (unsigned long)MurmurHash64A(value, strlen(value), hs.seed);
return ck_hs_set(&hs, h, value, &previous);
}
static void *
set_get(const char *value)
{
ck_hs_hash_t h;
unsigned long h;
void *v;
h.value = (unsigned long)MurmurHash64A(value, strlen(value), hs.seed);
h = (unsigned long)MurmurHash64A(value, strlen(value), hs.seed);
v = ck_hs_get(&hs, h, value);
return v;
}
@ -182,9 +182,9 @@ set_get(const char *value)
static bool
set_insert(const char *value)
{
ck_hs_hash_t h;
unsigned long h;
h.value = (unsigned long)MurmurHash64A(value, strlen(value), hs.seed);
h = (unsigned long)MurmurHash64A(value, strlen(value), hs.seed);
return ck_hs_put(&hs, h, value);
}

@ -67,13 +67,13 @@ static struct ck_malloc my_allocator = {
.free = hs_free
};
static ck_hs_hash_t
static unsigned long
hs_hash(const void *object, unsigned long seed)
{
const char *c = object;
ck_hs_hash_t h;
unsigned long h;
h.value = (unsigned long)MurmurHash64A(c, strlen(c), seed);
h = (unsigned long)MurmurHash64A(c, strlen(c), seed);
return h;
}
@ -100,9 +100,9 @@ set_init(void)
static bool
set_remove(const char *value)
{
ck_hs_hash_t h;
unsigned long h;
h.value = (unsigned long)MurmurHash64A(value, strlen(value), hs.seed);
h = hs_hash(value, hs.seed);
ck_hs_remove(&hs, h, value);
return true;
}
@ -110,20 +110,21 @@ set_remove(const char *value)
static bool
set_replace(const char *value)
{
ck_hs_hash_t h;
unsigned long h;
void *previous;
h.value = (unsigned long)MurmurHash64A(value, strlen(value), hs.seed);
return ck_hs_set(&hs, h, value, &previous);
h = hs_hash(value, hs.seed);
ck_hs_set(&hs, h, value, &previous);
return previous != NULL;
}
static void *
set_get(const char *value)
{
ck_hs_hash_t h;
unsigned long h;
void *v;
h.value = (unsigned long)MurmurHash64A(value, strlen(value), hs.seed);
h = hs_hash(value, hs.seed);
v = ck_hs_get(&hs, h, value);
return v;
}
@ -131,9 +132,9 @@ set_get(const char *value)
static bool
set_insert(const char *value)
{
ck_hs_hash_t h;
unsigned long h;
h.value = (unsigned long)MurmurHash64A(value, strlen(value), hs.seed);
h = hs_hash(value, hs.seed);
return ck_hs_put(&hs, h, value);
}
@ -219,7 +220,6 @@ main(int argc, char *argv[])
keys = t;
set_init();
for (i = 0; i < keys_length; i++)
d += set_insert(keys[i]) == false;
ck_hs_stat(&hs, &st);

@ -64,14 +64,14 @@ const char *test[] = {"Samy", "Al", "Bahra", "dances", "in", "the", "wind.", "On
const char *negative = "negative";
static ck_hs_hash_t
static unsigned long
hs_hash(const void *object, unsigned long seed)
{
const char *c = object;
ck_hs_hash_t h;
unsigned long h;
(void)seed;
h.value = c[0];
h = c[0];
return h;
}
@ -85,8 +85,9 @@ hs_compare(const void *previous, const void *compare)
int
main(void)
{
const char *blob = "blobs";
unsigned long h;
ck_hs_t hs;
ck_hs_hash_t h;
size_t i;
if (ck_hs_init(&hs, CK_HS_MODE_SPMC | CK_HS_MODE_OBJECT, hs_hash, hs_compare, &my_allocator, 8, 6602834) == false) {
@ -96,7 +97,7 @@ main(void)
/* Test serial put semantics. */
for (i = 0; i < sizeof(test) / sizeof(*test); i++) {
h.value = test[i][0];
h = test[i][0];
ck_hs_put(&hs, h, test[i]);
if (ck_hs_put(&hs, h, test[i]) == true) {
fprintf(stderr, "ERROR [1]: put must fail on collision.\n");
@ -107,7 +108,7 @@ main(void)
/* Test grow semantics. */
ck_hs_grow(&hs, 32);
for (i = 0; i < sizeof(test) / sizeof(*test); i++) {
h.value = test[i][0];
h = test[i][0];
if (ck_hs_put(&hs, h, test[i]) == true) {
fprintf(stderr, "ERROR [2]: put must fail on collision.\n");
exit(EXIT_FAILURE);
@ -119,10 +120,21 @@ main(void)
}
}
h = ULONG_MAX;
if (ck_hs_put(&hs, h, blob) == false) {
fprintf(stderr, "ERROR: Duplicate put failed.\n");
exit(EXIT_FAILURE);
}
if (ck_hs_put(&hs, h, blob) == true) {
fprintf(stderr, "ERROR: Duplicate put succeeded.\n");
exit(EXIT_FAILURE);
}
/* Grow set and check get semantics. */
ck_hs_grow(&hs, 128);
for (i = 0; i < sizeof(test) / sizeof(*test); i++) {
h.value = test[i][0];
h = test[i][0];
if (ck_hs_get(&hs, h, test[i]) == NULL) {
fprintf(stderr, "ERROR: get must not fail\n");
exit(EXIT_FAILURE);
@ -133,7 +145,7 @@ main(void)
for (i = 0; i < sizeof(test) / sizeof(*test); i++) {
void *r;
h.value = test[i][0];
h = test[i][0];
if (ck_hs_get(&hs, h, test[i]) == NULL)
continue;
@ -153,7 +165,7 @@ main(void)
void *r;
bool d;
h.value = test[i][0];
h = test[i][0];
d = ck_hs_get(&hs, h, test[i]) != NULL;
if (ck_hs_set(&hs, h, test[i], &r) == false) {
fprintf(stderr, "ERROR: Failed to set\n");

@ -168,16 +168,16 @@ ck_hs_reset(struct ck_hs *hs)
}
static inline unsigned long
ck_hs_map_probe_next(struct ck_hs_map *map, unsigned long offset, ck_hs_hash_t h, unsigned long level, unsigned long probes)
ck_hs_map_probe_next(struct ck_hs_map *map, unsigned long offset, unsigned long h, unsigned long level, unsigned long probes)
{
ck_hs_hash_t r;
unsigned long r;
unsigned long stride;
(void)probes;
(void)level;
r.value = h.value >> map->step;
stride = (r.value & ~CK_HS_PROBE_L1_MASK) << 1 | (r.value & CK_HS_PROBE_L1_MASK);
r = h >> map->step;
stride = (r & ~CK_HS_PROBE_L1_MASK) << 1 | (r & CK_HS_PROBE_L1_MASK);
return (offset + (stride | CK_HS_PROBE_L1)) & map->mask;
}
@ -201,7 +201,7 @@ restart:
return false;
for (k = 0; k < map->capacity; k++) {
struct ck_hs_hash h;
unsigned long h;
previous = map->entries[k];
if (previous == CK_HS_EMPTY || previous == CK_HS_TOMBSTONE)
@ -213,7 +213,7 @@ restart:
#endif
h = hs->hf(previous, hs->seed);
offset = h.value & update->mask;
offset = h & update->mask;
probes = 0;
for (i = 0; i < update->probe_limit; i++) {
@ -224,7 +224,7 @@ restart:
probes++;
if (*cursor == CK_HS_EMPTY) {
*cursor = previous;
*cursor = map->entries[k];
update->n_entries++;
if (probes > update->probe_maximum)
@ -261,7 +261,7 @@ ck_hs_map_probe(struct ck_hs *hs,
struct ck_hs_map *map,
unsigned long *n_probes,
void ***priority,
ck_hs_hash_t h,
unsigned long h,
const void *key,
void **object,
unsigned long probe_limit)
@ -274,11 +274,11 @@ ck_hs_map_probe(struct ck_hs *hs,
#ifdef CK_HS_PP
/* If we are storing object pointers, then we may leverage pointer packing. */
struct ck_hs_hash hv;
unsigned long hv;
if (hs->mode & CK_HS_MODE_OBJECT) {
hv.value = (h.value >> 25) & CK_HS_KEY_MASK;
compare = (void *)((uintptr_t)key | (hv.value << CK_MD_VMA_BITS));
hv = (h >> 25) & CK_HS_KEY_MASK;
compare = (void *)((uintptr_t)key | (hv << CK_MD_VMA_BITS));
} else {
compare = key;
}
@ -286,7 +286,7 @@ ck_hs_map_probe(struct ck_hs *hs,
compare = key;
#endif
offset = h.value & map->mask;
offset = h & map->mask;
*object = NULL;
for (i = 0; i < probe_limit; i++) {
@ -310,7 +310,7 @@ ck_hs_map_probe(struct ck_hs *hs,
#ifdef CK_HS_PP
if (hs->mode & CK_HS_MODE_OBJECT) {
if (((uintptr_t)k >> CK_MD_VMA_BITS) != hv.value)
if (((uintptr_t)k >> CK_MD_VMA_BITS) != hv)
continue;
k = (void *)((uintptr_t)k & (((uintptr_t)1 << CK_MD_VMA_BITS) - 1));
@ -344,7 +344,7 @@ leave:
bool
ck_hs_set(struct ck_hs *hs,
struct ck_hs_hash h,
unsigned long h,
const void *key,
void **previous)
{
@ -366,7 +366,7 @@ restart:
#ifdef CK_HS_PP
if (hs->mode & CK_HS_MODE_OBJECT) {
insert = (void *)((uintptr_t)key | ((h.value >> 25) << CK_MD_VMA_BITS));
insert = (void *)((uintptr_t)key | ((h >> 25) << CK_MD_VMA_BITS));
} else {
insert = (void *)key;
}
@ -386,7 +386,7 @@ restart:
* is visible with respect to concurrent probe sequences.
*/
if (*slot != CK_HS_EMPTY) {
ck_pr_inc_uint(&map->generation[h.value & CK_HS_G_MASK]);
ck_pr_inc_uint(&map->generation[h & CK_HS_G_MASK]);
ck_pr_fence_store();
ck_pr_store_ptr(slot, CK_HS_TOMBSTONE);
}
@ -410,7 +410,7 @@ restart:
bool
ck_hs_put(struct ck_hs *hs,
struct ck_hs_hash h,
unsigned long h,
const void *key)
{
void **slot, **first, *object, *insert;
@ -433,7 +433,7 @@ restart:
#ifdef CK_HS_PP
if (hs->mode & CK_HS_MODE_OBJECT) {
insert = (void *)((uintptr_t)key | ((h.value >> 25) << CK_MD_VMA_BITS));
insert = (void *)((uintptr_t)key | ((h >> 25) << CK_MD_VMA_BITS));
} else {
insert = (void *)key;
}
@ -447,7 +447,7 @@ restart:
if (first != NULL) {
/* If an earlier bucket was found, then go ahead and replace it. */
ck_pr_store_ptr(first, insert);
ck_pr_inc_uint(&map->generation[h.value & CK_HS_G_MASK]);
ck_pr_inc_uint(&map->generation[h & CK_HS_G_MASK]);
/* Guarantee that new object is visible with respect to generation increment. */
ck_pr_fence_store();
@ -466,7 +466,7 @@ restart:
void *
ck_hs_get(struct ck_hs *hs,
struct ck_hs_hash h,
unsigned long h,
const void *key)
{
void **slot, **first, *object;
@ -477,7 +477,7 @@ ck_hs_get(struct ck_hs *hs,
do {
map = ck_pr_load_ptr(&hs->map);
generation = &map->generation[h.value & CK_HS_G_MASK];
generation = &map->generation[h & CK_HS_G_MASK];
g = ck_pr_load_uint(generation);
probe = ck_pr_load_uint(&map->probe_maximum);
ck_pr_fence_load();
@ -495,7 +495,7 @@ ck_hs_get(struct ck_hs *hs,
void *
ck_hs_remove(struct ck_hs *hs,
struct ck_hs_hash h,
unsigned long h,
const void *key)
{
void **slot, **first, *object;

Loading…
Cancel
Save