From 8b685d2db956ebcb7e84b530e6ebab8321070e83 Mon Sep 17 00:00:00 2001 From: John Kerl Date: Wed, 2 Sep 2015 21:12:40 -0400 Subject: [PATCH] [read performance iterate] parse-trie iterate --- .gitignore | 1 + c/Makefile | 3 ++ c/containers/parse_trie.c | 78 ++++++++++++++++++++++++++++++ c/containers/parse_trie.h | 26 ++++++++++ c/containers/test_parse_trie.c | 88 ++++++++++++++++++++++++++++++++++ 5 files changed, 196 insertions(+) create mode 100644 c/containers/parse_trie.c create mode 100644 c/containers/parse_trie.h create mode 100644 c/containers/test_parse_trie.c diff --git a/.gitignore b/.gitignore index 83b2014d6..e327c08a1 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ mlr-unit-tester test-mlrutil test-string-builder test-string-byte-reader +test-parse-trie test-lrec test-join-bucket-keeper termcvt diff --git a/c/Makefile b/c/Makefile index 77682229c..aa1cc628b 100644 --- a/c/Makefile +++ b/c/Makefile @@ -176,6 +176,9 @@ test-mlrutil: .always test-string-builder: .always $(CCDEBUG) -D__TEST_STRING_BUILDER_MAIN__ lib/mlrutil.c lib/mlr_globals.c lib/string_builder.c lib/test_string_builder.c -o test-string-builder +test-parse-trie: .always + $(CCDEBUG) -D__TEST_PARSE_TRIE_MAIN__ lib/mlrutil.c lib/mlr_globals.c containers/parse_trie.c containers/test_parse_trie.c -o test-parse-trie + test-join-bucket-keeper: .always $(CCDEBUG) -D__TEST_JOIN_BUCKET_KEEPER_MAIN__ $(TEST_JOIN_BUCKET_KEEPER_SRCS) -o test-join-bucket-keeper diff --git a/c/containers/parse_trie.c b/c/containers/parse_trie.c new file mode 100644 index 000000000..31fbafd60 --- /dev/null +++ b/c/containers/parse_trie.c @@ -0,0 +1,78 @@ +#include +#include "lib/mlrutil.h" +#include "containers/parse_trie.h" + +static parse_trie_node_t* parse_trie_node_alloc(); +static void parse_trie_print_aux(parse_trie_node_t* pnode, int depth); + +// ---------------------------------------------------------------- +parse_trie_t* parse_trie_alloc() { + parse_trie_t* ptrie = mlr_malloc_or_die(sizeof(parse_trie_t)); + return ptrie; +} + +static parse_trie_node_t* parse_trie_node_alloc() { + parse_trie_node_t* pnode = mlr_malloc_or_die(sizeof(parse_trie_node_t)); + for (int i = 0; i < 256; i++) + pnode->pnexts[i] = NULL; + pnode->c = 0; + return pnode; +} + +// ---------------------------------------------------------------- +void parse_trie_free(parse_trie_t* ptrie) { + return; // xxx stub +} + +// ---------------------------------------------------------------- +void parse_trie_print(parse_trie_t* ptrie) { + parse_trie_node_t* pnode = ptrie->proot; + printf("PARSE TRIE DUMP START\n"); + if (pnode != NULL) { + parse_trie_print_aux(pnode, 0); + } + printf("PARSE TRIE DUMP END\n"); +} + +static void parse_trie_print_aux(parse_trie_node_t* pnode, int depth) { + printf("[pnode=%p]\n", pnode); + for (int i = 0; i < depth; i++) + printf(" "); + printf("c=%c,stridx=%d,strlen=%d\n", pnode->c, pnode->stridx, pnode->strlen); + printf("[pnode=%p]\n", pnode); + for (int i = 0; i < 256; i++) { + parse_trie_node_t* pnext = pnode->pnexts[i]; + if (pnext != NULL) { + parse_trie_print_aux(pnext, depth+1); + } + } +} + +// ---------------------------------------------------------------- +void parse_trie_add_string(parse_trie_t* ptrie, char* string) { + if (ptrie->proot == NULL) { + ptrie->proot = parse_trie_node_alloc(); + } + //parse_trie_node_t* pnode = ptrie->proot; + return; // xxx stub +} + +// ---------------------------------------------------------------- +// Example: +// * string 0 is "a" +// * string 1 is "aa" +// * buf is "aaabc" +int parse_trie_match(parse_trie_t* ptrie, char* buf, int buflen, int* pstridx, int* pmatchlen) { + parse_trie_node_t* pnode = ptrie->proot; + parse_trie_node_t* pnext; + int i; + for (i = 0; i < buflen; i++) { + char c = buf[i]; + pnext = pnode->pnexts[(unsigned) c]; + // xxx not quite right + if (pnode == NULL) + return FALSE; + pnode = pnext; + } + return TRUE; // xxx stub +} diff --git a/c/containers/parse_trie.h b/c/containers/parse_trie.h new file mode 100644 index 000000000..e252f41f6 --- /dev/null +++ b/c/containers/parse_trie.h @@ -0,0 +1,26 @@ +#ifndef PARSE_TRIE_H +#define PARSE_TRIE_H + +// ---------------------------------------------------------------- +// xxx cmt for data parse, not DSL parse. +// xxx cmt why not flex/lemon: want streaming, not ingest-all. +struct _parse_trie_node_t; +typedef struct _parse_trie_node_t { + struct _parse_trie_node_t* pnexts[256]; + char c; // current character at this node + int stridx; // which string was stored ending here; -1 if not end of string. + int strlen; // length of string stored ending here; -1 if not end of string. +} parse_trie_node_t; +typedef struct _parse_trie_t { + parse_trie_node_t* proot; + int maxlen; +} parse_trie_t; + +// ---------------------------------------------------------------- +parse_trie_t* parse_trie_alloc(); +void parse_trie_free(parse_trie_t* ptrie); +void parse_trie_print(parse_trie_t* ptrie); +void parse_trie_add_string(parse_trie_t* ptrie, char* string); +int parse_trie_match(parse_trie_t* ptrie, char* buf, int buflen, int* pstridx, int* pmatchlen); + +#endif // PARSE_TRIE_H diff --git a/c/containers/test_parse_trie.c b/c/containers/test_parse_trie.c new file mode 100644 index 000000000..899eca5f6 --- /dev/null +++ b/c/containers/test_parse_trie.c @@ -0,0 +1,88 @@ +#include +#include +#include "lib/minunit.h" +#include "lib/mlrutil.h" +#include "containers/parse_trie.h" + +#ifdef __TEST_PARSE_TRIE_MAIN__ +int tests_run = 0; +int tests_failed = 0; +int assertions_run = 0; +int assertions_failed = 0; + +// ---------------------------------------------------------------- +static char * test_disjoint() { + parse_trie_t* ptrie = parse_trie_alloc(); + parse_trie_add_string(ptrie, "abc"); + parse_trie_add_string(ptrie, "fg"); + parse_trie_print(ptrie); + + int stridx = -2; + int matchlen = -2; + int rc = parse_trie_match(ptrie, "abcde", 2, &stridx, &matchlen); + mu_assert_lf(rc == TRUE); + mu_assert_lf(stridx == 0); + mu_assert_lf(matchlen == 3); + + parse_trie_free(ptrie); + return 0; +} + +// ---------------------------------------------------------------- +static char * test_short_long() { + parse_trie_t* ptrie = parse_trie_alloc(); + parse_trie_add_string(ptrie, "a"); + parse_trie_add_string(ptrie, "aa"); + + int stridx = -2; + int matchlen = -2; + int rc = parse_trie_match(ptrie, "aaabc", 2, &stridx, &matchlen); + mu_assert_lf(rc == TRUE); + mu_assert_lf(stridx == 0); + mu_assert_lf(matchlen == 3); + + parse_trie_free(ptrie); + return 0; +} + +// ---------------------------------------------------------------- +static char * test_long_short() { + parse_trie_t* ptrie = parse_trie_alloc(); + parse_trie_add_string(ptrie, "aa"); + parse_trie_add_string(ptrie, "a"); + + int stridx = -2; + int matchlen = -2; + int rc = parse_trie_match(ptrie, "aaabc", 2, &stridx, &matchlen); + mu_assert_lf(rc == TRUE); + mu_assert_lf(stridx == 0); + mu_assert_lf(matchlen == 3); + + parse_trie_free(ptrie); + return 0; +} + +// ================================================================ +static char * all_tests() { + mu_run_test(test_disjoint); + mu_run_test(test_short_long); + mu_run_test(test_long_short); + return 0; +} + +int main(int argc, char **argv) { + char *result = all_tests(); + printf("\n"); + if (result != 0) { + //printf("%s\n", result); + printf("Not all unit tests passed\n"); + } + else { + printf("TEST_PARSE_TRIE: ALL UNIT TESTS PASSED\n"); + } + printf("Tests passed: %d of %d\n", tests_run - tests_failed, tests_run); + printf("Assertions passed: %d of %d\n", assertions_run - assertions_failed, assertions_run); + + return result != 0; +} +#endif // __TEST_PARSE_TRIE_MAIN__