X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=lib%2Fhash-test.c;h=803a0302e7a98c4f373ee40328a781ef00c09bf8;hb=b4d79987a979bcbf749294c706fdc8c4ae8f9304;hp=ae1e6f8649c8f9c9b9211474e35f9b60e4f57bfd;hpb=2237687dce28209d9b1dd8ef23b9a915c80b390c;p=libucw.git diff --git a/lib/hash-test.c b/lib/hash-test.c index ae1e6f86..803a0302 100644 --- a/lib/hash-test.c +++ b/lib/hash-test.c @@ -1,85 +1,77 @@ /* Tests for hash table routines */ #include "lib/lib.h" +#include "lib/mempool.h" #include #include - -#if 0 +#include /* TEST 1: integers */ -struct node { +struct node1 { int key; int data; }; -#define HASH_NODE struct node -#define HASH_PREFIX(x) test_##x +#define HASH_NODE struct node1 +#define HASH_PREFIX(x) test1_##x #define HASH_KEY_ATOMIC key #define HASH_ATOMIC_TYPE int +#define HASH_ZERO_FILL #define HASH_GIVE_INIT_DATA -static inline void test_init_data(struct node *n) +static inline void test1_init_data(struct node1 *n) { n->data = n->key + 123; } #define HASH_WANT_FIND -//#define HASH_WANT_NEW #define HASH_WANT_LOOKUP -//#define HASH_WANT_DELETE #define HASH_WANT_REMOVE #include "lib/hashtable.h" -static void test(void) +static void test1(void) { int i; - test_init(); + test1_init(); for (i=0; i<1024; i++) { - struct node *n = test_lookup(i); + struct node1 *n = test1_lookup(i); ASSERT(n->data == i+123); } for (i=1; i<1024; i+=2) { -#if 0 - test_delete(i); -#else - struct node *n = test_lookup(i); - test_remove(n); -#endif + struct node1 *n = test1_lookup(i); + test1_remove(n); } for (i=0; i<1024; i++) { - struct node *n = test_find(i); + struct node1 *n = test1_find(i); if (!n != (i&1) || (n && n->data != i+123)) die("Inconsistency at i=%d", i); } i=0; - HASH_FOR_ALL(test, n) + HASH_FOR_ALL(test1, n) { - i += 1 + 0*n->key; - // printf("%d\n", n->key); + i += 1 + n->key; } HASH_END_FOR; - ASSERT(i == 512); - log(L_INFO, "OK"); + ASSERT(i == 262144); + puts("OK"); } -#elif 1 - /* TEST 2: external strings */ -struct node { +struct node2 { char *key; int data; }; -#define HASH_NODE struct node -#define HASH_PREFIX(x) test_##x +#define HASH_NODE struct node2 +#define HASH_PREFIX(x) test2_##x #define HASH_KEY_STRING key #define HASH_NOCASE #define HASH_AUTO_POOL 4096 @@ -89,91 +81,85 @@ struct node { #include "lib/hashtable.h" -static void test(void) +static void test2(void) { int i; - test_init(); + test2_init(); for (i=0; i<1024; i+=2) { char x[32]; sprintf(x, "abc%d", i); - test_new(xstrdup(x)); + test2_new(xstrdup(x)); } for (i=0; i<1024; i++) { char x[32]; - struct node *n; + struct node2 *n; sprintf(x, "ABC%d", i); - n = test_find(x); + n = test2_find(x); if (!n != (i&1)) die("Inconsistency at i=%d", i); } - log(L_INFO, "OK"); + puts("OK"); } -#elif 1 - /* TEST 3: internal strings + pools */ -#include "lib/mempool.h" - -static struct mempool *pool; +static struct mempool *pool3; -struct node { +struct node3 { int data; char key[1]; }; -#define HASH_NODE struct node -#define HASH_PREFIX(x) test_##x +#define HASH_NODE struct node3 +#define HASH_PREFIX(x) test3_##x #define HASH_KEY_ENDSTRING key #define HASH_WANT_FIND #define HASH_WANT_NEW -#define HASH_USE_POOL pool +#define HASH_USE_POOL pool3 #include "lib/hashtable.h" -static void test(void) +static void test3(void) { int i; - pool = mp_new(16384); - test_init(); + pool3 = mp_new(16384); + test3_init(); for (i=0; i<1048576; i+=2) { char x[32]; sprintf(x, "abc%d", i); - test_new(x); + test3_new(x); } for (i=0; i<1048576; i++) { char x[32]; - struct node *n; + struct node3 *n; sprintf(x, "abc%d", i); - n = test_find(x); + n = test3_find(x); if (!n != (i&1)) die("Inconsistency at i=%d", i); } - log(L_INFO, "OK"); + puts("OK"); } -#elif 1 - /* TEST 4: complex keys */ #include "lib/hashfunc.h" -struct node { +struct node4 { int port; int data; char host[1]; }; -#define HASH_NODE struct node -#define HASH_PREFIX(x) test_##x +#define HASH_NODE struct node4 +#define HASH_PREFIX(x) test4_##x #define HASH_KEY_COMPLEX(x) x host, x port #define HASH_KEY_DECL char *host, int port @@ -185,25 +171,25 @@ struct node { #define HASH_WANT_REMOVE #define HASH_GIVE_HASHFN -static uns test_hash(char *host, int port) +static uns test4_hash(char *host, int port) { - return hash_string_nocase(host) ^ hash_int(port); + return hash_string_nocase(host) ^ hash_u32(port); } #define HASH_GIVE_EQ -static inline int test_eq(char *host1, int port1, char *host2, int port2) +static inline int test4_eq(char *host1, int port1, char *host2, int port2) { return !strcasecmp(host1,host2) && port1 == port2; } #define HASH_GIVE_EXTRA_SIZE -static inline uns test_extra_size(char *host, int port UNUSED) +static inline uns test4_extra_size(char *host, int port UNUSED) { return strlen(host); } #define HASH_GIVE_INIT_KEY -static inline void test_init_key(struct node *n, char *host, int port) +static inline void test4_init_key(struct node4 *n, char *host, int port) { strcpy(n->host, host); n->port = port; @@ -211,36 +197,123 @@ static inline void test_init_key(struct node *n, char *host, int port) #include "lib/hashtable.h" -static void test(void) +static void test4(void) { int i; + char x[32]; + struct node4 *n; - test_init(); - for (i=0; i<1024; i+=2) + test4_init(); + for (i=0; i<1024; i++) + if ((i % 3) == 0) + { + sprintf(x, "abc%d", i); + n = test4_new(x, i%10); + n->data = i; + } + for (i=0; i<1024; i++) { - char x[32]; sprintf(x, "abc%d", i); - test_new(x, i%10); + n = test4_lookup(x, i%10); + n->data = i; } + for (i=0; i<1024; i++) + if (i % 2) + { + sprintf(x, "aBc%d", i); + if ((i % 7) < 3) + { + n = test4_find(x, i%10); + ASSERT(n); + test4_remove(n); + } + else + test4_delete(x, i%10); + } for (i=0; i<1024; i++) { - char x[32]; - struct node *n; sprintf(x, "ABC%d", i); - n = test_find(x, i%10); - if (!n != (i&1)) + n = test4_find(x, i%10); + if (!n != (i&1) || (n && n->data != i)) die("Inconsistency at i=%d", i); } - log(L_INFO, "OK"); - test_cleanup(); - log(L_INFO, "Cleaned up"); + test4_cleanup(); + puts("OK"); +} + +/* TEST 5: integers again, but this time dynamically */ + +struct node5 { + int key; + int data; +}; + +#define HASH_NODE struct node5 +#define HASH_PREFIX(x) test5_##x +#define HASH_KEY_ATOMIC key +#define HASH_ATOMIC_TYPE int +#define HASH_TABLE_DYNAMIC + +struct test5_table; + +#define HASH_GIVE_INIT_DATA +static inline void test5_init_data(struct test5_table *table UNUSED, struct node5 *n) +{ + n->data = n->key + 123; } -#endif +#define HASH_WANT_FIND +#define HASH_WANT_NEW +#define HASH_WANT_DELETE + +#include "lib/hashtable.h" + +static void test5(void) +{ + int i; + struct test5_table tab; + + test5_init(&tab); + for (i=0; i<1024; i++) + { + struct node5 *n = test5_new(&tab, i); + ASSERT(n->data == i+123); + } + for (i=1; i<1024; i+=2) + test5_delete(&tab, i); + for (i=0; i<1024; i++) + { + struct node5 *n = test5_find(&tab, i); + if (!n != (i&1) || (n && n->data != i+123)) + die("Inconsistency at i=%d", i); + } + i=0; + HASH_FOR_ALL_DYNAMIC(test5, &tab, n) + i += 1 + n->key; + HASH_END_FOR; + ASSERT(i == 262144); + puts("OK"); +} int -main(void) +main(int argc, char **argv) { - test(); + uns m = ~0U; + if (argc > 1) + { + m = 0; + for (int i=1; i