]> Sergey Matveev's repositories - bfs.git/commitdiff
tests/trie: New acceptance test for tries
authorTavian Barnes <tavianator@tavianator.com>
Tue, 9 Jun 2020 16:56:28 +0000 (12:56 -0400)
committerTavian Barnes <tavianator@tavianator.com>
Tue, 9 Jun 2020 17:01:37 +0000 (13:01 -0400)
.gitignore
Makefile
tests/trie.c [new file with mode: 0644]

index c18ddc3652d89905c582c4826863b7d5886c7b6e..7a60b0c8f0fd22adc384606afd1490fb4be98468 100644 (file)
@@ -2,4 +2,5 @@
 *.d
 /bfs
 /tests/mksock
+/tests/trie
 /tests/xtimegm
index 4f4c1e355813164c25a3b87c9279a1ad939d69a2..384496624ef4df7e3e5c7c8124579703a384c289 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -89,7 +89,7 @@ ALL_LDLIBS = $(LOCAL_LDLIBS) $(LDLIBS)
 
 default: bfs
 
-all: bfs tests/mksock tests/xtimegm
+all: bfs tests/mksock tests/trie tests/xtimegm
 
 bfs: \
     bftw.o \
@@ -126,13 +126,19 @@ release: bfs
 tests/mksock: tests/mksock.o
        $(CC) $(ALL_LDFLAGS) $^ -o $@
 
+tests/trie: trie.o tests/trie.o
+       $(CC) $(ALL_LDFLAGS) $^ -o $@
+
 tests/xtimegm: time.o tests/xtimegm.o
        $(CC) $(ALL_LDFLAGS) $^ -o $@
 
 %.o: %.c
        $(CC) $(ALL_CFLAGS) -c $< -o $@
 
-check: check-xtimegm check-bfs check-dfs check-ids
+check: check-trie check-xtimegm check-bfs check-dfs check-ids
+
+check-trie: tests/trie
+       $<
 
 check-xtimegm: tests/xtimegm
        $<
@@ -150,7 +156,7 @@ endif
        +$(MAKE) -B check $(DISTCHECK_FLAGS)
 
 clean:
-       $(RM) bfs *.[od] tests/mksock tests/xtimegm tests/*.[od]
+       $(RM) bfs *.[od] tests/mksock tests/trie tests/xtimegm tests/*.[od]
 
 install:
        $(MKDIR) $(DESTDIR)$(PREFIX)/bin
@@ -162,6 +168,6 @@ uninstall:
        $(RM) $(DESTDIR)$(PREFIX)/bin/bfs
        $(RM) $(DESTDIR)$(MANDIR)/man1/bfs.1
 
-.PHONY: all asan ubsan msan release check distcheck clean install uninstall
+.PHONY: all asan ubsan msan release check check-trie check-xtimegm distcheck clean install uninstall
 
 -include $(wildcard *.d)
diff --git a/tests/trie.c b/tests/trie.c
new file mode 100644 (file)
index 0000000..7182a03
--- /dev/null
@@ -0,0 +1,118 @@
+#undef NDEBUG
+
+#include "../trie.h"
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+const char *keys[] = {
+       "foo",
+       "bar",
+       "baz",
+       "qux",
+       "quux",
+       "quuux",
+       "quuuux",
+
+       "pre",
+       "pref",
+       "prefi",
+       "prefix",
+
+       "AAAA",
+       "AADD",
+       "ABCD",
+       "DDAA",
+       "DDDD",
+
+       "<<<",
+       "<<<>>>",
+       "<<<<<<",
+       "<<<<<<>>>>>>",
+       ">>>>>>",
+       ">>><<<",
+       ">>>",
+};
+
+const size_t nkeys = sizeof(keys) / sizeof(keys[0]);
+
+int main(void) {
+       struct trie trie;
+       trie_init(&trie);
+
+       for (size_t i = 0; i < nkeys; ++i) {
+               assert(!trie_find_str(&trie, keys[i]));
+
+               const char *prefix = NULL;
+               for (size_t j = 0; j < i; ++j) {
+                       if (strncmp(keys[i], keys[j], strlen(keys[j])) == 0) {
+                               if (!prefix || strcmp(keys[j], prefix) > 0) {
+                                       prefix = keys[j];
+                               }
+                       }
+               }
+
+               struct trie_leaf *leaf = trie_find_prefix(&trie, keys[i]);
+               if (prefix) {
+                       assert(leaf);
+                       assert(strcmp(prefix, leaf->key) == 0);
+               } else {
+                       assert(!leaf);
+               }
+
+               leaf = trie_insert_str(&trie, keys[i]);
+               assert(leaf);
+               assert(strcmp(keys[i], leaf->key) == 0);
+               assert(leaf->length == strlen(keys[i]) + 1);
+       }
+
+       for (size_t i = 0; i < nkeys; ++i) {
+               struct trie_leaf *leaf = trie_find_str(&trie, keys[i]);
+               assert(leaf);
+               assert(strcmp(keys[i], leaf->key) == 0);
+               assert(leaf->length == strlen(keys[i]) + 1);
+
+               trie_remove(&trie, leaf);
+               leaf = trie_find_str(&trie, keys[i]);
+               assert(!leaf);
+
+               const char *postfix = NULL;
+               for (size_t j = i + 1; j < nkeys; ++j) {
+                       if (strncmp(keys[i], keys[j], strlen(keys[i])) == 0) {
+                               if (!postfix || strcmp(keys[j], postfix) < 0) {
+                                       postfix = keys[j];
+                               }
+                       }
+               }
+
+               leaf = trie_find_postfix(&trie, keys[i]);
+               if (postfix) {
+                       assert(leaf);
+                       assert(strcmp(postfix, leaf->key) == 0);
+               } else {
+                       assert(!leaf);
+               }
+       }
+
+       // This tests the "jump" node handline on 32-bit platforms
+       size_t longsize = 1 << 20;
+       char *longstr = malloc(longsize);
+       assert(longstr);
+
+       memset(longstr, 0xAC, longsize);
+       assert(!trie_find_mem(&trie, longstr, longsize));
+       assert(trie_insert_mem(&trie, longstr, longsize));
+
+       memset(longstr + longsize/2, 0xAB, longsize/2);
+       assert(!trie_find_mem(&trie, longstr, longsize));
+       assert(trie_insert_mem(&trie, longstr, longsize));
+
+       memset(longstr, 0xAA, longsize/2);
+       assert(!trie_find_mem(&trie, longstr, longsize));
+       assert(trie_insert_mem(&trie, longstr, longsize));
+
+       free(longstr);
+       trie_destroy(&trie);
+       return EXIT_SUCCESS;
+}