/* Tests for hash table routines */
#include "lib/lib.h"
+#include "lib/mempool.h"
#include <stdio.h>
#include <string.h>
-#if 0
-
/* 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_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
#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
#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);
}
#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;
#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<argc; i++)
+ m |= 1 << atol(argv[i]);
+ }
+ if (m & (1 << 1))
+ test1();
+ if (m & (1 << 2))
+ test2();
+ if (m & (1 << 3))
+ test3();
+ if (m & (1 << 4))
+ test4();
+ if (m & (1 << 5))
+ test5();
return 0;
}