mirror of
https://github.com/johnkerl/miller.git
synced 2026-07-26 09:23:55 +00:00
[read performance iterate] parse-trie iterate
This commit is contained in:
parent
1d2ab64bb3
commit
b6ac95ff4c
3 changed files with 89 additions and 26 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue