[read performance iterate] parse-trie iterate

This commit is contained in:
John Kerl 2015-09-02 22:20:59 -04:00
parent 1d2ab64bb3
commit b6ac95ff4c
3 changed files with 89 additions and 26 deletions

View file

@ -1,21 +1,27 @@
#include <stdlib.h>
#include <ctype.h>
#include "lib/mlrutil.h"
#include "containers/parse_trie.h"
static parse_trie_node_t* parse_trie_node_alloc();
static parse_trie_node_t* parse_trie_node_alloc(char c);
static void parse_trie_print_aux(parse_trie_node_t* pnode, int depth);
static void parse_trie_add_string_aux(parse_trie_node_t* pnode, char* string, int stridx, int len);
// ----------------------------------------------------------------
parse_trie_t* parse_trie_alloc() {
parse_trie_t* ptrie = mlr_malloc_or_die(sizeof(parse_trie_t));
ptrie->proot = parse_trie_node_alloc(0);
ptrie->maxlen = 0;
return ptrie;
}
static parse_trie_node_t* parse_trie_node_alloc() {
static parse_trie_node_t* parse_trie_node_alloc(char c) {
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;
pnode->c = c;
pnode->stridx = -1;
pnode->strlen = -1;
return pnode;
}
@ -35,33 +41,62 @@ void parse_trie_print(parse_trie_t* ptrie) {
}
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);
printf("c=%c[%02x],stridx=%d,strlen=%d\n",
isprint((unsigned char)pnode->c) ? pnode->c : '?',
(unsigned)pnode->c,
pnode->stridx,
pnode->strlen);
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);
} else {
//printf("c=%c[%02x],stridx=%d,strlen=%d\n",
//isprint((unsigned char)pnode->c) ? pnode->c : '?',
//(unsigned)pnode->c,
//pnode->stridx,
//pnode->strlen);
}
}
}
// ----------------------------------------------------------------
void parse_trie_add_string(parse_trie_t* ptrie, char* string) {
if (ptrie->proot == NULL) {
ptrie->proot = parse_trie_node_alloc();
void parse_trie_add_string(parse_trie_t* ptrie, char* string, int stridx) {
int len = strlen(string);
parse_trie_add_string_aux(ptrie->proot, string, stridx, strlen(string));
if (len > ptrie->maxlen)
ptrie->maxlen = len;
}
static void parse_trie_add_string_aux(parse_trie_node_t* pnode, char* string, int stridx, int len) {
char c = string[0];
if (c == 0) {
pnode->stridx = stridx;
pnode->strlen = len;
} else {
parse_trie_node_t* pnext = pnode->pnexts[(unsigned)c];
if (pnext == NULL) {
pnext = parse_trie_node_alloc(c);
pnext->c = c;
pnext->stridx = -1;
pnext->strlen = -1;
pnode->pnexts[(unsigned)c] = pnext;
}
parse_trie_add_string_aux(pnext, &string[1], stridx, len);
}
//parse_trie_node_t* pnode = ptrie->proot;
return; // xxx stub
}
// ----------------------------------------------------------------
// Example:
// Example input:
// * string 0 is "a"
// * string 1 is "aa"
// * buf is "aaabc"
// Output:
// * return value is TRUE
// * stridx is 1 since longest match is "aa"
// * matchlen is 2 since "aa" has length 2
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;
@ -69,10 +104,14 @@ int parse_trie_match(parse_trie_t* ptrie, char* buf, int buflen, int* pstridx, i
for (i = 0; i < buflen; i++) {
char c = buf[i];
pnext = pnode->pnexts[(unsigned) c];
// xxx not quite right
if (pnode == NULL)
if (pnext == NULL)
return FALSE;
if (pnext->strlen > 0) {
*pstridx = pnext->stridx;
*pmatchlen = pnext->strlen;
return TRUE;
}
pnode = pnext;
}
return TRUE; // xxx stub
return FALSE;
}

View file

@ -20,7 +20,7 @@ typedef struct _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);
void parse_trie_add_string(parse_trie_t* ptrie, char* string, int stridx);
int parse_trie_match(parse_trie_t* ptrie, char* buf, int buflen, int* pstridx, int* pmatchlen);
#endif // PARSE_TRIE_H

View file

@ -11,15 +11,38 @@ int assertions_run = 0;
int assertions_failed = 0;
// ----------------------------------------------------------------
static char * test_disjoint() {
static char * test_simplest() {
parse_trie_t* ptrie = parse_trie_alloc();
parse_trie_add_string(ptrie, "abc");
parse_trie_add_string(ptrie, "fg");
parse_trie_print(ptrie);
parse_trie_add_string(ptrie, "a", 0);
parse_trie_print(ptrie);
int stridx = -2;
int matchlen = -2;
int rc = parse_trie_match(ptrie, "abcde", 2, &stridx, &matchlen);
int rc = parse_trie_match(ptrie, "a", 1, &stridx, &matchlen);
mu_assert_lf(rc == TRUE);
mu_assert_lf(stridx == 0);
mu_assert_lf(matchlen == 1);
parse_trie_free(ptrie);
return 0;
}
// ----------------------------------------------------------------
static char * test_disjoint() {
parse_trie_t* ptrie = parse_trie_alloc();
parse_trie_print(ptrie);
parse_trie_add_string(ptrie, "abc", 0);
parse_trie_print(ptrie);
parse_trie_add_string(ptrie, "fg", 1);
parse_trie_print(ptrie);
int stridx = -2;
int matchlen = -2;
int rc = parse_trie_match(ptrie, "abcde", 5, &stridx, &matchlen);
printf("rc = %d\n", rc);
printf("stridx = %d\n", stridx);
printf("matchlen = %d\n", matchlen);
mu_assert_lf(rc == TRUE);
mu_assert_lf(stridx == 0);
mu_assert_lf(matchlen == 3);
@ -31,12 +54,12 @@ static char * test_disjoint() {
// ----------------------------------------------------------------
static char * test_short_long() {
parse_trie_t* ptrie = parse_trie_alloc();
parse_trie_add_string(ptrie, "a");
parse_trie_add_string(ptrie, "aa");
parse_trie_add_string(ptrie, "a", 0);
parse_trie_add_string(ptrie, "aa", 1);
int stridx = -2;
int matchlen = -2;
int rc = parse_trie_match(ptrie, "aaabc", 2, &stridx, &matchlen);
int rc = parse_trie_match(ptrie, "aaabc", 5, &stridx, &matchlen);
mu_assert_lf(rc == TRUE);
mu_assert_lf(stridx == 0);
mu_assert_lf(matchlen == 3);
@ -48,12 +71,12 @@ static char * test_short_long() {
// ----------------------------------------------------------------
static char * test_long_short() {
parse_trie_t* ptrie = parse_trie_alloc();
parse_trie_add_string(ptrie, "aa");
parse_trie_add_string(ptrie, "a");
parse_trie_add_string(ptrie, "aa", 0);
parse_trie_add_string(ptrie, "a", 1);
int stridx = -2;
int matchlen = -2;
int rc = parse_trie_match(ptrie, "aaabc", 2, &stridx, &matchlen);
int rc = parse_trie_match(ptrie, "aaabc", 5, &stridx, &matchlen);
mu_assert_lf(rc == TRUE);
mu_assert_lf(stridx == 0);
mu_assert_lf(matchlen == 3);
@ -64,6 +87,7 @@ static char * test_long_short() {
// ================================================================
static char * all_tests() {
mu_run_test(test_simplest);
mu_run_test(test_disjoint);
mu_run_test(test_short_long);
mu_run_test(test_long_short);