}
}
+/*
+ * Assign unique ID to all buckets to enable sorting
+ */
+static void
+assign_bucket_id(struct trie_node *node, u32 *counter)
+{
+ assert(node != NULL);
+
+ if (node->bucket)
+ {
+ if (node->bucket->id == 0)
+ {
+ node->bucket->id = *counter;
+ *counter += 1;
+ }
+
+ /* All leaves have a bucket */
+ if (is_leaf(node))
+ return;
+ }
+
+ if (node->child[0])
+ assign_bucket_id(node->child[0], counter);
+
+ if (node->child[1])
+ assign_bucket_id(node->child[1], counter);
+}
+
/*
* First pass of Optimal Route Table Construction (ORTC) algorithm
*/
assert(a != NULL);
assert(b != NULL);
- if ((uintptr_t)a < (uintptr_t)b)
+ if (a->id < b->id)
return -1;
- if ((uintptr_t)a > (uintptr_t)b)
+ if (a->id > b->id)
return 1;
return 0;
output_buckets[output_count++] = input_buckets[i];
}
- // strictly greater
+ /* Strictly greater */
for (int i = 1; i < output_count; i++)
- assert(output_buckets[i - 1] < output_buckets[i]);
+ assert(output_buckets[i - 1]->id < output_buckets[i]->id);
- // duplicates
+ /* Duplicates */
for (int i = 0; i < output_count; i++)
for (int j = i + 1; j < output_count; j++)
assert(output_buckets[i] != output_buckets[j]);
bug("Impossible");
}
- // strictly greater
+ /* Strictly greater */
for (int k = 1; k < output_count; k++)
- assert(output[k - 1] < output[k]);
+ assert(output[k - 1]->id < output[k]->id);
- // duplicates
+ /* Duplicates */
for (int k = 0; k < output_count; k++)
for (int l = k + 1; l < output_count; l++)
assert(output[k] != output[l]);
second_pass(left);
second_pass(right);
- // duplicates
+ /* Duplicates */
for (int i = 0; i < left->potential_buckets_count; i++)
for (int j = i + 1; j < left->potential_buckets_count; j++)
assert(left->potential_buckets[i] != left->potential_buckets[j]);
}
else
{
- // Internal nodes should not have a bucket since it was deleted during first pass
+ /* Internal nodes should not have a bucket since it was deleted during first pass */
if (!is_leaf(node))
assert(node->bucket == NULL);
log("====PREFIXES BEFORE ====");
+ /* Start with 1 as 0 is reserved for IDs that have not been assigned yet */
+ u32 bucket_counter = 1;
+ assign_bucket_id(p->root, &bucket_counter);
+
log("====FIRST PASS====");
first_pass(p->root, p->trie_pool);
first_pass_after_check(p->root);