- size_t map_size;
-};
-
-static const struct trie_child_entry_f *trie_node_children(struct trie_f *trie, const struct trie_node_f *node) {
- return (const struct trie_child_entry_f *)((const char *)node + le64toh(trie->head->node_size));
-}
-
-static const struct trie_value_entry_f *trie_node_values(struct trie_f *trie, const struct trie_node_f *node) {
- const char *base = (const char *)node;
-
- base += le64toh(trie->head->node_size);
- base += node->children_count * le64toh(trie->head->child_entry_size);
- return (const struct trie_value_entry_f *)base;
-}
-
-static const struct trie_node_f *trie_node_from_off(struct trie_f *trie, le64_t off) {
- return (const struct trie_node_f *)(trie->map + le64toh(off));
-}
-
-static const char *trie_string(struct trie_f *trie, le64_t off) {
- return trie->map + le64toh(off);
-}
-
-static int trie_children_cmp_f(const void *v1, const void *v2) {
- const struct trie_child_entry_f *n1 = v1;
- const struct trie_child_entry_f *n2 = v2;
-
- return n1->c - n2->c;
-}
-
-static const struct trie_node_f *node_lookup_f(struct trie_f *trie, const struct trie_node_f *node, uint8_t c) {
- struct trie_child_entry_f *child;
- struct trie_child_entry_f search;
-
- search.c = c;
- child = bsearch(&search, trie_node_children(trie, node), node->children_count,
- le64toh(trie->head->child_entry_size), trie_children_cmp_f);
- if (child)
- return trie_node_from_off(trie, child->child_off);
- return NULL;
-}
-
-static void trie_fnmatch_f(struct trie_f *trie, const struct trie_node_f *node, size_t p,
- struct linebuf *buf, const char *search,
- void (*cb)(struct trie_f *trie, const char *key, const char *value)) {
- size_t len;
- size_t i;
- const char *prefix;
-
- prefix = trie_string(trie, node->prefix_off);
- len = strlen(prefix + p);
- linebuf_add(buf, prefix + p, len);
-
- for (i = 0; i < node->children_count; i++) {
- const struct trie_child_entry_f *child = &trie_node_children(trie, node)[i];
-
- linebuf_add_char(buf, child->c);
- trie_fnmatch_f(trie, trie_node_from_off(trie, child->child_off), 0, buf, search, cb);
- linebuf_rem_char(buf);
- }
-
- if (node->values_count && fnmatch(linebuf_get(buf), search, 0) == 0)
- for (i = 0; i < node->values_count; i++)
- cb(trie, trie_string(trie, trie_node_values(trie, node)[i].key_off),
- trie_string(trie, trie_node_values(trie, node)[i].value_off));
-
- linebuf_rem(buf, len);
-}
-
-static void trie_search_f(struct trie_f *trie, const char *search,
- void (*cb)(struct trie_f *trie, const char *key, const char *value)) {
- struct linebuf buf;
- const struct trie_node_f *node;
- size_t i = 0;
-
- linebuf_init(&buf);
-
- node = trie_node_from_off(trie, trie->head->nodes_root_off);
- while (node) {
- const struct trie_node_f *child;
- size_t p = 0;
-
- if (node->prefix_off) {
- uint8_t c;
-
- for (; (c = trie_string(trie, node->prefix_off)[p]); p++) {
- if (c == '*' || c == '?' || c == '[') {
- trie_fnmatch_f(trie, node, p, &buf, search + i + p, cb);
- return;
- }
- if (c != search[i + p])
- return;
- }
- i += p;
- }
-
- child = node_lookup_f(trie, node, '*');
- if (child) {
- linebuf_add_char(&buf, '*');
- trie_fnmatch_f(trie, child, 0, &buf, search + i, cb);
- linebuf_rem_char(&buf);
- }