Subtraction; relabelling; pretty output
This commit is contained in:
parent
85a139f5dd
commit
0e88711a50
10
TODO.md
10
TODO.md
|
@ -1,5 +1,7 @@
|
|||
Consider whether a stack or a queue makes most sense for the freelist.
|
||||
|
||||
Consider a naming convention to indicate grab'd vs ungrab'd results.
|
||||
|
||||
|
||||
Needed by prospect:
|
||||
|
||||
|
@ -87,8 +89,6 @@ Needed by prospect:
|
|||
}
|
||||
|
||||
// patch
|
||||
// composePatch -> subtractUnit;
|
||||
// composePatch -> unionUnit;
|
||||
// computePatch -> subtractUnit; // I guess?
|
||||
// stripInterests -> relabel;
|
||||
// stripPatch -> stripInterests;
|
||||
|
@ -96,6 +96,8 @@ Needed by prospect:
|
|||
applyPatch -> unionPIDs;
|
||||
biasedIntersection -> intersectUnit;
|
||||
biasedIntersection -> step;
|
||||
composePatch -> subtractUnit;
|
||||
composePatch -> unionUnit;
|
||||
computeAggregatePatch -> subtractCustom;
|
||||
labelInterests -> relabel;
|
||||
limitPatch -> intersectAsymmetric;
|
||||
|
@ -105,6 +107,7 @@ Needed by prospect:
|
|||
updateInterests -> unionUnit;
|
||||
dropInterests -> project;
|
||||
labelPatch -> labelInterests;
|
||||
patchSeq -> composePatch;
|
||||
|
||||
// mux
|
||||
computeAffectedPIDs -> matchMatcher;
|
||||
|
@ -121,11 +124,12 @@ Needed by prospect:
|
|||
muxUpdateStream -> patchUnion;
|
||||
|
||||
// core
|
||||
observeAtMeta -> union;
|
||||
observeAtMeta -> unionUnit;
|
||||
|
||||
// user code
|
||||
userCode -> project;
|
||||
userCode -> observeAtMeta;
|
||||
userCode -> patchSeq;
|
||||
|
||||
// semantics
|
||||
semantics -> muxUpdateStream;
|
||||
|
|
171
main.c
171
main.c
|
@ -8,6 +8,13 @@
|
|||
#include "critbit.h"
|
||||
#include "route.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#define LITERAL4(s) ({ \
|
||||
int ___v = 0; \
|
||||
memcpy(&___v, s, 4); \
|
||||
ntohl(___v); \
|
||||
})
|
||||
|
||||
static void atom_incref(void *atom_context, tt_arena_t *a, tt_atom_t atom) {
|
||||
/* printf("incref %u\n", atom); */
|
||||
}
|
||||
|
@ -130,43 +137,43 @@ int main(int argc, char *argv[]) {
|
|||
tt_node_ptr_t A = tt_grab(&a, MAKE_PATH(&a, a_set, {TT_BOS, 'A', TT_EOS}));
|
||||
printf("\nA node: %u/%u\n", tt_ptr_idx(A), tt_ptr_tag(A));
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("A", A, &a);
|
||||
tt_dump_arena_dot_styled("A", A, &a, 1);
|
||||
tt_node_ptr_t B = tt_grab(&a, MAKE_PATH(&a, b_set, {TT_BOS, 'B', TT_EOS}));
|
||||
printf("\nB node: %u/%u\n", tt_ptr_idx(B), tt_ptr_tag(B));
|
||||
tt_dump_arena_dot("B", B, &a);
|
||||
tt_node_ptr_t C = tt_trie_union(&a, A, B);
|
||||
tt_dump_arena_dot_styled("B", B, &a, 1);
|
||||
tt_node_ptr_t C = tt_trie_union_map(&a, A, B);
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("Cpredrop", C, &a);
|
||||
tt_dump_arena_dot_styled("Cpredrop", C, &a, 1);
|
||||
tt_drop(&a, A);
|
||||
tt_drop(&a, B);
|
||||
printf("\nC node: %u/%u\n", tt_ptr_idx(C), tt_ptr_tag(C));
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("Cpostdrop", C, &a);
|
||||
tt_dump_arena_dot_styled("Cpostdrop", C, &a, 1);
|
||||
putchar('\n');
|
||||
tt_dump_routingtable(&a, C, 0);
|
||||
tt_drop(&a, C);
|
||||
}
|
||||
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("after1", TT_NO_PTR, &a);
|
||||
tt_dump_arena_dot_styled("after1", TT_NO_PTR, &a, 1);
|
||||
|
||||
printf("\n============================================================ 2\n");
|
||||
{
|
||||
tt_node_ptr_t A = tt_grab(&a, MAKE_PATH(&a, a_set, {TT_BOS, 'A', TT_EOS}));
|
||||
printf("\nA node: %u/%u\n", tt_ptr_idx(A), tt_ptr_tag(A));
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("A", A, &a);
|
||||
tt_dump_arena_dot_styled("A", A, &a, 1);
|
||||
tt_node_ptr_t B = tt_grab(&a, MAKE_PATH(&a, b_set, {TT_BOS, TT_WILD, TT_EOS}));
|
||||
printf("\nB node: %u/%u\n", tt_ptr_idx(B), tt_ptr_tag(B));
|
||||
tt_dump_arena_dot("B", B, &a);
|
||||
tt_node_ptr_t C = tt_trie_union(&a, A, B);
|
||||
tt_dump_arena_dot_styled("B", B, &a, 1);
|
||||
tt_node_ptr_t C = tt_trie_union_map(&a, A, B);
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("Cpredrop", C, &a);
|
||||
tt_dump_arena_dot_styled("Cpredrop", C, &a, 1);
|
||||
tt_drop(&a, A);
|
||||
tt_drop(&a, B);
|
||||
printf("\nC node: %u/%u\n", tt_ptr_idx(C), tt_ptr_tag(C));
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("Cpostdrop", C, &a);
|
||||
tt_dump_arena_dot_styled("Cpostdrop", C, &a, 1);
|
||||
putchar('\n');
|
||||
tt_dump_routingtable(&a, C, 0);
|
||||
tt_drop(&a, C);
|
||||
|
@ -177,18 +184,18 @@ int main(int argc, char *argv[]) {
|
|||
tt_node_ptr_t A = tt_grab(&a, MAKE_PATH(&a, a_set, {TT_BOS, 'A', TT_EOS}));
|
||||
printf("\nA node: %u/%u\n", tt_ptr_idx(A), tt_ptr_tag(A));
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("A", A, &a);
|
||||
tt_dump_arena_dot_styled("A", A, &a, 1);
|
||||
tt_node_ptr_t B = tt_grab(&a, MAKE_PATH(&a, b_set, {TT_WILD}));
|
||||
printf("\nB node: %u/%u\n", tt_ptr_idx(B), tt_ptr_tag(B));
|
||||
tt_dump_arena_dot("B", B, &a);
|
||||
tt_node_ptr_t C = tt_trie_union(&a, A, B);
|
||||
tt_dump_arena_dot_styled("B", B, &a, 1);
|
||||
tt_node_ptr_t C = tt_trie_union_map(&a, A, B);
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("Cpredrop", C, &a);
|
||||
tt_dump_arena_dot_styled("Cpredrop", C, &a, 1);
|
||||
tt_drop(&a, A);
|
||||
tt_drop(&a, B);
|
||||
printf("\nC node: %u/%u\n", tt_ptr_idx(C), tt_ptr_tag(C));
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("Cpostdrop", C, &a);
|
||||
tt_dump_arena_dot_styled("Cpostdrop", C, &a, 1);
|
||||
putchar('\n');
|
||||
tt_dump_routingtable(&a, C, 0);
|
||||
tt_drop(&a, C);
|
||||
|
@ -199,18 +206,18 @@ int main(int argc, char *argv[]) {
|
|||
tt_node_ptr_t A = tt_grab(&a, MAKE_PATH(&a, b_set /* !!! */, {TT_BOS, 'A', TT_EOS}));
|
||||
printf("\nA node: %u/%u\n", tt_ptr_idx(A), tt_ptr_tag(A));
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("A", A, &a);
|
||||
tt_dump_arena_dot_styled("A", A, &a, 1);
|
||||
tt_node_ptr_t B = tt_grab(&a, MAKE_PATH(&a, b_set, {TT_WILD}));
|
||||
printf("\nB node: %u/%u\n", tt_ptr_idx(B), tt_ptr_tag(B));
|
||||
tt_dump_arena_dot("B", B, &a);
|
||||
tt_node_ptr_t C = tt_trie_union(&a, A, B);
|
||||
tt_dump_arena_dot_styled("B", B, &a, 1);
|
||||
tt_node_ptr_t C = tt_trie_union_map(&a, A, B);
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("Cpredrop", C, &a);
|
||||
tt_dump_arena_dot_styled("Cpredrop", C, &a, 1);
|
||||
tt_drop(&a, A);
|
||||
tt_drop(&a, B);
|
||||
printf("\nC node: %u/%u\n", tt_ptr_idx(C), tt_ptr_tag(C));
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("Cpostdrop", C, &a);
|
||||
tt_dump_arena_dot_styled("Cpostdrop", C, &a, 1);
|
||||
putchar('\n');
|
||||
tt_dump_routingtable(&a, C, 0);
|
||||
tt_drop(&a, C);
|
||||
|
@ -221,18 +228,18 @@ int main(int argc, char *argv[]) {
|
|||
tt_node_ptr_t A = tt_grab(&a, MAKE_PATH(&a, a_set, {TT_BOS, 'A', 'B', TT_EOS}));
|
||||
printf("\nA node: %u/%u\n", tt_ptr_idx(A), tt_ptr_tag(A));
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("A", A, &a);
|
||||
tt_dump_arena_dot_styled("A", A, &a, 1);
|
||||
tt_node_ptr_t B = tt_grab(&a, MAKE_PATH(&a, b_set, {TT_BOS, TT_WILD, TT_EOS}));
|
||||
printf("\nB node: %u/%u\n", tt_ptr_idx(B), tt_ptr_tag(B));
|
||||
tt_dump_arena_dot("B", B, &a);
|
||||
tt_node_ptr_t C = tt_trie_union(&a, A, B);
|
||||
tt_dump_arena_dot_styled("B", B, &a, 1);
|
||||
tt_node_ptr_t C = tt_trie_union_map(&a, A, B);
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("Cpredrop", C, &a);
|
||||
tt_dump_arena_dot_styled("Cpredrop", C, &a, 1);
|
||||
tt_drop(&a, A);
|
||||
tt_drop(&a, B);
|
||||
printf("\nC node: %u/%u\n", tt_ptr_idx(C), tt_ptr_tag(C));
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("Cpostdrop", C, &a);
|
||||
tt_dump_arena_dot_styled("Cpostdrop", C, &a, 1);
|
||||
putchar('\n');
|
||||
tt_dump_routingtable(&a, C, 0);
|
||||
tt_drop(&a, C);
|
||||
|
@ -243,18 +250,18 @@ int main(int argc, char *argv[]) {
|
|||
tt_node_ptr_t A = tt_grab(&a, MAKE_PATH(&a, a_set, {TT_BOS, 'A', 'B', TT_EOS}));
|
||||
printf("\nA node: %u/%u\n", tt_ptr_idx(A), tt_ptr_tag(A));
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("A", A, &a);
|
||||
tt_dump_arena_dot_styled("A", A, &a, 1);
|
||||
tt_node_ptr_t B = tt_grab(&a, MAKE_PATH(&a, b_set, {TT_BOS, TT_WILD, TT_WILD, TT_EOS}));
|
||||
printf("\nB node: %u/%u\n", tt_ptr_idx(B), tt_ptr_tag(B));
|
||||
tt_dump_arena_dot("B", B, &a);
|
||||
tt_node_ptr_t C = tt_trie_union(&a, A, B);
|
||||
tt_dump_arena_dot_styled("B", B, &a, 1);
|
||||
tt_node_ptr_t C = tt_trie_union_map(&a, A, B);
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("Cpredrop", C, &a);
|
||||
tt_dump_arena_dot_styled("Cpredrop", C, &a, 1);
|
||||
tt_drop(&a, A);
|
||||
tt_drop(&a, B);
|
||||
printf("\nC node: %u/%u\n", tt_ptr_idx(C), tt_ptr_tag(C));
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("Cpostdrop", C, &a);
|
||||
tt_dump_arena_dot_styled("Cpostdrop", C, &a, 1);
|
||||
putchar('\n');
|
||||
tt_dump_routingtable(&a, C, 0);
|
||||
tt_drop(&a, C);
|
||||
|
@ -265,39 +272,121 @@ int main(int argc, char *argv[]) {
|
|||
tt_node_ptr_t A = tt_grab(&a, MAKE_PATH(&a, a_set, {TT_BOS, 'A', TT_WILD, TT_EOS}));
|
||||
printf("\nA node: %u/%u\n", tt_ptr_idx(A), tt_ptr_tag(A));
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("A", A, &a);
|
||||
tt_dump_arena_dot_styled("A", A, &a, 1);
|
||||
tt_node_ptr_t B = tt_grab(&a, MAKE_PATH(&a, b_set, {TT_BOS, TT_WILD, 'B', TT_EOS}));
|
||||
printf("\nB node: %u/%u\n", tt_ptr_idx(B), tt_ptr_tag(B));
|
||||
tt_dump_arena_dot("B", B, &a);
|
||||
tt_node_ptr_t C = tt_trie_union(&a, A, B);
|
||||
tt_dump_arena_dot_styled("B", B, &a, 1);
|
||||
tt_node_ptr_t C = tt_trie_union_map(&a, A, B);
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("Cpredrop", C, &a);
|
||||
tt_dump_arena_dot_styled("Cpredrop", C, &a, 1);
|
||||
tt_drop(&a, A);
|
||||
tt_drop(&a, B);
|
||||
printf("\nC node: %u/%u\n", tt_ptr_idx(C), tt_ptr_tag(C));
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("Cpostdrop", C, &a);
|
||||
tt_dump_arena_dot_styled("Cpostdrop", C, &a, 1);
|
||||
putchar('\n');
|
||||
tt_dump_routingtable(&a, C, 0);
|
||||
|
||||
tt_node_ptr_t D = tt_trie_union(&a, C, C);
|
||||
tt_node_ptr_t D = tt_trie_union_map(&a, C, C);
|
||||
tt_drop(&a, C);
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("D", D, &a);
|
||||
tt_dump_arena_dot_styled("D", D, &a, 1);
|
||||
tt_dump_routingtable(&a, D, 0);
|
||||
|
||||
tt_node_ptr_t E = tt_grab(&a, MAKE_PATH(&a, b_set, {TT_WILD}));
|
||||
tt_node_ptr_t F = tt_trie_union(&a, D, E);
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot_styled("E", E, &a, 1);
|
||||
tt_node_ptr_t F = tt_trie_union_map(&a, D, E);
|
||||
tt_drop(&a, D);
|
||||
tt_drop(&a, E);
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("F", F, &a);
|
||||
tt_dump_arena_dot_styled("F", F, &a, 1);
|
||||
tt_dump_routingtable(&a, F, 0);
|
||||
|
||||
tt_node_ptr_t G = tt_grab(&a, tt_trie_relabel_const(&a, F, a_set));
|
||||
tt_drop(&a, F);
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot_styled("G", G, &a, 1);
|
||||
tt_dump_routingtable(&a, G, 0);
|
||||
tt_drop(&a, G);
|
||||
}
|
||||
|
||||
printf("\n============================================================ 8\n");
|
||||
{
|
||||
tt_node_ptr_t A = tt_grab(&a, MAKE_PATH(&a, TT_EMPTY_DICT, {TT_BOS, 'A', TT_WILD, TT_EOS}));
|
||||
printf("\nA node: %u/%u\n", tt_ptr_idx(A), tt_ptr_tag(A));
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot_styled("A", A, &a, 1);
|
||||
tt_dump_routingtable(&a, A, 0);
|
||||
tt_node_ptr_t B = tt_grab(&a, MAKE_PATH(&a, TT_EMPTY_DICT, {TT_BOS, TT_WILD, 'B', TT_EOS}));
|
||||
printf("\nB node: %u/%u\n", tt_ptr_idx(B), tt_ptr_tag(B));
|
||||
tt_dump_arena_dot_styled("B", B, &a, 1);
|
||||
tt_dump_routingtable(&a, B, 0);
|
||||
tt_node_ptr_t C = tt_trie_subtract_set(&a, A, B);
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot_styled("Cpredrop", C, &a, 1);
|
||||
tt_drop(&a, A);
|
||||
tt_drop(&a, B);
|
||||
printf("\nC node: %u/%u\n", tt_ptr_idx(C), tt_ptr_tag(C));
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot_styled("Cpostdrop", C, &a, 1);
|
||||
putchar('\n');
|
||||
tt_dump_routingtable(&a, C, 0);
|
||||
tt_drop(&a, C);
|
||||
}
|
||||
|
||||
printf("\n============================================================ 9\n");
|
||||
{
|
||||
tt_node_ptr_t A = tt_grab(&a, MAKE_PATH(&a, TT_EMPTY_DICT, {TT_WILD}));
|
||||
printf("\nA node: %u/%u\n", tt_ptr_idx(A), tt_ptr_tag(A));
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot_styled("A", A, &a, 1);
|
||||
tt_dump_routingtable(&a, A, 0);
|
||||
tt_node_ptr_t B = tt_grab(&a, MAKE_PATH(&a, TT_EMPTY_DICT, {TT_BOS, 'A', 'B', TT_EOS}));
|
||||
printf("\nB node: %u/%u\n", tt_ptr_idx(B), tt_ptr_tag(B));
|
||||
tt_dump_arena_dot_styled("B", B, &a, 1);
|
||||
tt_dump_routingtable(&a, B, 0);
|
||||
tt_node_ptr_t C = tt_trie_subtract_set(&a, A, B);
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot_styled("Cpredrop", C, &a, 1);
|
||||
tt_drop(&a, A);
|
||||
tt_drop(&a, B);
|
||||
printf("\nC node: %u/%u\n", tt_ptr_idx(C), tt_ptr_tag(C));
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot_styled("Cpostdrop", C, &a, 1);
|
||||
tt_replace(&a, &C, tt_trie_relabel_const(&a, C, a_set));
|
||||
printf("\nC node post relabel: %u/%u\n", tt_ptr_idx(C), tt_ptr_tag(C));
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot_styled("Cpostrelabel", C, &a, 1);
|
||||
putchar('\n');
|
||||
tt_dump_routingtable(&a, C, 0);
|
||||
tt_drop(&a, C);
|
||||
}
|
||||
|
||||
printf("\n============================================================ A\n");
|
||||
{
|
||||
tt_node_ptr_t d = TT_EMPTY_DICT;
|
||||
tt_replace(&a, &d, tt_dict_set(&a, d, LITERAL4("appl"), TT_EMPTY));
|
||||
tt_replace(&a, &d, tt_dict_set(&a, d, LITERAL4("caar"), TT_EMPTY));
|
||||
tt_replace(&a, &d, tt_dict_set(&a, d, LITERAL4("cadr"), TT_EMPTY));
|
||||
tt_replace(&a, &d, tt_dict_set(&a, d, LITERAL4("cdar"), TT_EMPTY));
|
||||
tt_replace(&a, &d, tt_dict_set(&a, d, LITERAL4("cddr"), TT_EMPTY));
|
||||
tt_replace(&a, &d, tt_dict_set(&a, d, LITERAL4("cons"), TT_EMPTY));
|
||||
tt_replace(&a, &d, tt_dict_set(&a, d, LITERAL4("goog"), TT_EMPTY));
|
||||
tt_replace(&a, &d, tt_dict_set(&a, d, LITERAL4("lisp"), TT_EMPTY));
|
||||
tt_replace(&a, &d, tt_dict_set(&a, d, LITERAL4("snoc"), TT_EMPTY));
|
||||
tt_replace(&a, &d, tt_dict_set(&a, d, LITERAL4("spcx"), TT_EMPTY));
|
||||
tt_replace(&a, &d, tt_dict_set(&a, d, LITERAL4("twtr"), TT_EMPTY));
|
||||
tt_replace(&a, &d, tt_dict_set(&a, d, LITERAL4("unit"), TT_EMPTY));
|
||||
tt_replace(&a, &d, tt_dict_set(&a, d, LITERAL4("void"), TT_EMPTY));
|
||||
printf("\nd node: %u/%u\n", tt_ptr_idx(d), tt_ptr_tag(d));
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot_styled("d", d, &a, 1);
|
||||
tt_drop(&a, d);
|
||||
}
|
||||
|
||||
tt_arena_flush(&a);
|
||||
tt_dump_arena_dot("afterAll", TT_NO_PTR, &a); /* expect a_set and b_set here */
|
||||
tt_dump_arena_dot_styled("afterAll", TT_NO_PTR, &a, 1); /* expect a_set and b_set here */
|
||||
|
||||
tt_arena_done(&a);
|
||||
return EXIT_SUCCESS;
|
||||
|
|
82
route.c
82
route.c
|
@ -193,7 +193,7 @@ tt_node_ptr_t tt_trie_combine(tt_arena_t *a,
|
|||
tt_node_ptr_t w2 = TT_BRANCH_WILDCARD(a,r2);
|
||||
tt_node_ptr_t dict1 = TT_BRANCH_OTHERS(a,r1);
|
||||
tt_node_ptr_t dict2 = TT_BRANCH_OTHERS(a,r2);
|
||||
tt_node_ptr_t result_wild = TT_NO_PTR; /* grab'd */
|
||||
tt_node_ptr_t result_wild = TT_EMPTY; /* grab'd */
|
||||
tt_node_ptr_t result_others = TT_EMPTY_DICT; /* grab'd */
|
||||
tt_node_ptr_t result = TT_NO_PTR; /* grab'd */
|
||||
int ok = 1;
|
||||
|
@ -240,13 +240,17 @@ tt_node_ptr_t tt_trie_combine(tt_arena_t *a,
|
|||
(TT_EMPTY_P(w2) &&
|
||||
(tt_dict_size(a, dict1) >= tt_dict_size(a, dict2)))) {
|
||||
/* Either a wildcard on the left, or no wildcard at all but the left is larger */
|
||||
result_wild = tt_grab(a, w1);
|
||||
result_others = left_base_keep ? tt_grab(a, dict1) : TT_EMPTY_DICT;
|
||||
if (left_base_keep) {
|
||||
result_wild = tt_grab(a, w1);
|
||||
result_others = tt_grab(a, dict1);
|
||||
}
|
||||
ok = ok && tt_dict_foreach(a, dict2, NULL, examine_key);
|
||||
} else {
|
||||
/* Either a wildcard on the right, or no wildcard at all but the right is larger */
|
||||
result_wild = tt_grab(a, w2);
|
||||
result_others = right_base_keep ? tt_grab(a, dict2) : TT_EMPTY_DICT;
|
||||
if (right_base_keep) {
|
||||
result_wild = tt_grab(a, w2);
|
||||
result_others = tt_grab(a, dict2);
|
||||
}
|
||||
ok = ok && tt_dict_foreach(a, dict1, NULL, examine_key);
|
||||
}
|
||||
|
||||
|
@ -298,8 +302,8 @@ tt_node_ptr_t tt_trie_combine(tt_arena_t *a,
|
|||
return g(r1, r2);
|
||||
}
|
||||
|
||||
tt_node_ptr_t tt_trie_union(tt_arena_t *a, tt_node_ptr_t r1, tt_node_ptr_t r2) {
|
||||
tt_node_ptr_t f_union(void *f_context, tt_node_ptr_t r1, tt_node_ptr_t r2) {
|
||||
tt_node_ptr_t tt_trie_union_map(tt_arena_t *a, tt_node_ptr_t r1, tt_node_ptr_t r2) {
|
||||
tt_node_ptr_t f_union_map(void *f_context, tt_node_ptr_t r1, tt_node_ptr_t r2) {
|
||||
tt_tag_t t1 = tt_ptr_tag(r1);
|
||||
tt_tag_t t2 = tt_ptr_tag(r2);
|
||||
if (t1 != TT_TAG_OK) {
|
||||
|
@ -314,7 +318,69 @@ tt_node_ptr_t tt_trie_union(tt_arena_t *a, tt_node_ptr_t r1, tt_node_ptr_t r2) {
|
|||
return tt_grab(a, result);
|
||||
}
|
||||
}
|
||||
return tt_trie_combine(a, r1, r2, 1, 1, 1, 1, NULL, f_union);
|
||||
return tt_trie_combine(a, r1, r2, 1, 1, 1, 1, NULL, f_union_map);
|
||||
}
|
||||
|
||||
tt_node_ptr_t tt_trie_subtract_set(tt_arena_t *a, tt_node_ptr_t r1, tt_node_ptr_t r2) {
|
||||
tt_node_ptr_t f_subtract_set(void *f_context, tt_node_ptr_t r1, tt_node_ptr_t r2) {
|
||||
return TT_EMPTY;
|
||||
}
|
||||
return tt_trie_combine(a, r1, r2, 0, 1, 1, 0, NULL, f_subtract_set);
|
||||
}
|
||||
|
||||
tt_node_ptr_t tt_trie_relabel(tt_arena_t *a,
|
||||
tt_node_ptr_t r,
|
||||
void *f_context,
|
||||
tt_node_ptr_t (*f)(void *f_context,
|
||||
tt_node_ptr_t oldlabel))
|
||||
{
|
||||
tt_node_ptr_t walk(tt_node_ptr_t r) {
|
||||
if (TT_EMPTY_P(r)) {
|
||||
return r;
|
||||
}
|
||||
|
||||
switch (tt_ptr_tag(r)) {
|
||||
case TT_TAG_OK:
|
||||
return tt_cons_ok(a, RET_IF_NO_PTR(f(f_context, TT_OK_DICT(a, r))));
|
||||
|
||||
case TT_TAG_TAIL:
|
||||
return tt_cons_tail(a, RET_IF_NO_PTR(walk(TT_TAIL_TRIE(a, r))));
|
||||
|
||||
case TT_TAG_BRANCH: {
|
||||
tt_node_ptr_t wild = tt_grab(a, RET_IF_NO_PTR(walk(TT_BRANCH_WILDCARD(a, r))));
|
||||
tt_node_ptr_t others = TT_EMPTY_DICT; /* grab'd */
|
||||
tt_node_ptr_t result = TT_NO_PTR;
|
||||
int visit_edge(void *context, tt_atom_t key, tt_node_ptr_t trie) {
|
||||
tt_node_ptr_t new_trie = tt_grab(a, walk(trie));
|
||||
tt_node_ptr_t new_others;
|
||||
if (TT_NO_PTR_P(new_trie)) return 0;
|
||||
new_others = tt_grab(a, rupdate_dict(a, wild, others, key, new_trie));
|
||||
tt_drop(a, new_trie);
|
||||
if (TT_NO_PTR_P(new_others)) return 0;
|
||||
tt_drop(a, others);
|
||||
others = new_others;
|
||||
return 1;
|
||||
}
|
||||
if (tt_dict_foreach(a, TT_BRANCH_OTHERS(a, r), NULL, visit_edge)) {
|
||||
result = rbranch(a, wild, others);
|
||||
}
|
||||
tt_drop(a, wild);
|
||||
tt_drop(a, others);
|
||||
return result;
|
||||
}
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
return walk(r);
|
||||
}
|
||||
|
||||
tt_node_ptr_t tt_trie_relabel_const(tt_arena_t *a, tt_node_ptr_t r, tt_node_ptr_t newlabel) {
|
||||
tt_node_ptr_t relabel_to_const(void *context, tt_node_ptr_t oldlabel) {
|
||||
return newlabel;
|
||||
}
|
||||
return tt_trie_relabel(a, r, NULL, relabel_to_const);
|
||||
}
|
||||
|
||||
tt_node_ptr_t tt_begin_path(tt_arena_t *a, tt_node_ptr_t ok_dict) {
|
||||
|
|
11
route.h
11
route.h
|
@ -26,7 +26,16 @@ extern tt_node_ptr_t tt_trie_combine(tt_arena_t *a,
|
|||
tt_node_ptr_t r2));
|
||||
|
||||
/* N.B. Returns a tt_grab'd result. */
|
||||
extern tt_node_ptr_t tt_trie_union(tt_arena_t *a, tt_node_ptr_t r1, tt_node_ptr_t r2);
|
||||
extern tt_node_ptr_t tt_trie_union_map(tt_arena_t *a, tt_node_ptr_t r1, tt_node_ptr_t r2);
|
||||
extern tt_node_ptr_t tt_trie_subtract_set(tt_arena_t *a, tt_node_ptr_t r1, tt_node_ptr_t r2);
|
||||
|
||||
/* ungrab'd */
|
||||
extern tt_node_ptr_t tt_trie_relabel(tt_arena_t *a,
|
||||
tt_node_ptr_t r,
|
||||
void *f_context,
|
||||
tt_node_ptr_t (*f)(void *f_context,
|
||||
tt_node_ptr_t oldlabel));
|
||||
extern tt_node_ptr_t tt_trie_relabel_const(tt_arena_t *a, tt_node_ptr_t r, tt_node_ptr_t newlabel);
|
||||
|
||||
/* These return ungrab'd */
|
||||
extern tt_node_ptr_t tt_begin_path(tt_arena_t *a, tt_node_ptr_t ok_dict);
|
||||
|
|
59
treetrie.c
59
treetrie.c
|
@ -8,6 +8,10 @@
|
|||
#include "treetrie.h"
|
||||
#include "fasthash.h"
|
||||
|
||||
/* These two only included for tt_dump_arena_dot_styled. */
|
||||
#include "route.h"
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/* Customized special-purpose fasthash variation */
|
||||
#define mix(h) ({ \
|
||||
(h) ^= (h) >> 23; \
|
||||
|
@ -354,7 +358,11 @@ static void dump_dot_edge(tt_arena_t *a, tt_node_ptr_t p, int lr, char const *ed
|
|||
}
|
||||
}
|
||||
|
||||
void tt_dump_arena_dot(char const *rootlabel, tt_node_ptr_t rootptr, tt_arena_t *a) {
|
||||
void tt_dump_arena_dot_styled(char const *rootlabel,
|
||||
tt_node_ptr_t rootptr,
|
||||
tt_arena_t *a,
|
||||
int style)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("digraph Arena {\n");
|
||||
|
@ -392,7 +400,37 @@ void tt_dump_arena_dot(char const *rootlabel, tt_node_ptr_t rootptr, tt_arena_t
|
|||
printf("label=\"branch");
|
||||
break;
|
||||
case TT_TAG_LEAF:
|
||||
printf("shape=underline,label=\"leaf a%d", (int) a->nodes[n].b);
|
||||
switch (style) {
|
||||
case 1: {
|
||||
char buf[5];
|
||||
int v = (int) a->nodes[n].b;
|
||||
if (v < -9 || v >= 32) {
|
||||
int j;
|
||||
v = htonl(v);
|
||||
memcpy(buf, &v, 4);
|
||||
for (j = 0; j < 4; j++) {
|
||||
if (buf[j] < 32) { buf[j] = ' '; }
|
||||
}
|
||||
buf[4] = '\0';
|
||||
} else {
|
||||
switch (v) {
|
||||
case TT_WILD: buf[0] = '*'; buf[1] = '\0'; break;
|
||||
case TT_BOS: buf[0] = buf[1] = '<'; buf[2] = '\0'; break;
|
||||
case TT_EOS: buf[0] = buf[1] = '>'; buf[2] = '\0'; break;
|
||||
case TT_BOC: buf[0] = buf[1] = '{'; buf[2] = '\0'; break;
|
||||
case TT_EOC: buf[0] = buf[1] = '}'; buf[2] = '\0'; break;
|
||||
default:
|
||||
snprintf(buf, sizeof(buf), "%d", v);
|
||||
buf[4] = '\0';
|
||||
}
|
||||
}
|
||||
printf("shape=underline,label=\"leaf '%s'", buf);
|
||||
break;
|
||||
}
|
||||
case 0:
|
||||
default:
|
||||
printf("shape=underline,label=\"leaf a%d", (int) a->nodes[n].b);
|
||||
}
|
||||
break;
|
||||
case TT_TAG_NODE:
|
||||
printf("label=\"node @%d", a->headers[n].inuse.index);
|
||||
|
@ -436,6 +474,10 @@ void tt_dump_arena_dot(char const *rootlabel, tt_node_ptr_t rootptr, tt_arena_t
|
|||
printf("}\n");
|
||||
}
|
||||
|
||||
void tt_dump_arena_dot(char const *rootlabel, tt_node_ptr_t rootptr, tt_arena_t *a) {
|
||||
tt_dump_arena_dot_styled(rootlabel, rootptr, a, 0);
|
||||
}
|
||||
|
||||
void tt_arena_flush1(tt_arena_t *a, tt_free_chain_t *c) {
|
||||
tt_node_idx_t i = a->free_chain.head;
|
||||
chain_splice(a, c, &a->free_chain);
|
||||
|
@ -538,11 +580,14 @@ inline tt_node_ptr_t tt_grab(tt_arena_t *a, tt_node_ptr_t p) {
|
|||
inline void tt_drop(tt_arena_t *a, tt_node_ptr_t p) {
|
||||
tt_node_idx_t i = tt_ptr_idx(p);
|
||||
tt_tag_t t = tt_ptr_tag(p);
|
||||
if (t != TT_TAG_INVALID && t != TT_TAG_SPECIAL
|
||||
&& a->headers[i].inuse.refcount < TT_REFCOUNT_LIMIT) {
|
||||
/* printf("++++++++++++++++++++++++++++++ dropping %d\n", i); */
|
||||
if (--(a->headers[i].inuse.refcount) == 0) {
|
||||
recycle_node(a, p);
|
||||
if (t != TT_TAG_INVALID && t != TT_TAG_SPECIAL) {
|
||||
uint32_t oldcount = a->headers[i].inuse.refcount;
|
||||
if (oldcount < TT_REFCOUNT_LIMIT) {
|
||||
/* printf("++++++++++++++++++++++++++++++ dropping %d\n", i); */
|
||||
assert(oldcount != 0);
|
||||
if (--(a->headers[i].inuse.refcount) == 0) {
|
||||
recycle_node(a, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
10
treetrie.h
10
treetrie.h
|
@ -109,6 +109,10 @@ extern void tt_arena_done(tt_arena_t *a);
|
|||
|
||||
extern void tt_dump_arena_summary(tt_arena_t *a);
|
||||
extern void tt_dump_arena(tt_arena_t *a, int show_free_chain);
|
||||
extern void tt_dump_arena_dot_styled(char const *rootlabel,
|
||||
tt_node_ptr_t rootptr,
|
||||
tt_arena_t *a,
|
||||
int style);
|
||||
extern void tt_dump_arena_dot(char const *rootlabel, tt_node_ptr_t rootptr, tt_arena_t *a);
|
||||
|
||||
extern void tt_arena_flush(tt_arena_t *a);
|
||||
|
@ -178,6 +182,12 @@ static inline tt_node_ptr_t tt_right(tt_arena_t *a, tt_node_ptr_t p) {
|
|||
#define TT_DICT_ROOT(a,p) tt_left(a,p)
|
||||
#define TT_DICT_SIZE(a,p) ((uint32_t) tt_right(a,p))
|
||||
|
||||
static inline void tt_replace(tt_arena_t *a, tt_node_ptr_t *target, tt_node_ptr_t newval) {
|
||||
tt_grab(a, newval);
|
||||
tt_drop(a, *target);
|
||||
*target = newval;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue