commit e0669f09d99f5866e16b662a05f13310fff6b0db
parent a18b7b206480fc086260e1be30364f7c6efca030
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Thu, 30 Apr 2026 12:22:45 +0200
Fix for tree whose root contains all lines
This is a borderline case that highlights several specific issues in the
construction process, which this commit resolves.
A new test has been added to detect construction bugs, and it now
verifies that everything works as expected.
Diffstat:
2 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/src/sln_tree_build.c b/src/sln_tree_build.c
@@ -1091,7 +1091,7 @@ partition_lines_breadth_first
node_range[0] = NODE(inode)->range[0];
node_range[1] = NODE(inode)->range[1];
nlines_node = node_range[1] - node_range[0] + 1/*inclusive bound*/;
- ASSERT(nlines_node > tree->args.leaf_nlines);
+ ASSERT(nlines_node >= tree->args.leaf_nlines);
if(nlines_node <= tree->args.leaf_nlines) {
/* Make a leaf */
@@ -1187,6 +1187,7 @@ build_subtrees
ASSERT(nsubtrees < INT_MAX);
#define NODE(Id) (darray_node_data_get(&tree->nodes) + (Id))
+ #define IS_LEAF(Buf, Id) (darray_node_cdata_get(Buf)[Id].offset == 0)
allocator = tree->sln->allocator;
@@ -1254,8 +1255,11 @@ build_subtrees
nnodes_t = darray_node_size_get(&tree->nodes);
res2 = darray_node_resize(&tree->nodes, nnodes_t + nnodes_s - 1/*root*/);
if(res2 == RES_OK) {
- /* Set the offset to the first child of the root node of the subtree */
- NODE(subtrees[i])->offset = ui64_to_ui32(nnodes_t - subtrees[i]);
+
+ if(!IS_LEAF(&scratch->nodes, 0)) {
+ /* Set the offset to the first child of the root node of the subtree */
+ NODE(subtrees[i])->offset = ui64_to_ui32(nnodes_t - subtrees[i]);
+ }
/* Copy the subtree nodes in the main node buffer */
src = darray_node_cdata_get(&scratch->nodes) + 1/*discard root*/;
diff --git a/src/test_sln_tree.c b/src/test_sln_tree.c
@@ -344,7 +344,7 @@ test_tree
CHK(sln_node_get_desc(tree, node, &node_desc) == RES_OK);
CHK(node_desc.ilines[0] == 0);
CHK(node_desc.ilines[1] == desc.nlines - 1);
- CHK(node_desc.nvertices >= 1 && node_desc.nvertices < desc.nvertices);
+ CHK(node_desc.nvertices >= 1 && node_desc.nvertices <= desc.nvertices);
CHK(node_desc.nchildren <= desc.arity);
while(!sln_node_is_leaf(node)) {
@@ -590,6 +590,14 @@ main(int argc, char** argv)
test_tree(sln, &tree_args, line_list);
test_tree_serialization(sln, &tree_args);
+ /* Test building a tree forcing all lines beeing in the root of the tree */
+ CHK(g_nlines < SLN_LEAF_NLINES_MAX);
+ tree_args.arity = 2;
+ tree_args.leaf_nlines = (unsigned)g_nlines;
+ tree_args.collapse_polylines = 0;
+ test_tree(sln, &tree_args, line_list);
+ test_tree_serialization(sln, &tree_args);
+
CHK(sln_device_ref_put(sln) == RES_OK);
CHK(shtr_ref_put(shtr) == RES_OK);
CHK(shtr_line_list_ref_put(line_list) == RES_OK);