From c3db3e569d610b5c049ad4d7790db5f7dfd45b54 Mon Sep 17 00:00:00 2001 From: Igor Putovny Date: Wed, 31 Jul 2024 18:12:50 +0200 Subject: [PATCH] Split third pass function into two functions (in order to get rid of redundant condition testing) --- proto/aggregator/aggregator.c | 85 +++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 38 deletions(-) diff --git a/proto/aggregator/aggregator.c b/proto/aggregator/aggregator.c index 441e63f4e..61f362159 100644 --- a/proto/aggregator/aggregator.c +++ b/proto/aggregator/aggregator.c @@ -554,64 +554,73 @@ remove_potential_buckets(struct trie_node *node) * Third pass of Optimal Route Table Construction (ORTC) algorithm */ static void -third_pass(struct trie_node *node) +third_pass_helper(struct trie_node *node) { assert(node != NULL); assert(node->potential_buckets_count <= MAX_POTENTIAL_BUCKETS_COUNT); - /* Root is assigned any of its potential buckets */ - if (!node->parent) - { - assert(node->potential_buckets_count > 0); - assert(node->potential_buckets[0] != NULL); - node->bucket = node->potential_buckets[0]; + /* Internal nodes should not have a bucket since it was deleted during first pass */ + if (!is_leaf(node)) + assert(node->bucket == NULL); + + /* Bucket inherited from the closest ancestor with a non-null bucket */ + const struct aggregator_bucket *inherited_bucket = node->parent->ancestor->bucket; - /* Root is the first node with a bucket */ - node->ancestor = node; + /* + * If bucket inherited from ancestor is one of potential buckets of this node, + * then this node doesn't need bucket because it inherits one. + */ + if (is_bucket_potential(node, inherited_bucket)) + { + node->bucket = NULL; + remove_potential_buckets(node); } else { - /* Internal nodes should not have a bucket since it was deleted during first pass */ - if (!is_leaf(node)) - assert(node->bucket == NULL); - - /* Bucket inherited from the closest ancestor with a non-null bucket */ - const struct aggregator_bucket *inherited_bucket = node->parent->ancestor->bucket; - - /* - * If bucket inherited from ancestor is one of potential buckets of this node, - * then this node doesn't need bucket because it inherits one. - */ - if (is_bucket_potential(node, inherited_bucket)) - { - node->bucket = NULL; - remove_potential_buckets(node); - } - else - { - assert(node->potential_buckets_count > 0); - node->bucket = node->potential_buckets[0]; - } - - /* - * Node with a bucket is the closest ancestor for all his descendants. - * Otherwise, it must refer to the closest ancestor of its parent. - */ - node->ancestor = node->bucket ? node : node->parent->ancestor; + assert(node->potential_buckets_count > 0); + node->bucket = node->potential_buckets[0]; } + /* + * Node with a bucket is the closest ancestor for all his descendants. + * Otherwise, it must refer to the closest ancestor of its parent. + */ + node->ancestor = node->bucket ? node : node->parent->ancestor; + /* Preorder traversal */ if (node->child[0]) - third_pass(node->child[0]); + third_pass_helper(node->child[0]); if (node->child[1]) - third_pass(node->child[1]); + third_pass_helper(node->child[1]); /* Leaves with no assigned bucket are removed */ if (!node->bucket && is_leaf(node)) remove_node(node); } +static void +third_pass(struct trie_node *root) +{ + assert(root != NULL); + assert(root->potential_buckets_count <= MAX_POTENTIAL_BUCKETS_COUNT); + + assert(root->potential_buckets_count > 0); + assert(root->potential_buckets[0] != NULL); + + /* Root is assigned any of its potential buckets */ + root->bucket = root->potential_buckets[0]; + + /* The closest ancestor of the root node with a non-null bucket is the root itself */ + root->ancestor = root; + + if (root->child[0]) + third_pass_helper(root->child[0]); + + if (root->child[1]) + third_pass_helper(root->child[1]); +} + static void get_trie_prefix_count_helper(const struct trie_node *node, int *count) { -- 2.47.2