X-Git-Url: http://git.madism.org/?a=blobdiff_plain;f=common%2Ftrie.c;h=5ed957f48082598f08fb94d2965a24842c8a84d0;hb=87a5fb7f3d8be835f151f0534e5b36bd9583f1c5;hp=4575a636680f826d3681f6b99847306df12159d0;hpb=4967e5b5d3bba84232eebf9763eb214ef395e061;p=apps%2Fpfixtools.git diff --git a/common/trie.c b/common/trie.c index 4575a63..5ed957f 100644 --- a/common/trie.c +++ b/common/trie.c @@ -76,6 +76,7 @@ void trie_delete(trie_t **trie) } p_delete(&(entry->children)); } + p_delete(&(*trie)->entries); p_delete(trie); } } @@ -132,23 +133,37 @@ static inline trie_entry_t* trie_entry_child(const trie_t *trie, return NULL; } -static void trie_grow(trie_t *trie, int delta) +static inline void trie_grow(trie_t *trie, int delta) { - p_allocgrow(&trie->entries, trie->entries_len + delta, &trie->entries_size); + int next_size = trie->entries_size; + if (next_size > trie->entries_len + delta) { + return; + } + do { + next_size = p_alloc_nr(next_size); + } while (trie->entries_len + delta > next_size); + p_allocgrow(&trie->entries, next_size, &trie->entries_size); + printf("After grow: %d\n", trie->entries_size); +} + +static inline int trie_entry_new(trie_t *trie) +{ + memset(trie->entries + trie->entries_len, 0, sizeof(trie_entry_t)); + return trie->entries_len++; } -static int trie_add_leaf(trie_t *trie, const char *key) +static inline int trie_add_leaf(trie_t *trie, const char *key) { trie_entry_t *entry; - trie_grow(trie, 1); - entry = &trie->entries[trie->entries_len++]; + entry = &trie->entries[trie_entry_new(trie)]; entry->c = m_strdup(key); entry->c_len = m_strlen(key) + 1; entry->c_own = true; return trie->entries_len - 1; } -static void trie_entry_insert_child(trie_t *trie, trie_entry_t *entry, int pchild) +static inline void trie_entry_insert_child(trie_t *trie, trie_entry_t *entry, + int pchild) { const char c = trie->entries[pchild].c[0]; int start = 0; @@ -176,13 +191,13 @@ static void trie_entry_insert_child(trie_t *trie, trie_entry_t *entry, int pchil entry->children + start, sizeof(int) * (entry->children_len - start)); entry->children[start] = pchild; + ++entry->children_len; } -static void trie_entry_split(trie_t *trie, trie_entry_t *entry, int pos) +static inline void trie_entry_split(trie_t *trie, trie_entry_t *entry, int pos) { trie_entry_t *child; - trie_grow(trie, 2); - child = &trie->entries[trie->entries_len++]; + child = &trie->entries[trie_entry_new(trie)]; if (pos == 0) { child->c = entry->c; child->c_len = entry->c_len; @@ -194,7 +209,7 @@ static void trie_entry_split(trie_t *trie, trie_entry_t *entry, int pos) child->c = entry->c + pos; child->c_len = entry->c_len - pos; child->c_own = false; - entry->c_len -= pos; + entry->c_len = pos; } child->children = entry->children; child->children_len = entry->children_len; @@ -207,6 +222,7 @@ static void trie_entry_split(trie_t *trie, trie_entry_t *entry, int pos) void trie_insert(trie_t *trie, const char* key) { + trie_grow(trie, 2); if (trie->entries_len == 0) { (void)trie_add_leaf(trie, key); } else { @@ -214,6 +230,9 @@ void trie_insert(trie_t *trie, const char* key) while (true) { int pos = 0; if (trie_entry_c_match(current, key, &pos)) { + if (current->c_len && current->c[current->c_len - 1] == '\0') { + return; + } trie_entry_t *next = NULL; key += pos; next = trie_entry_child(trie, current, key); @@ -257,3 +276,35 @@ bool trie_lookup(const trie_t *trie, const char *key) } } } + + +/* Debug {{{1 + */ + +static inline void trie_entry_inspect(const trie_t *trie, + const trie_entry_t *entry, int level) +{ + for (int i = 0 ; i < level ; ++i) { + fputs(" ", stdout); + } + if (entry->c == NULL) { + fputs("(nil)", stdout); + } else { + for (int i = 0 ; i < entry->c_len ; ++i) { + if (entry->c[i]) { + printf("%c ", entry->c[i]); + } else { + fputs("\\0 ", stdout); + } + } + } + fputs("\n", stdout); + for (int i = 0 ; i < entry->children_len ; ++i) { + trie_entry_inspect(trie, &trie->entries[entry->children[i]], level + 1); + } +} + +void trie_inspect(const trie_t *trie) +{ + trie_entry_inspect(trie, trie->entries, 0); +}