extern linpool *rte_update_pool;
+static int total_nodes;
+static int prefix_nodes;
+static int artificial_nodes;
+static int additional_nodes;
+static int removed_nodes;
+static int one_child_nodes_1;
+static int one_child_nodes_2;
+
static inline int
is_leaf(const struct trie_node *node)
{
create_new_node(linpool *trie_pool)
{
struct trie_node *node = lp_allocz(trie_pool, sizeof(*node));
+ total_nodes++;
return node;
}
else
bug("Invalid child pointer");
}
+
+ removed_nodes++;
}
/*
new->parent = node;
node->child[bit] = new;
new->depth = new->parent->depth + 1;
+ prefix_nodes++;
}
node = node->child[bit];
new->parent = node;
node->child[bit] = new;
new->depth = new->parent->depth + 1;
+ prefix_nodes++;
}
node = node->child[bit];
* First pass of Optimal Route Table Construction (ORTC) algorithm
*/
static void
-first_pass(struct trie_node *node, linpool *trie_pool)
+first_pass(struct trie_node *node)
{
assert(node != NULL);
- assert(trie_pool != NULL);
if (is_leaf(node))
{
for (int i = 0; i < 2; i++)
{
+ if (!node->child[i])
+ artificial_nodes++;
}
if (node->child[0])
- first_pass(node->child[0], trie_pool);
+ first_pass(node->child[0]);
if (node->child[1])
- first_pass(node->child[1], trie_pool);
+ first_pass(node->child[1]);
}
static void
left = &artificial_node;
else
bug("Node does not have only one child");
+
+ one_child_nodes_1++;
}
assert(left != NULL && right != NULL);
node->child[0] = new;
else
bug("Node does not have only one child");
+
+ additional_nodes++;
}
+
+ one_child_nodes_2++;
}
/* Preorder traversal */
return result;
}
+static void
+get_trie_node_count_helper(const struct trie_node *node, int *count)
+{
+ *count += 1;
+
+ if (node->child[0])
+ get_trie_node_count_helper(node->child[0], count);
+
+ if (node->child[1])
+ get_trie_node_count_helper(node->child[1], count);
+}
+
+static int
+get_trie_node_count(const struct trie_node *root)
+{
+ int count = 0;
+ get_trie_node_count_helper(root, &count);
+ return count;
+}
+
static void
print_prefixes_ip4_helper(struct net_addr_ip4 *addr, const struct trie_node *node, int depth)
{
print_prefixes(p->root, p->addr_type);
}
- first_pass(p->root, p->trie_pool);
+ times_update(&main_timeloop);
+ log("==== FIRST PASS ====");
+ first_pass(p->root);
first_pass_after_check(p->root);
+ times_update(&main_timeloop);
+ log("==== FIRST PASS DONE ====");
if (p->logging)
{
print_prefixes(p->root, p->addr_type);
}
+ times_update(&main_timeloop);
+ log("==== SECOND PASS ====");
second_pass(p->root);
+ times_update(&main_timeloop);
+ log("==== SECOND PASS DONE");
if (p->logging)
{
print_prefixes(p->root, p->addr_type);
}
+ times_update(&main_timeloop);
+ log("==== THIRD PASS ====");
third_pass(p, p->root);
+ times_update(&main_timeloop);
+ log("==== THIRD PASS DONE ====");
if (p->logging)
{
log("%d prefixes after aggregation", p->after_count);
log("%d internal nodes with bucket", p->internal_nodes);
log("%d leaves with bucket", p->leaves);
+
+ log("");
+ log("%d nodes in total", total_nodes);
+ log("%d prefix nodes", prefix_nodes);
+ log("%d artificial nodes", artificial_nodes);
+ log("%d nodes added in the third pass", additional_nodes);
+ log("%d nodes removed", removed_nodes);
+ log("%d nodes left", get_trie_node_count(p->root));
+ log("%d one-child nodes in the second pass", one_child_nodes_1);
+ log("%d one-child nodes in the third pass", one_child_nodes_2);
+
+ total_nodes = prefix_nodes = artificial_nodes = additional_nodes = removed_nodes = one_child_nodes_1 = one_child_nodes_2 = 0;
log("==== AGGREGATION DONE ====");
}