#include #include #include #include #include #include #include "treetrie.h" #include "critbit.h" #include "route.h" static inline tt_node_ptr_t rseq(tt_arena_t *a, tt_atom_t s, tt_node_ptr_t r) { if (TT_EMPTY_P(r)) { return TT_EMPTY; } assert(s != TT_WILD); return tt_cons_branch(a, TT_EMPTY, RET_IF_NO_PTR(tt_dict_singleton(a, s, r))); } static inline tt_node_ptr_t rwild(tt_arena_t *a, tt_node_ptr_t r) { if (TT_EMPTY_P(r)) { return TT_EMPTY; } return tt_cons_branch(a, r, TT_EMPTY_DICT); } static inline tt_node_ptr_t rbranch(tt_arena_t *a, tt_node_ptr_t wild, /* trie */ tt_node_ptr_t others) /* dict */ { if (TT_EMPTY_P(wild) && TT_EMPTY_DICT_P(others)) { return TT_EMPTY; } return tt_cons_branch(a, wild, others); } static inline tt_node_ptr_t rwildseq(tt_arena_t *a, tt_node_ptr_t r) { if (TT_EMPTY_P(r)) { return TT_EMPTY; } return tt_cons_tail(a, r); } static inline tt_node_ptr_t runwildseq(tt_arena_t *a, tt_node_ptr_t r) { if (tt_ptr_tag(r) == TT_TAG_TAIL) { return TT_TAIL_TRIE(a,r); } else { return TT_EMPTY; } } static inline tt_node_ptr_t rlookup(tt_arena_t *a, tt_node_ptr_t r, tt_atom_t key) { tt_node_ptr_t result; assert(tt_ptr_tag(r) == TT_TAG_BRANCH); result = tt_dict_get(a, TT_BRANCH_OTHERS(a,r), key); if (!TT_NO_PTR_P(result)) { return result; } result = TT_BRANCH_WILDCARD(a,r); switch (key) { case TT_BOS: return rwildseq(a, result); case TT_EOS: return runwildseq(a, result); default: return result; } } static inline tt_node_ptr_t rupdate(tt_arena_t *a, tt_node_ptr_t r0, /* branch */ tt_atom_t key, tt_node_ptr_t k) /* trie */ { assert(key != TT_WILD); if (TT_EMPTY_P(r0)) { return rseq(a, key, k); } else { tt_node_ptr_t old_wild; tt_node_ptr_t old_others; assert(tt_ptr_tag(r0) == TT_TAG_BRANCH); old_wild = TT_BRANCH_WILDCARD(a,r0); old_others = TT_BRANCH_OTHERS(a,r0); #define R0_SANS_KEY() (rbranch(a, old_wild, RET_IF_NO_PTR(tt_dict_remove(a, old_others, key)))) #define R0_WITH_KEY() (rbranch(a, old_wild, RET_IF_NO_PTR(tt_dict_set(a, old_others, key, k)))) switch (key) { case TT_BOS: if (tt_ptr_tag(k) == TT_TAG_TAIL) { return (TT_TAIL_TRIE(a,k) == old_wild) ? R0_SANS_KEY() : R0_WITH_KEY(); } else { return TT_EMPTY_P(k) ? R0_SANS_KEY() : R0_WITH_KEY(); } case TT_EOS: if (tt_ptr_tag(old_wild) == TT_TAG_TAIL) { return (TT_TAIL_TRIE(a,old_wild) == k) ? R0_SANS_KEY() : R0_WITH_KEY(); } else { return TT_EMPTY_P(k) ? R0_SANS_KEY() : R0_WITH_KEY(); } default: return (k == old_wild) ? R0_SANS_KEY() : R0_WITH_KEY(); } #undef R0_SANS_KEY #undef R0_WITH_KEY } } /* static tt_node_ptr_t combine(tt_arena_t *a, */ /* tt_node_ptr_t r1, */ /* tt_node_ptr_t r2, */ /* int left_empty_keep, */ /* int right_empty_keep, */ /* int left_base_keep, */ /* int right_base_keep, */ /* void *f_context, */ /* tt_node_ptr_t (*f)(void *f_context, tt_node_ptr_t r1, tt_node_ptr_t r2)) */ /* { */ /* tt_node_ptr_t g(tt_node_ptr_t r1, tt_node_ptr_t r2) { */ /* tt_tag_t t1, t2; */ /* if (TT_EMPTY_P(r1)) { */ /* return left_empty_keep ? r2 : TT_EMPTY; */ /* } */ /* if (TT_EMPTY_P(r2)) { */ /* return right_empty_keep ? r1 : TT_EMPTY; */ /* } */ /* t1 = tt_ptr_tag(r1); */ /* t2 = tt_ptr_tag(r2); */ /* if (t1 == TT_TAG_TAIL) { */ /* if (t2 == TT_TAG_TAIL) { */ /* return rwildseq(a, RET_IF_NO_PTR(g(TT_TAIL_TRIE(a,r1), TT_TAIL_TRIE(a,r2)))); */ /* } else { */ /* ....HERE */ /* } */ /* switch (tt_ptr_tag(r1)) { */ /* default: */ /* abort(); */ /* } */ /* } */ /* return g(r1, r2); */ /* } */