Hi, I wanted to know the size of the augeas tree to calculate the memory impact of adding indexes to tree nodes, and no function was existing for this. aug_get is returning the size of the node set match by PATH, but this is not the size of the tree i.e. it's not recursive.
I would propose the attached patch to add this capability to the API. I find that it could be useful also for sanity check in other applications, like in a GUI, when a duplicated model must stay in sync with the augeas tree. Cheer, Francis
>From 95cebcc676cab3a4896a16bb0899124aea3986ca Mon Sep 17 00:00:00 2001 From: Francis Giraldeau <[email protected]> Date: Fri, 15 Oct 2010 23:44:23 -0400 Subject: [PATCH] Add function to get a subtree size The new function aug_size returns the number of nodes in the subtree selected by PATH. It counts the number of nodes by traversing recursively the subtree. * Add the aug_size API function * Add the "size" command to augtool * Add unittest for aug_size --- src/augeas.c | 35 +++++++++++++++++++++++++++++++++++ src/augeas.h | 10 ++++++++++ src/augeas_sym.version | 5 +++++ src/augtool.c | 24 ++++++++++++++++++++++++ tests/test-api.c | 12 ++++++++++++ 5 files changed, 86 insertions(+), 0 deletions(-) diff --git a/src/augeas.c b/src/augeas.c index 25ca016..7d51720 100644 --- a/src/augeas.c +++ b/src/augeas.c @@ -173,6 +173,14 @@ void tree_store_value(struct tree *tree, char **value) { tree_mark_dirty(tree); } +int tree_size(struct tree *tree) { + int size = 1; + list_for_each(c, tree->children) { + size += tree_size(c); + } + return size; +} + int tree_set_value(struct tree *tree, const char *value) { char *v = NULL; @@ -1350,6 +1358,33 @@ int aug_print(const struct augeas *aug, FILE *out, const char *pathin) { return -1; } +int aug_size(const struct augeas *aug, const char *path) { + struct pathx *p; + struct tree *root; + int r = 0; + + api_entry(aug); + + if (path == NULL || strlen(path) == 0) { + path = "/*"; + } + + p = pathx_aug_parse(aug, aug->origin, path, true); + ERR_BAIL(aug); + pathx_find_one(p, &root); + + if (root != NULL) + r = tree_size(root); + + free_pathx(p); + + api_exit(aug); + return r; + error: + api_exit(aug); + return -1; +} + void aug_close(struct augeas *aug) { if (aug == NULL) return; diff --git a/src/augeas.h b/src/augeas.h index b4848cb..2da2cee 100644 --- a/src/augeas.h +++ b/src/augeas.h @@ -276,6 +276,16 @@ int aug_load(augeas *aug); */ int aug_print(const augeas *aug, FILE *out, const char *path); +/* Function: aug_size + * + * Get the number of nodes in an augeas tree. + * + * Returns: + * number of nodes of the tree under PATH on success, or a negative value + * on failure + */ +int aug_size(const augeas *aug, const char *path); + /* Function: aug_close * * Close this Augeas instance and free any storage associated with diff --git a/src/augeas_sym.version b/src/augeas_sym.version index 542f5fa..64e9d1e 100644 --- a/src/augeas_sym.version +++ b/src/augeas_sym.version @@ -34,3 +34,8 @@ AUGEAS_0.11.0 { global: aug_setm; } AUGEAS_0.10.0; + +AUGEAS_0.12.0 { + global: + aug_size; +} AUGEAS_0.11.0; \ No newline at end of file diff --git a/src/augtool.c b/src/augtool.c index 6c8416a..3c88d01 100644 --- a/src/augtool.c +++ b/src/augtool.c @@ -770,6 +770,29 @@ static const struct command_def cmd_print_def = { .help = "Print entries in the tree. If PATH is given, printing starts there,\n otherwise the whole tree is printed" }; +static void cmd_size(struct command *cmd) { + const char *path = arg_value(cmd, "path"); + int size; + + size = aug_size(aug, path); + err_check(cmd); + printf("tree size: %d\n", size); +} + +static const struct command_opt_def cmd_size_opts[] = { + { .type = CMD_PATH, .name = "path", .optional = true, + .help = "get the number of nodes of this subtree" }, + CMD_OPT_DEF_LAST +}; + +static const struct command_def cmd_size_def = { + .name = "size", + .opts = cmd_size_opts, + .handler = cmd_size, + .synopsis = "size of this subtree", + .help = "Print the size of this tree. If PATH is given, returns the size of the subtree there,\n otherwise, returns the size of the whole tree" +}; + static void cmd_save(struct command *cmd) { int r; r = aug_save(aug); @@ -928,6 +951,7 @@ static const struct command_def const *commands[] = { &cmd_match_def, &cmd_mv_def, &cmd_print_def, + &cmd_size_def, &cmd_rm_def, &cmd_save_def, &cmd_set_def, diff --git a/tests/test-api.c b/tests/test-api.c index 322f4a9..e853553 100644 --- a/tests/test-api.c +++ b/tests/test-api.c @@ -222,6 +222,17 @@ static void testDefNodeCreateMeta(CuTest *tc) { aug_close(aug); } +static void testTreeSize(CuTest *tc) { + int size; + struct augeas *aug; + + aug = aug_init(root, loadpath, AUG_NO_STDINC|AUG_NO_LOAD); + CuAssertPtrNotNull(tc, aug); + + size = aug_size(aug, "/augeas/version"); + CuAssertIntEquals(tc, 8, size); +} + int main(void) { char *output = NULL; CuSuite* suite = CuSuiteNew(); @@ -232,6 +243,7 @@ int main(void) { SUITE_ADD_TEST(suite, testDefVarMeta); SUITE_ADD_TEST(suite, testDefNodeExistingMeta); SUITE_ADD_TEST(suite, testDefNodeCreateMeta); + SUITE_ADD_TEST(suite, testTreeSize); abs_top_srcdir = getenv("abs_top_srcdir"); if (abs_top_srcdir == NULL) -- 1.7.1
_______________________________________________ augeas-devel mailing list [email protected] https://www.redhat.com/mailman/listinfo/augeas-devel
