Subtraction; relabelling; pretty output

This commit is contained in:
Tony Garnock-Jones 2015-07-13 19:57:06 -04:00
parent 85a139f5dd
commit 0e88711a50
6 changed files with 283 additions and 60 deletions

10
TODO.md
View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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);

View File

@ -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);
}
}
}
}

View File

@ -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