From e20f3730d108c75d5964a9472481d847e9f665b7 Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Sun, 12 Jul 2015 19:36:16 -0400 Subject: [PATCH] dot output --- main.c | 11 ++++--- treetrie.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ treetrie.h | 1 + 3 files changed, 97 insertions(+), 4 deletions(-) diff --git a/main.c b/main.c index 3dd5f01..df5d6b5 100644 --- a/main.c +++ b/main.c @@ -118,7 +118,8 @@ int main(int argc, char *argv[]) { tt_prepend_path(&a, TT_EOS, tt_begin_path(&a, a_set))))); printf("\nA node: %u/%u\n", tt_ptr_idx(A), tt_ptr_tag(A)); - tt_dump_arena(&a, 0); + tt_arena_flush(&a); + tt_dump_arena_dot(&a); tt_node_ptr_t B = tt_grab(&a, tt_prepend_path(&a, TT_BOS, @@ -126,12 +127,14 @@ int main(int argc, char *argv[]) { tt_prepend_path(&a, TT_EOS, tt_begin_path(&a, b_set))))); printf("\nB node: %u/%u\n", tt_ptr_idx(B), tt_ptr_tag(B)); - tt_dump_arena(&a, 0); + tt_arena_flush(&a); + tt_dump_arena_dot(&a); tt_node_ptr_t C = tt_trie_union(&a, A, B); tt_drop(&a, A); tt_drop(&a, B); printf("\nC node: %u/%u\n", tt_ptr_idx(C), tt_ptr_tag(C)); - tt_dump_arena(&a, 0); + tt_arena_flush(&a); + tt_dump_arena_dot(&a); putchar('\n'); tt_dump_routingtable(&a, C, 0); tt_drop(&a, C); @@ -139,7 +142,7 @@ int main(int argc, char *argv[]) { putchar('\n'); tt_arena_flush(&a); - tt_dump_arena(&a, 0); + tt_dump_arena_dot(&a); /* tt_dump_arena_summary(&a); */ tt_arena_done(&a); diff --git a/treetrie.c b/treetrie.c index a255903..02d0c16 100644 --- a/treetrie.c +++ b/treetrie.c @@ -341,6 +341,95 @@ void tt_dump_arena(tt_arena_t *a, int show_free_chain) { } } +static void dump_dot_edge(tt_arena_t *a, tt_node_ptr_t p, int lr, char const *edgename) { + tt_node_idx_t n = tt_ptr_idx(p); + tt_tag_t target_t = tt_ptr_tag(lr ? a->nodes[n].b : a->nodes[n].a); + if (target_t != TT_TAG_INVALID && target_t != TT_TAG_SPECIAL) { + printf(" i%u_%u -> i%u_%u [label=\"%s\"];\n", + n, + tt_ptr_tag(p), + tt_ptr_idx(lr ? a->nodes[n].b : a->nodes[n].a), + target_t, + edgename); + } +} + +void tt_dump_arena_dot(tt_arena_t *a) { + int i; + + printf("digraph Arena {\n"); + for (i = 0; i < a->table_length; i++) { + tt_node_ptr_t p = a->table[i].ptr; + tt_node_idx_t n = tt_ptr_idx(p); + + if (TT_NO_PTR_P(p)) { + continue; + } + + if (n >= a->table_length) { + printf(" // %12u -> %12u ?!?!?!\n", i, n); + } else { + tt_hash_t h = a->table[i].hash; + int distance = i - (h % a->table_length); + if (distance < 0) distance += a->table_length; + printf(" i%u_%u [", + n, + tt_ptr_tag(p)); + switch (tt_ptr_tag(p)) { + case TT_TAG_TAIL: + printf("label=\"tail"); + break; + case TT_TAG_OK: + printf("shape=underline,label=\"ok"); + break; + case TT_TAG_BRANCH: + printf("label=\"branch"); + break; + case TT_TAG_LEAF: + printf("label=\"leaf a%d", (int) a->nodes[n].b); + break; + case TT_TAG_NODE: + printf("label=\"node @%d", a->headers[n].inuse.index); + break; + case TT_TAG_DICT: + printf("label=\"dict s%u", a->nodes[n].b); + break; + default: + printf("???? %08x\n", p); + assert(0); + } + /* printf(" #%u d%d r%d\"];\n", i, distance, a->headers[n].inuse.refcount); */ + printf(" r%d\"];\n", a->headers[n].inuse.refcount); + switch (tt_ptr_tag(p)) { + case TT_TAG_TAIL: + dump_dot_edge(a, p, 0, "trie"); + break; + case TT_TAG_OK: + dump_dot_edge(a, p, 0, "dict"); + break; + case TT_TAG_BRANCH: + dump_dot_edge(a, p, 0, "wild"); + dump_dot_edge(a, p, 1, "others"); + break; + case TT_TAG_LEAF: + dump_dot_edge(a, p, 0, "trie"); + break; + case TT_TAG_NODE: + dump_dot_edge(a, p, 0, "zero"); + dump_dot_edge(a, p, 1, "one"); + break; + case TT_TAG_DICT: + dump_dot_edge(a, p, 0, "root"); + break; + default: + printf("???? %08x\n", p); + assert(0); + } + } + } + printf("}\n"); +} + 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); diff --git a/treetrie.h b/treetrie.h index fd7afdd..571c2a7 100644 --- a/treetrie.h +++ b/treetrie.h @@ -110,6 +110,7 @@ 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(tt_arena_t *a); extern void tt_arena_flush(tt_arena_t *a);