Browse Source

Rename uthash_memcmp to HASH_KEYCMP, step 2.

Well, this certainly fell by the wayside! Back in December 2018
(two years ago), I did the first part (introducing `HASH_KEYCMP`),
cut release version 2.1.0, and said we should immediately fix up
the tests and then let it bake for "a few months" before removing
all support for `alt_memcmp`. It turns out that I forgot to do
any of that. So now I've fixed up the tests, just in time to
cut release version 2.2.0.

Then we can let version 2.2.0 bake for "a few months" (read: maybe
a couple of years :)) before finally removing `alt_memcmp`.

test96.c now demonstrates the intended usage of HASH_FUNCTION
and HASH_KEYCMP as a matching pair. (This is similar to the
pair of template parameters `Hasher, KeyEqual` taken by C++'s
`unordered_set`; the difference is that we take `KeyNotEqual`,
so that you can pass in a strcmp-like trivalued comparator --
but you don't have to, and test96.c regression-tests
that passing in a plain old not-equal function works fine.

Fixes #157.
Arthur O'Dwyer 4 years ago
parent
commit
6b4768b966
8 changed files with 114 additions and 24 deletions
  1. 1 1
      src/uthash.h
  2. 1 1
      tests/Makefile
  3. 3 2
      tests/README
  4. 7 6
      tests/test6.c
  5. 10 10
      tests/test88.ans
  6. 4 4
      tests/test88.c
  7. 40 0
      tests/test96.ans
  8. 48 0
      tests/test96.c

+ 1 - 1
src/uthash.h

@@ -764,7 +764,7 @@ do {
   }                                                                              \
   while ((out) != NULL) {                                                        \
     if ((out)->hh.hashv == (hashval) && (out)->hh.keylen == (keylen_in)) {       \
-      if (HASH_KEYCMP((out)->hh.key, keyptr, keylen_in) == 0) {              \
+      if (HASH_KEYCMP((out)->hh.key, keyptr, keylen_in) == 0) {                  \
         break;                                                                   \
       }                                                                          \
     }                                                                            \

+ 1 - 1
tests/Makefile

@@ -12,7 +12,7 @@ PROGS = test1 test2 test3 test4 test5 test6 test7 test8 test9   \
         test66 test67 test68 test69 test70 test71 test72 test73 \
         test74 test75 test76 test77 test78 test79 test80 test81 \
         test82 test83 test84 test85 test86 test87 test88 test89 \
-        test90 test91 test92 test93 test94 test95
+        test90 test91 test92 test93 test94 test95 test96
 CFLAGS += -I$(HASHDIR)
 #CFLAGS += -DHASH_BLOOM=16
 #CFLAGS += -O2

+ 3 - 2
tests/README

@@ -7,7 +7,7 @@ test2:  make 10-item hash, lookup items with even keys, print
 test3:  make 10-item hash, delete items with even keys, print others
 test4:  10 structs have dual hash handles, separate keys
 test5:  10 structs have dual hash handles, lookup evens by alt key
-test6:  test alt malloc macros (and alt memcmp macro)
+test6:  test alt malloc macros (and alt key-comparison macro)
 test7:  test alt malloc macros with 1000 structs so bucket expansion occurs
 test8:  test num_items counter in UT_hash_handle
 test9:  test "find" after bucket expansion
@@ -89,7 +89,7 @@ test84: test HASH_REPLACE_STR with char* key
 test85: test HASH_OVERHEAD on null and non null hash
 test86: test *_APPEND_ELEM / *_PREPEND_ELEM (Thilo Schulz)
 test87: test HASH_ADD_INORDER() macro (Thilo Schulz)
-test88: test alt memcmp and strlen macros
+test88: test alt key-comparison and strlen macros
 test89: test code from the tinydtls project
 test90: regression-test HASH_ADD_KEYPTR_INORDER (IronBug)
 test91: test LL_INSERT_INORDER etc.
@@ -97,6 +97,7 @@ test92: HASH_NONFATAL_OOM
 test93: alt_fatal
 test94: utlist with fields named other than 'next' and 'prev'
 test95: utstack
+test96: HASH_FUNCTION + HASH_KEYCMP
 
 Other Make targets
 ================================================================================

+ 7 - 6
tests/test6.c

@@ -7,15 +7,16 @@
 /* Set up macros for alternative malloc/free functions  */
 #undef uthash_malloc
 #undef uthash_free
-#undef uthash_memcmp
 #undef uthash_strlen
 #undef uthash_bzero
 #define uthash_malloc(sz) alt_malloc(sz)
 #define uthash_free(ptr,sz) alt_free(ptr,sz)
-#define uthash_memcmp(a,b,n) alt_memcmp(a,b,n)
 #define uthash_strlen(s) ..fail_to_compile..
 #define uthash_bzero(a,n) alt_bzero(a,n)
 
+#undef HASH_KEYCMP
+#define HASH_KEYCMP(a,b,n) alt_keycmp(a,b,n)
+
 typedef struct example_user_t {
     int id;
     int cookie;
@@ -41,10 +42,10 @@ static void alt_free(void *ptr, size_t sz)
     free(ptr);
 }
 
-static int alt_memcmp_count = 0;
-static int alt_memcmp(const void *a, const void *b, size_t n)
+static int alt_keycmp_count = 0;
+static int alt_keycmp(const void *a, const void *b, size_t n)
 {
-    ++alt_memcmp_count;
+    ++alt_keycmp_count;
     return memcmp(a,b,n);
 }
 
@@ -115,7 +116,7 @@ int main()
 #else
     assert(alt_bzero_count == 2);
 #endif
-    assert(alt_memcmp_count == 10);
+    assert(alt_keycmp_count == 10);
     assert(alt_malloc_balance == 0);
     return 0;
 }

+ 10 - 10
tests/test88.ans

@@ -9,22 +9,22 @@ alt_strlen
 alt_strlen
 alt_strlen
 alt_strlen
-alt_memcmp
+alt_keycmp
 alt_strlen
-alt_memcmp
+alt_keycmp
 alt_strlen
-alt_memcmp
+alt_keycmp
 alt_strlen
-alt_memcmp
+alt_keycmp
 alt_strlen
-alt_memcmp
+alt_keycmp
 alt_strlen
-alt_memcmp
+alt_keycmp
 alt_strlen
-alt_memcmp
+alt_keycmp
 alt_strlen
-alt_memcmp
+alt_keycmp
 alt_strlen
-alt_memcmp
+alt_keycmp
 alt_strlen
-alt_memcmp
+alt_keycmp

+ 4 - 4
tests/test88.c

@@ -8,9 +8,9 @@
 
 /* This is mostly a copy of test6.c. */
 
-#undef uthash_memcmp
+#undef HASH_KEYCMP
 #undef uthash_strlen
-#define uthash_memcmp(a,b,n) alt_memcmp(a,b,n)
+#define HASH_KEYCMP(a,b,n) alt_keycmp(a,b,n)
 #define uthash_strlen(s) alt_strlen(s)
 
 typedef struct example_user_t {
@@ -19,9 +19,9 @@ typedef struct example_user_t {
     UT_hash_handle hh;
 } example_user_t;
 
-static int alt_memcmp(const void *a, const void *b, size_t n)
+static int alt_keycmp(const void *a, const void *b, size_t n)
 {
-    puts("alt_memcmp");
+    puts("alt_keycmp");
     return memcmp(a,b,n);
 }
 

+ 40 - 0
tests/test96.ans

@@ -0,0 +1,40 @@
+time 56 not found, inserting it
+time 7 not found, inserting it
+time 10 not found, inserting it
+time 39 not found, inserting it
+time 82 found with value 10
+time 15 found with value 39
+time 31 found with value 7
+time 26 not found, inserting it
+time 51 found with value 39
+time 83 not found, inserting it
+time 46 found with value 10
+time 92 found with value 56
+time 49 not found, inserting it
+time 25 found with value 49
+time 80 found with value 56
+time 54 not found, inserting it
+time 97 found with value 49
+time 9 not found, inserting it
+time 34 found with value 10
+time 86 found with value 26
+time 87 found with value 39
+time 28 not found, inserting it
+time 13 found with value 49
+time 91 found with value 7
+time 95 found with value 83
+time 63 found with value 39
+time 71 found with value 83
+time 100 found with value 28
+time 44 found with value 56
+time 42 found with value 54
+time 16 found with value 28
+time 32 found with value 56
+time 6 found with value 54
+time 85 found with value 49
+time 40 found with value 28
+time 20 found with value 56
+time 18 found with value 54
+time 99 found with value 39
+time 22 found with value 10
+time 1 found with value 49

+ 48 - 0
tests/test96.c

@@ -0,0 +1,48 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define HASH_FUNCTION(a,n,hv) (hv = clockface_hash(*(const int*)(a)))
+#define HASH_KEYCMP(a,b,n) clockface_neq(*(const int*)(a), *(const int*)(b))
+
+#include "uthash.h"
+
+struct clockface {
+    int time;
+    UT_hash_handle hh;
+};
+
+int clockface_hash(int time)
+{
+    return (time % 4);
+}
+
+int clockface_neq(int t1, int t2)
+{
+    return ((t1 % 12) != (t2 % 12));
+}
+
+int main()
+{
+    int random_data[] = {
+        56, 7, 10, 39, 82, 15, 31, 26, 51, 83,
+        46, 92, 49, 25, 80, 54, 97, 9, 34, 86,
+        87, 28, 13, 91, 95, 63, 71, 100, 44, 42,
+        16, 32, 6, 85, 40, 20, 18, 99, 22, 1
+    };
+
+    struct clockface *times = NULL;
+    for (int i=0; i < 40; ++i) {
+        struct clockface *elt = (struct clockface *)malloc(sizeof(*elt));
+        struct clockface *found = NULL;
+        elt->time = random_data[i];
+        HASH_FIND_INT(times, &elt->time, found);
+        if (found) {
+            printf("time %d found with value %d\n", elt->time, found->time);
+        } else {
+            printf("time %d not found, inserting it\n", elt->time);
+            HASH_ADD_INT(times, time, elt);
+        }
+    }
+
+    return 0;
+}