commit 1a4496eef4c5ad30a2e289ac89377c50746caad7
parent 70df096314ca59941e4b1aa38fb02775b6e46704
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 15 Apr 2026 15:32:48 +0200
Add a test on tree construction
Verify that constructing a binary tree by merging child polylines or by
collapsing them within the parent node yields the same result.
Diffstat:
| M | src/test_sln_tree.c | | | 212 | ++++++++++++++++++++++++++++++++++++++++++------------------------------------- |
1 file changed, 114 insertions(+), 98 deletions(-)
diff --git a/src/test_sln_tree.c b/src/test_sln_tree.c
@@ -142,6 +142,109 @@ check_tree_lines
}
static void
+check_mesh_equality(const struct sln_mesh* mesh1, const struct sln_mesh* mesh2)
+{
+ size_t i;
+ CHK(mesh1 && mesh2);
+ CHK(mesh1->nvertices == mesh2->nvertices);
+
+ FOR_EACH(i, 0, mesh1->nvertices) {
+ CHK(mesh1->vertices[i].wavenumber == mesh2->vertices[i].wavenumber);
+ CHK(mesh1->vertices[i].ka == mesh2->vertices[i].ka);
+ }
+}
+
+static void
+check_node_equality
+ (const struct sln_tree* tree1,
+ const struct sln_tree* tree2,
+ const struct sln_node* node1,
+ const struct sln_node* node2)
+{
+ struct sln_mesh mesh1 = SLN_MESH_NULL;
+ struct sln_mesh mesh2 = SLN_MESH_NULL;
+ size_t iline, nlines;
+
+ CHK(node1 && node2);
+ CHK(sln_node_is_leaf(node1) == sln_node_is_leaf(node2));
+ CHK(sln_node_get_line_count(node1) == sln_node_get_line_count(node2));
+ nlines = sln_node_get_line_count(node1);
+
+ FOR_EACH(iline, 0, nlines) {
+ struct shtr_line line1 = SHTR_LINE_NULL;
+ struct shtr_line line2 = SHTR_LINE_NULL;
+ CHK(sln_node_get_line(tree1, node1, iline, &line1) == RES_OK);
+ CHK(sln_node_get_line(tree2, node2, iline, &line2) == RES_OK);
+ CHK(shtr_line_eq(&line1, &line2));
+ }
+
+ CHK(sln_node_get_mesh(tree1, node1, &mesh1) == RES_OK);
+ CHK(sln_node_get_mesh(tree2, node2, &mesh2) == RES_OK);
+ check_mesh_equality(&mesh1, &mesh2);
+}
+
+static void
+check_tree_equality
+ (const struct sln_tree* tree1,
+ const struct sln_tree* tree2)
+{
+ #define STACK_SIZE \
+ ( SLN_TREE_DEPTH_MAX \
+ * (SLN_TREE_ARITY_MAX-1/*1st child*/) * 2/*#trees*/ \
+ + 1/*Dummy node*/)
+
+ const struct sln_node* stack[STACK_SIZE] = {NULL};
+ int istack = 0;
+
+ struct sln_tree_desc desc1 = SLN_TREE_DESC_NULL;
+ struct sln_tree_desc desc2 = SLN_TREE_DESC_NULL;
+ const struct sln_node* node1 = NULL;
+ const struct sln_node* node2 = NULL;
+
+ CHK(sln_tree_get_desc(tree1, &desc1) == RES_OK);
+ CHK(sln_tree_get_desc(tree2, &desc2) == RES_OK);
+ CHK(desc1.max_nlines_per_leaf == desc2.max_nlines_per_leaf);
+ CHK(desc1.mesh_decimation_err == desc2.mesh_decimation_err);
+ CHK(desc1.mesh_type == desc2.mesh_type);
+ CHK(desc1.line_profile == desc2.line_profile);
+ CHK(desc1.pressure == desc2.pressure);
+ CHK(desc1.temperature == desc2.temperature);
+ CHK(desc1.depth == desc2.depth);
+ CHK(desc1.nlines == desc2.nlines);
+ CHK(desc1.nvertices == desc2.nvertices);
+ CHK(desc1.nnodes == desc2.nnodes);
+ CHK(desc1.arity == desc2.arity);
+
+ stack[istack++] = NULL;
+ stack[istack++] = NULL;
+
+ node1 = sln_tree_get_root(tree1);
+ node2 = sln_tree_get_root(tree2);
+
+ while(node1 || node2) {
+ CHK((!node1 && !node2) || (node1 && node2));
+ check_node_equality(tree1, tree2, node1, node2);
+
+ if(sln_node_is_leaf(node1)) {
+ node2 = stack[--istack];
+ node1 = stack[--istack];
+ } else {
+ unsigned i = 0;
+ unsigned n = sln_node_get_child_count(tree1, node1);
+
+ FOR_EACH(i, 1, n) {
+ stack[istack++] = sln_node_get_child(tree1, node1, i);
+ stack[istack++] = sln_node_get_child(tree2, node2, i);
+ }
+ node1 = sln_node_get_child(tree1, node1, 0);
+ node2 = sln_node_get_child(tree2, node2, 0);
+ }
+ }
+
+ #undef STACK_SIZE
+}
+
+static void
test_tree
(struct sln_device* sln,
const struct sln_tree_create_args* tree_args_in,
@@ -253,111 +356,24 @@ test_tree
tree_args.line_profile = SLN_LINE_PROFILE_VOIGT;
CHK(sln_tree_create(sln, &tree_args, &tree) == RES_OK);
- CHK(sln_tree_ref_put(tree) == RES_OK);
-}
-static void
-check_mesh_equality(const struct sln_mesh* mesh1, const struct sln_mesh* mesh2)
-{
- size_t i;
- CHK(mesh1 && mesh2);
- CHK(mesh1->nvertices == mesh2->nvertices);
-
- FOR_EACH(i, 0, mesh1->nvertices) {
- CHK(mesh1->vertices[i].wavenumber == mesh2->vertices[i].wavenumber);
- CHK(mesh1->vertices[i].ka == mesh2->vertices[i].ka);
- }
-}
+ if(tree_args.arity == 2 && tree_args.collapse_polylines == 0) {
+ struct sln_tree* tree2 = NULL;
-static void
-check_node_equality
- (const struct sln_tree* tree1,
- const struct sln_tree* tree2,
- const struct sln_node* node1,
- const struct sln_node* node2)
-{
- struct sln_mesh mesh1 = SLN_MESH_NULL;
- struct sln_mesh mesh2 = SLN_MESH_NULL;
- size_t iline, nlines;
+ /* Verify that, when constructing a binary tree, creating polylines for
+ * internal nodes by reducing the polylines of their children results in
+ * exactly the same tree as when the polyline of an internal node is
+ * constructed by merging the polylines of its children */
+ tree_args.collapse_polylines = 1;
+ CHK(sln_tree_create(sln, &tree_args, &tree2) == RES_OK);
+ check_tree_equality(tree, tree2);
- CHK(node1 && node2);
- CHK(sln_node_is_leaf(node1) == sln_node_is_leaf(node2));
- CHK(sln_node_get_line_count(node1) == sln_node_get_line_count(node2));
- nlines = sln_node_get_line_count(node1);
-
- FOR_EACH(iline, 0, nlines) {
- struct shtr_line line1 = SHTR_LINE_NULL;
- struct shtr_line line2 = SHTR_LINE_NULL;
- CHK(sln_node_get_line(tree1, node1, iline, &line1) == RES_OK);
- CHK(sln_node_get_line(tree2, node2, iline, &line2) == RES_OK);
- CHK(shtr_line_eq(&line1, &line2));
+ CHK(sln_tree_ref_put(tree2) == RES_OK);
}
- CHK(sln_node_get_mesh(tree1, node1, &mesh1) == RES_OK);
- CHK(sln_node_get_mesh(tree2, node2, &mesh2) == RES_OK);
- check_mesh_equality(&mesh1, &mesh2);
+ CHK(sln_tree_ref_put(tree) == RES_OK);
}
-static void
-check_tree_equality
- (const struct sln_tree* tree1,
- const struct sln_tree* tree2)
-{
- #define STACK_SIZE \
- ( SLN_TREE_DEPTH_MAX \
- * (SLN_TREE_ARITY_MAX-1/*1st child*/) * 2/*#trees*/ \
- + 1/*Dummy node*/)
-
- const struct sln_node* stack[STACK_SIZE] = {NULL};
- int istack = 0;
-
- struct sln_tree_desc desc1 = SLN_TREE_DESC_NULL;
- struct sln_tree_desc desc2 = SLN_TREE_DESC_NULL;
- const struct sln_node* node1 = NULL;
- const struct sln_node* node2 = NULL;
-
- CHK(sln_tree_get_desc(tree1, &desc1) == RES_OK);
- CHK(sln_tree_get_desc(tree2, &desc2) == RES_OK);
- CHK(desc1.max_nlines_per_leaf == desc2.max_nlines_per_leaf);
- CHK(desc1.mesh_decimation_err == desc2.mesh_decimation_err);
- CHK(desc1.mesh_type == desc2.mesh_type);
- CHK(desc1.line_profile == desc2.line_profile);
- CHK(desc1.pressure == desc2.pressure);
- CHK(desc1.temperature == desc2.temperature);
- CHK(desc1.depth == desc2.depth);
- CHK(desc1.nlines == desc2.nlines);
- CHK(desc1.nvertices == desc2.nvertices);
- CHK(desc1.nnodes == desc2.nnodes);
- CHK(desc1.arity == desc2.arity);
-
- stack[istack++] = NULL;
- stack[istack++] = NULL;
-
- node1 = sln_tree_get_root(tree1);
- node2 = sln_tree_get_root(tree2);
-
- while(node1 || node2) {
- CHK((!node1 && !node2) || (node1 && node2));
- check_node_equality(tree1, tree2, node1, node2);
-
- if(sln_node_is_leaf(node1)) {
- node2 = stack[--istack];
- node1 = stack[--istack];
- } else {
- unsigned i = 0;
- unsigned n = sln_node_get_child_count(tree1, node1);
-
- FOR_EACH(i, 1, n) {
- stack[istack++] = sln_node_get_child(tree1, node1, i);
- stack[istack++] = sln_node_get_child(tree2, node2, i);
- }
- node1 = sln_node_get_child(tree1, node1, 0);
- node2 = sln_node_get_child(tree2, node2, 0);
- }
- }
-
- #undef STACK_SIZE
-}
static void
test_tree_serialization