UcxMap now separates internal non-const keys from public const keys

Thu, 21 Jun 2018 16:00:37 +0200

author
Mike Becker <universe@uap-core.de>
date
Thu, 21 Jun 2018 16:00:37 +0200
changeset 327
fbc33813265b
parent 326
3dd7d21fb76b
child 328
2bf1da3c411e

UcxMap now separates internal non-const keys from public const keys

This simplifies function calls with constant keys like scstr_t or const char*.

src/map.c file | annotate | diff | comparison | revisions
src/ucx/map.h file | annotate | diff | comparison | revisions
test/map_tests.c file | annotate | diff | comparison | revisions
--- 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;
             }
 
--- 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.
--- 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");

mercurial