[read performance iterate] parse-trie iterate

This commit is contained in:
John Kerl 2015-09-02 21:12:40 -04:00
parent 8a4782dab6
commit 8b685d2db9
5 changed files with 196 additions and 0 deletions

1
.gitignore vendored
View file

@ -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

View file

@ -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

78
c/containers/parse_trie.c Normal file
View file

@ -0,0 +1,78 @@
#include <stdlib.h>
#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
}

26
c/containers/parse_trie.h Normal file
View file

@ -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

View file

@ -0,0 +1,88 @@
#include <stdio.h>
#include <string.h>
#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__