Bugfixes
This commit is contained in:
parent
e20f3730d1
commit
7bfbb3f8c9
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
all: t
|
||||
|
||||
t: *.c
|
||||
$(CC) -Wall -Os -o $@ -g *.c
|
||||
$(CC) -Wall -O0 -o $@ -g *.c
|
||||
|
||||
clean:
|
||||
rm -f t
|
||||
|
|
18
critbit.c
18
critbit.c
|
@ -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
108
main.c
|
@ -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;
|
||||
|
|
22
route.c
22
route.c
|
@ -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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
if (TT_NO_PTR_P(new_result_others)) return 0;
|
||||
tt_drop(a, result_others);
|
||||
result_others = new_result_others;
|
||||
return 1;
|
||||
|
@ -231,17 +225,17 @@ 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);
|
||||
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);
|
||||
return result;
|
||||
}
|
||||
} else if (t2 == TT_TAG_TAIL) {
|
||||
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;
|
||||
}
|
||||
|
||||
if (t1 == TT_TAG_OK || t2 == TT_TAG_OK) {
|
||||
return f(f_context, r1, r2);
|
||||
|
|
12
treetrie.c
12
treetrie.c
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue