This commit is contained in:
Tony Garnock-Jones 2015-07-12 21:13:56 -04:00
parent e20f3730d1
commit 7bfbb3f8c9
6 changed files with 133 additions and 37 deletions

View File

@ -1,7 +1,7 @@
all: t
t: *.c
$(CC) -Wall -Os -o $@ -g *.c
$(CC) -Wall -O0 -o $@ -g *.c
clean:
rm -f t

View File

@ -54,7 +54,8 @@ static int set_walk(tt_arena_t *a,
tt_atom_t key,
tt_node_ptr_t trie,
tt_node_ptr_t n,
tt_node_ptr_t *result)
tt_node_ptr_t *result,
int *added_count)
{
switch (tt_ptr_tag(n)) {
case TT_TAG_LEAF: {
@ -71,6 +72,7 @@ static int set_walk(tt_arena_t *a,
} else {
int leading_zeros = __builtin_clz(differences);
int first_differing_bit = (8 * sizeof(differences)) - leading_zeros - 1;
*added_count = 1;
return first_differing_bit;
}
}
@ -78,7 +80,7 @@ static int set_walk(tt_arena_t *a,
int index = TT_NODE_INDEX(a, n);
if (bit_ref(key, index)) {
tt_node_ptr_t one = TT_NODE_ONE(a, n);
int first_differing_bit = set_walk(a, key, trie, one, result);
int first_differing_bit = set_walk(a, key, trie, one, result, added_count);
if (first_differing_bit == -1) {
if (*result == one) {
*result = n;
@ -99,7 +101,7 @@ static int set_walk(tt_arena_t *a,
}
} else {
tt_node_ptr_t zero = TT_NODE_ZERO(a, n);
int first_differing_bit = set_walk(a, key, trie, zero, result);
int first_differing_bit = set_walk(a, key, trie, zero, result, added_count);
if (first_differing_bit == -1) {
if (*result == zero) {
*result = n;
@ -145,8 +147,9 @@ tt_node_ptr_t tt_dict_set(tt_arena_t *a,
{
tt_node_ptr_t old_root = TT_DICT_ROOT(a,t);
int added_count = 0;
tt_node_ptr_t result = TT_NO_PTR;
int first_differing_bit = set_walk(a, key, trie, old_root, &result);
int first_differing_bit = set_walk(a, key, trie, old_root, &result, &added_count);
if (first_differing_bit != -1) {
result = splice_key(a, key, trie, first_differing_bit, old_root);
}
@ -155,7 +158,7 @@ tt_node_ptr_t tt_dict_set(tt_arena_t *a,
} else if (result == old_root) {
return t;
} else {
return tt_cons_dict(a, result, TT_DICT_SIZE(a,t) + 1);
return tt_cons_dict(a, result, TT_DICT_SIZE(a,t) + added_count);
}
}
}
@ -210,11 +213,14 @@ tt_node_ptr_t tt_dict_remove(tt_arena_t *a,
assert(tt_ptr_tag(t) == TT_TAG_DICT);
{
tt_node_ptr_t old_root = TT_DICT_ROOT(a,t);
int removed_count = 0;
tt_node_ptr_t n =
RET_IF_NO_PTR(tt_dict_remove1(a, TT_DICT_ROOT(a,t), key, &removed_count));
RET_IF_NO_PTR(tt_dict_remove1(a, old_root, key, &removed_count));
if (TT_EMPTY_DICT_P(n)) {
return TT_EMPTY_DICT;
} else if (n == old_root) {
return t;
} else {
return tt_cons_dict(a, n, TT_DICT_SIZE(a,t) - removed_count);
}

108
main.c
View File

@ -107,9 +107,10 @@ int main(int argc, char *argv[]) {
setbuf(stdout, NULL);
tt_arena_init(&a, NULL, atom_incref, atom_decref);
a_set = tt_dict_singleton(&a, 'A', TT_EMPTY);
b_set = tt_dict_singleton(&a, 'B', TT_EMPTY);
a_set = tt_grab(&a, tt_dict_singleton(&a, 'A', TT_EMPTY));
b_set = tt_grab(&a, tt_dict_singleton(&a, 'B', TT_EMPTY));
printf("\n============================================================ 1\n");
{
tt_node_ptr_t A =
tt_grab(&a,
@ -119,7 +120,7 @@ int main(int argc, char *argv[]) {
tt_begin_path(&a, a_set)))));
printf("\nA node: %u/%u\n", tt_ptr_idx(A), tt_ptr_tag(A));
tt_arena_flush(&a);
tt_dump_arena_dot(&a);
tt_dump_arena_dot("A", A, &a);
tt_node_ptr_t B =
tt_grab(&a,
tt_prepend_path(&a, TT_BOS,
@ -127,23 +128,112 @@ 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_arena_flush(&a);
tt_dump_arena_dot(&a);
tt_dump_arena_dot("B", B, &a);
tt_node_ptr_t C = tt_trie_union(&a, A, B);
tt_arena_flush(&a);
tt_dump_arena_dot("Cpredrop", C, &a);
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(&a);
tt_dump_arena_dot("Cpostdrop", C, &a);
putchar('\n');
tt_dump_routingtable(&a, C, 0);
tt_drop(&a, C);
}
putchar('\n');
tt_arena_flush(&a);
tt_dump_arena_dot(&a);
/* tt_dump_arena_summary(&a); */
tt_dump_arena_dot("after1", TT_NO_PTR, &a);
printf("\n============================================================ 2\n");
{
tt_node_ptr_t A =
tt_grab(&a,
tt_prepend_path(&a, TT_BOS,
tt_prepend_path(&a, 'A',
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_arena_flush(&a);
tt_dump_arena_dot("A", A, &a);
tt_node_ptr_t B =
tt_grab(&a,
tt_prepend_path(&a, TT_BOS,
tt_prepend_path(&a, TT_WILD,
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_dot("B", B, &a);
tt_node_ptr_t C = tt_trie_union(&a, A, B);
tt_arena_flush(&a);
tt_dump_arena_dot("Cpredrop", C, &a);
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);
putchar('\n');
tt_dump_routingtable(&a, C, 0);
tt_drop(&a, C);
}
printf("\n============================================================ 3\n");
{
tt_node_ptr_t A =
tt_grab(&a,
tt_prepend_path(&a, TT_BOS,
tt_prepend_path(&a, 'A',
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_arena_flush(&a);
tt_dump_arena_dot("A", A, &a);
tt_node_ptr_t B = tt_grab(&a, tt_prepend_path(&a, TT_WILD, tt_begin_path(&a, b_set)));
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_arena_flush(&a);
tt_dump_arena_dot("Cpredrop", C, &a);
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);
putchar('\n');
tt_dump_routingtable(&a, C, 0);
tt_drop(&a, C);
}
printf("\n============================================================ 4\n");
{
tt_node_ptr_t A =
tt_grab(&a,
tt_prepend_path(&a, TT_BOS,
tt_prepend_path(&a, 'A',
tt_prepend_path(&a, TT_EOS,
/* NB b_set below */
tt_begin_path(&a, b_set)))));
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_node_ptr_t B = tt_grab(&a, tt_prepend_path(&a, TT_WILD, tt_begin_path(&a, b_set)));
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_arena_flush(&a);
tt_dump_arena_dot("Cpredrop", C, &a);
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);
putchar('\n');
tt_dump_routingtable(&a, C, 0);
tt_drop(&a, C);
}
tt_arena_flush(&a);
tt_dump_arena_dot("afterAll", TT_NO_PTR, &a); /* expect a_set and b_set here */
tt_arena_done(&a);
return EXIT_SUCCESS;

28
route.c
View File

@ -179,18 +179,12 @@ tt_node_ptr_t tt_trie_combine(tt_arena_t *a,
return 0;
}
new_trie = g(trie1, trie2); /* already grabbed */
if (TT_NO_PTR_P(new_trie)) {
tt_drop(a, trie1);
tt_drop(a, trie2);
return 0;
}
tt_drop(a, trie1);
tt_drop(a, trie2);
if (TT_NO_PTR_P(new_trie)) return 0;
new_result_others = tt_grab(a, rupdate_dict(a, result_wild, result_others, key, new_trie));
if (TT_NO_PTR_P(new_result_others)) {
tt_drop(a, trie1);
tt_drop(a, trie2);
tt_drop(a, new_trie);
return 0;
}
tt_drop(a, new_trie);
if (TT_NO_PTR_P(new_result_others)) return 0;
tt_drop(a, result_others);
result_others = new_result_others;
return 1;
@ -231,15 +225,15 @@ tt_node_ptr_t tt_trie_combine(tt_arena_t *a,
tt_drop(a, combined);
return result;
} else {
tt_node_ptr_t r2_expanded = tt_grab(a, RET_IF_NO_PTR(expand(a, r2)));
tt_node_ptr_t result = g(r1, r2_expanded);
tt_drop(a, r2_expanded);
tt_node_ptr_t r1_expanded = tt_grab(a, RET_IF_NO_PTR(expand(a, r1)));
tt_node_ptr_t result = g(r1_expanded, r2);
tt_drop(a, r1_expanded);
return result;
}
} else if (t2 == TT_TAG_TAIL) {
tt_node_ptr_t r1_expanded = tt_grab(a, RET_IF_NO_PTR(expand(a, r1)));
tt_node_ptr_t result = g(r1_expanded, r2);
tt_drop(a, r1_expanded);
tt_node_ptr_t r2_expanded = tt_grab(a, RET_IF_NO_PTR(expand(a, r2)));
tt_node_ptr_t result = g(r1, r2_expanded);
tt_drop(a, r2_expanded);
return result;
}

View File

@ -354,10 +354,16 @@ static void dump_dot_edge(tt_arena_t *a, tt_node_ptr_t p, int lr, char const *ed
}
}
void tt_dump_arena_dot(tt_arena_t *a) {
void tt_dump_arena_dot(char const *rootlabel, tt_node_ptr_t rootptr, tt_arena_t *a) {
int i;
printf("digraph Arena {\n");
printf(" root [shape=box, label=\"%s\"];\n", rootlabel);
if (tt_ptr_tag(rootptr) != TT_TAG_INVALID && tt_ptr_tag(rootptr) != TT_TAG_SPECIAL) {
printf(" root -> i%u_%u;\n",
tt_ptr_idx(rootptr),
tt_ptr_tag(rootptr));
}
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);
@ -386,7 +392,7 @@ void tt_dump_arena_dot(tt_arena_t *a) {
printf("label=\"branch");
break;
case TT_TAG_LEAF:
printf("label=\"leaf a%d", (int) a->nodes[n].b);
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);
@ -399,7 +405,7 @@ void tt_dump_arena_dot(tt_arena_t *a) {
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);
printf(" i%u r%d\"];\n", n, a->headers[n].inuse.refcount);
switch (tt_ptr_tag(p)) {
case TT_TAG_TAIL:
dump_dot_edge(a, p, 0, "trie");

View File

@ -110,7 +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_dump_arena_dot(char const *rootlabel, tt_node_ptr_t rootptr, tt_arena_t *a);
extern void tt_arena_flush(tt_arena_t *a);