commit 24262a180898b2ebd4dcbb8d3b36d6728d2c5a2f
parent 473023652e0746cdd1f260fdb9922f7a541bce55
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 8 Apr 2026 10:12:39 +0200
Update to the sln_node_get_desc function
Add the number of children of the node to its descriptor. The result of
the sln_get query on a node is updated to display this new data.
Diffstat:
6 files changed, 36 insertions(+), 15 deletions(-)
diff --git a/doc/sln-get.1 b/doc/sln-get.1
@@ -15,7 +15,7 @@
.\"
.\" You should have received a copy of the GNU General Public License
.\" along with this program. If not, see <http://www.gnu.org/licenses/>.
-.Dd March 10, 2026
+.Dd April 8, 2026
.Dt SLN-GET 1
.Os
.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
@@ -115,9 +115,10 @@ line represents the two values of a polyline vertex, separated by a space:
its wavenumber in cm^-1, and its associated spectrum value.
.\""""""""""""""""""""""""""""""""""
.It Fl n
-Displays the description of the current node, i.e., its level relative to
-the root, the number of lines it partitions, and the number of polyline
-vertices used to represent them at the node's hierarchical level.
+Displays the description of the current node, i.e., its level relative
+to the root, the number of lines it partitions, the number of polyline
+vertices used to represent them at the node's hierarchical level, and
+the number of the node's children.
.\""""""""""""""""""""""""""""""""""
.It Fl p Ar molparams
Isotopologue metadata from which the tree was built.
diff --git a/src/sln.h b/src/sln.h
@@ -179,8 +179,9 @@ static const struct sln_tree_desc SLN_TREE_DESC_NULL = SLN_TREE_DESC_NULL__;
struct sln_node_desc {
size_t nlines;
size_t nvertices;
+ unsigned nchildren;
};
-#define SLN_NODE_DESC_NULL__ {0,0}
+#define SLN_NODE_DESC_NULL__ {0,0,0}
static const struct sln_node_desc SLN_NODE_DESC_NULL = SLN_NODE_DESC_NULL__;
struct sln_vertex { /* 8 Bytes */
@@ -339,7 +340,8 @@ sln_node_eval
SLN_API res_T
sln_node_get_desc
- (const struct sln_node* node,
+ (const struct sln_tree* tree,
+ const struct sln_node* node,
struct sln_node_desc* desc);
SLN_API double
diff --git a/src/sln_get.c b/src/sln_get.c
@@ -342,7 +342,7 @@ print_level_descriptor(const struct cmd* cmd)
} else {
/* The queried level or a leaf is reached, update the descriptor */
- if((res = sln_node_get_desc(node, &desc)) != RES_OK) goto error;
+ if((res = sln_node_get_desc(cmd->tree, node, &desc)) != RES_OK) goto error;
nvertices += desc.nvertices;
++nnodes;
@@ -404,12 +404,13 @@ print_node_descriptor(const struct cmd* cmd)
if((node = get_node(cmd, &depth)) == NULL) goto exit; /* tree is empty */
- res = sln_node_get_desc(node, &desc);
+ res = sln_node_get_desc(cmd->tree, node, &desc);
if(res != RES_OK) goto error;
printf("level: %u\n", depth);
printf("#lines: %lu\n", (unsigned long)desc.nlines);
printf("#vertices: %lu\n", (unsigned long)desc.nvertices);
+ printf("#nodes: %u\n", desc.nchildren);
exit:
return res;
diff --git a/src/sln_slab.c b/src/sln_slab.c
@@ -393,7 +393,7 @@ check_sampled_node(const struct cmd* cmd, const struct sln_node* node)
{
/* Verify that the sampled node corresponds to a single line */
struct sln_node_desc desc = SLN_NODE_DESC_NULL;
- SLN(node_get_desc(node, &desc));
+ SLN(node_get_desc(cmd->tree, node, &desc));
ASSERT(desc.nlines == 1);
}
#endif
diff --git a/src/sln_tree.c b/src/sln_tree.c
@@ -728,12 +728,16 @@ sln_node_eval
}
res_T
-sln_node_get_desc(const struct sln_node* node, struct sln_node_desc* desc)
+sln_node_get_desc
+ (const struct sln_tree* tree,
+ const struct sln_node* node,
+ struct sln_node_desc* desc)
{
- if(!node || !desc) return RES_BAD_ARG;
+ if(!tree || !node || !desc) return RES_BAD_ARG;
desc->nlines = node->range[1] - node->range[0];
desc->nlines += 1/*boundaries are inclusives*/;
desc->nvertices = node->nvertices;
+ desc->nchildren = sln_node_get_child_count(tree, node);
return RES_OK;
}
diff --git a/src/test_sln_tree.c b/src/test_sln_tree.c
@@ -188,24 +188,37 @@ test_tree
CHK(node = sln_tree_get_root(tree));
CHK(node != NULL);
- CHK(sln_node_get_desc(NULL, &node_desc) == RES_BAD_ARG);
- CHK(sln_node_get_desc(node, NULL) == RES_BAD_ARG);
- CHK(sln_node_get_desc(node, &node_desc) == RES_OK);
+ CHK(sln_node_get_desc(NULL, node, &node_desc) == RES_BAD_ARG);
+ CHK(sln_node_get_desc(tree, NULL, &node_desc) == RES_BAD_ARG);
+ CHK(sln_node_get_desc(tree, node, NULL) == RES_BAD_ARG);
+ CHK(sln_node_get_desc(tree, node, &node_desc) == RES_OK);
CHK(node_desc.nlines = desc.nlines);
CHK(node_desc.nvertices >= 1 && node_desc.nvertices < desc.nvertices);
+ CHK(node_desc.nchildren <= desc.arity);
while(!sln_node_is_leaf(node)) {
struct sln_node_desc node_desc_next = SLN_NODE_DESC_NULL;
+
+ CHK(sln_node_get_child_count(tree, node) != 0);
+ CHK(sln_node_get_child_count(tree, node) <= desc.arity);
+
node = sln_node_get_child(tree, node, 0);
- CHK(sln_node_get_desc(node, &node_desc_next) == RES_OK);
+ CHK(sln_node_get_desc(tree, node, &node_desc_next) == RES_OK);
CHK(node_desc_next.nlines >= 1);
CHK(node_desc_next.nlines < node_desc.nlines);
CHK(node_desc_next.nvertices >= 1);
CHK(node_desc_next.nlines < node_desc.nvertices);
+ if(sln_node_is_leaf(node)) {
+ CHK(node_desc_next.nchildren == 0);
+ } else {
+ CHK(node_desc_next.nchildren != 0);
+ CHK(node_desc_next.nchildren <= desc.arity);
+ }
node_desc = node_desc_next;
}
+ CHK(sln_node_get_child_count(tree, node) == 0);
CHK(sln_node_get_line_count(node) <= desc.max_nlines_per_leaf);
CHK(sln_node_get_line(NULL, node, 0, &line) == RES_BAD_ARG);