diff options
author | Erkki Seppälä <erkki.seppala@vincit.fi> | 2010-12-14 12:18:23 +0200 |
---|---|---|
committer | Erkki Seppälä <erkki.seppala@vincit.fi> | 2012-04-18 12:49:06 +0300 |
commit | ccb3e78124fb05defd0c9b438746b79d84dfc3ae (patch) | |
tree | 605d662d1a8b082ddb329af63751ec9a8de0a832 /test | |
parent | a2ac01a8ea8508ed35aa844a589672c1165e05e4 (diff) |
Xext: add a generic hashtable implementation
The generic hashtable implementation adds a key-value container, that
keeps the key and value inside the hashtable structure and manages
their memory by itself. This data structure is best suited for
fixed-length keys and values.
One creates a new hash table with ht_create and disposes it with
ht_destroy. ht_create accepts the key and value sizes (in bytes) in
addition to the hashing and comparison functions to use. When adding
keys with ht_add, they will be copied into the hash and a pointer to
the value will be returned: data may be put into this structure (or if
the hash table is to be used as a set, one can just not put anything
in).
The hash table comes also with one generic hashing function plus a
comparison function to facilitate ease of use. It also has a custom
hashing and comparison functions for hashing resource IDs with
HashXID.
Reviewed-by: Rami Ylimäki <rami.ylimaki@vincit.fi>
Signed-off-by: Erkki Seppälä <erkki.seppala@vincit.fi>
Diffstat (limited to 'test')
-rw-r--r-- | test/Makefile.am | 3 | ||||
-rw-r--r-- | test/hashtabletest.c | 162 |
2 files changed, 164 insertions, 1 deletions
diff --git a/test/Makefile.am b/test/Makefile.am index eb6147021..8c7e412c3 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -5,7 +5,7 @@ if XORG # Tests that require at least some DDX functions in order to fully link # For now, requires xf86 ddx, could be adjusted to use another SUBDIRS += xi2 -noinst_PROGRAMS += xkb input xtest misc fixes xfree86 +noinst_PROGRAMS += xkb input xtest misc fixes xfree86 hashtabletest endif check_LTLIBRARIES = libxservertest.la @@ -36,6 +36,7 @@ misc_LDADD=$(TEST_LDADD) fixes_LDADD=$(TEST_LDADD) xfree86_LDADD=$(TEST_LDADD) touch_LDADD=$(TEST_LDADD) +hashtabletest_LDADD=$(TEST_LDADD) ../Xext/hashtable.c libxservertest_la_LIBADD = $(XSERVER_LIBS) if XORG diff --git a/test/hashtabletest.c b/test/hashtabletest.c new file mode 100644 index 000000000..64c7091fc --- /dev/null +++ b/test/hashtabletest.c @@ -0,0 +1,162 @@ +#include <misc.h> +#include <stdlib.h> +#include <stdio.h> +#include "hashtable.h" +#include "resource.h" + +static void +print_xid(void* ptr, void* v) +{ + XID *x = v; + printf("%ld", *x); +} + +static void +print_int(void* ptr, void* v) +{ + int *x = v; + printf("%d", *x); +} + +static int +test1(void) +{ + HashTable h; + XID id; + int c; + int ok = 1; + const int numKeys = 420; + + printf("test1\n"); + h = ht_create(sizeof(XID), sizeof(int), ht_resourceid_hash, ht_resourceid_compare, NULL); + + for (c = 0; c < numKeys; ++c) { + int *dest; + id = c; + dest = ht_add(h, &id); + if (dest) { + *dest = 2 * c; + } + } + + printf("Distribution after insertion\n"); + ht_dump_distribution(h); + ht_dump_contents(h, print_xid, print_int, NULL); + + for (c = 0; c < numKeys; ++c) { + XID id = c; + int* v = ht_find(h, &id); + if (v) { + if (*v == 2 * c) { + // ok + } else { + printf("Key %d doesn't have expected value %d but has %d instead\n", + c, 2 * c, *v); + ok = 0; + } + } else { + ok = 0; + printf("Cannot find key %d\n", c); + } + } + + if (ok) { + printf("%d keys inserted and found\n", c); + + for (c = 0; c < numKeys; ++c) { + XID id = c; + ht_remove(h, &id); + } + + printf("Distribution after deletion\n"); + ht_dump_distribution(h); + } + + ht_destroy(h); + + return ok; +} + +static int +test2(void) +{ + HashTable h; + XID id; + int c; + int ok = 1; + const int numKeys = 420; + + printf("test2\n"); + h = ht_create(sizeof(XID), 0, ht_resourceid_hash, ht_resourceid_compare, NULL); + + for (c = 0; c < numKeys; ++c) { + id = c; + ht_add(h, &id); + } + + for (c = 0; c < numKeys; ++c) { + XID id = c; + if (!ht_find(h, &id)) { + ok = 0; + printf("Cannot find key %d\n", c); + } + } + + { + XID id = c + 1; + if (ht_find(h, &id)) { + ok = 0; + printf("Could find a key that shouldn't be there\n"); + } + } + + ht_destroy(h); + + if (ok) { + printf("Test with empty keys OK\n"); + } else { + printf("Test with empty keys FAILED\n"); + } + + return ok; +} + +static int +test3(void) +{ + int ok = 1; + HtGenericHashSetupRec hashSetup = { + .keySize = 4 + }; + HashTable h; + printf("test3\n"); + h = ht_create(4, 0, ht_generic_hash, ht_generic_compare, &hashSetup); + + if (!ht_add(h, "helo") || + !ht_add(h, "wrld")) { + printf("Could not insert keys\n"); + } + + if (!ht_find(h, "helo") || + !ht_find(h, "wrld")) { + ok = 0; + printf("Could not find inserted keys\n"); + } + + printf("Hash distribution with two strings\n"); + ht_dump_distribution(h); + + ht_destroy(h); + + return ok; +} + +int +main(void) +{ + int ok = test1(); + ok = ok && test2(); + ok = ok && test3(); + + return ok ? 0 : 1; +} |