# HG changeset patch # User Mike Becker # Date 1529589637 -7200 # Node ID fbc33813265b21856464351f79969a23cbfba26b # Parent 3dd7d21fb76bf544dfcfc22e7432d70764f220b9 UcxMap now separates internal non-const keys from public const keys This simplifies function calls with constant keys like scstr_t or const char*. diff -r 3dd7d21fb76b -r fbc33813265b src/map.c --- a/src/map.c Wed May 30 11:13:52 2018 +0200 +++ b/src/map.c Thu Jun 21 16:00:37 2018 +0200 @@ -154,19 +154,22 @@ UcxAllocator *allocator = map->allocator; if (key.hash == 0) { - key.hash = ucx_hash((char*)key.data, key.len); + key.hash = ucx_hash(key.data, key.len); } + + struct UcxMapKey mapkey; + mapkey.hash = key.hash; - size_t slot = key.hash%map->size; + size_t slot = mapkey.hash%map->size; UcxMapElement *elm = map->map[slot]; UcxMapElement *prev = NULL; - while (elm && elm->key.hash < key.hash) { + while (elm && elm->key.hash < mapkey.hash) { prev = elm; elm = elm->next; } - if (!elm || elm->key.hash != key.hash) { + if (!elm || elm->key.hash != mapkey.hash) { UcxMapElement *e = (UcxMapElement*)almalloc( allocator, sizeof(UcxMapElement)); if (!e) { @@ -188,8 +191,9 @@ return -1; } memcpy(kd, key.data, key.len); - key.data = kd; - elm->key = key; + mapkey.data = kd; + mapkey.len = key.len; + elm->key = mapkey; map->count++; } elm->data = data; @@ -239,11 +243,11 @@ return ucx_map_get_and_remove(map, key, 1); } -UcxKey ucx_key(void *data, size_t len) { +UcxKey ucx_key(const void *data, size_t len) { UcxKey key; key.data = data; key.len = len; - key.hash = ucx_hash((const char*) data, len); + key.hash = ucx_hash(data, len); return key; } @@ -312,7 +316,9 @@ if (e->data) { i->cur = e; *elm = e->data; - *key = e->key; + key->data = e->key.data; + key->hash = e->key.hash; + key->len = e->key.len; return 1; } diff -r 3dd7d21fb76b -r fbc33813265b src/ucx/map.h --- a/src/ucx/map.h Wed May 30 11:13:52 2018 +0200 +++ b/src/ucx/map.h Thu Jun 21 16:00:37 2018 +0200 @@ -89,26 +89,36 @@ size_t count; }; -/** Structure for a key of a UcxMap. */ +/** Structure to publicly denote a key of a UcxMap. */ struct UcxKey { /** The key data. */ - void *data; + const void *data; /** The length of the key data. */ - size_t len; + size_t len; + /** A cache for the hash value of the key data. */ + int hash; +}; + +/** Internal structure for a key of a UcxMap. */ +struct UcxMapKey { + /** The key data. */ + void *data; + /** The length of the key data. */ + size_t len; /** The hash value of the key data. */ - int hash; + int hash; }; /** Structure for an element of a UcxMap. */ struct UcxMapElement { /** The value data. */ - void *data; + void *data; /** A pointer to the next element in the current list. */ - UcxMapElement *next; + UcxMapElement *next; /** The corresponding key. */ - UcxKey key; + struct UcxMapKey key; }; /** Structure for an iterator over a UcxMap. */ @@ -285,7 +295,7 @@ * @see ucx_map_put() */ #define ucx_map_cstr_put(map, key, value) \ - ucx_map_put(map, ucx_key((void*)key, strlen(key)), (void*)value) + ucx_map_put(map, ucx_key(key, strlen(key)), (void*)value) /** * Shorthand for putting data with an integer key into the map. @@ -296,7 +306,7 @@ * @see ucx_map_put() */ #define ucx_map_int_put(map, key, value) \ - ucx_map_put(map, ucx_key((void*)&key, sizeof(key)), (void*)value) + ucx_map_put(map, ucx_key(&key, sizeof(key)), (void*)value) /** * Shorthand for getting data from the map with a sstr_t key. @@ -316,7 +326,7 @@ * @see ucx_map_get() */ #define ucx_map_cstr_get(map, key) \ - ucx_map_get(map, ucx_key((void*)key, strlen(key))) + ucx_map_get(map, ucx_key(key, strlen(key))) /** * Shorthand for getting data from the map with an integer key. @@ -326,7 +336,7 @@ * @see ucx_map_get() */ #define ucx_map_int_get(map, key) \ - ucx_map_get(map, ucx_key((void*)&key, sizeof(int))) + ucx_map_get(map, ucx_key(&key, sizeof(int))) /** * Shorthand for removing data from the map with a sstr_t key. @@ -346,7 +356,7 @@ * @see ucx_map_remove() */ #define ucx_map_cstr_remove(map, key) \ - ucx_map_remove(map, ucx_key((void*)key, strlen(key))) + ucx_map_remove(map, ucx_key(key, strlen(key))) /** * Shorthand for removing data from the map with an integer key. @@ -356,7 +366,7 @@ * @see ucx_map_remove() */ #define ucx_map_int_remove(map, key) \ - ucx_map_remove(map, ucx_key((void*)&key, sizeof(key))) + ucx_map_remove(map, ucx_key(&key, sizeof(key))) /** * Creates a UcxKey based on the given data. @@ -368,7 +378,7 @@ * @return a UcxKey with implicitly computed hash * @see ucx_hash() */ -UcxKey ucx_key(void *data, size_t len); +UcxKey ucx_key(const void *data, size_t len); /** * Computes a murmur hash-2. diff -r 3dd7d21fb76b -r fbc33813265b test/map_tests.c --- a/test/map_tests.c Wed May 30 11:13:52 2018 +0200 +++ b/test/map_tests.c Thu Jun 21 16:00:37 2018 +0200 @@ -39,7 +39,7 @@ } UCX_TEST(test_ucx_key) { - UcxKey key = ucx_key((void*)"This is a text.", 15); + UcxKey key = ucx_key("This is a text.", 15); UCX_TEST_BEGIN UCX_TEST_ASSERT(strncmp((const char*)key.data, "This is a text.", 15) == 0, "failed");