From fae7ea02cd078ea08c90bcff57979079d403e22c Mon Sep 17 00:00:00 2001 From: Christopher Lam Date: Sat, 2 Apr 2022 10:26:34 +0800 Subject: [PATCH] [account.cpp] gnc_accounts_and_all_descendants converted from scm much more efficient than guile algorithm, avoids numerous repeated GList<->SCM conversions, and traversals of account descendants. --- bindings/engine-common.i | 4 ++++ libgnucash/engine/Account.cpp | 16 ++++++++++++++++ libgnucash/engine/Account.h | 1 + 3 files changed, 21 insertions(+) diff --git a/bindings/engine-common.i b/bindings/engine-common.i index b4d861dd67..d85e7ef8d1 100644 --- a/bindings/engine-common.i +++ b/bindings/engine-common.i @@ -48,10 +48,14 @@ AccountList * gnc_account_get_descendants (const Account *account); %newobject gnc_account_get_descendants_sorted; AccountList * gnc_account_get_descendants_sorted (const Account *account); +%newobject gnc_accounts_and_all_descendants; +AccountList * gnc_accounts_and_all_descendants (AccountList *accounts); + %ignore gnc_account_get_children; %ignore gnc_account_get_children_sorted; %ignore gnc_account_get_descendants; %ignore gnc_account_get_descendants_sorted; +%ignore gnc_accounts_and_all_descendants; %include %include diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp index 92f4d2bf5b..4140ca1f6f 100644 --- a/libgnucash/engine/Account.cpp +++ b/libgnucash/engine/Account.cpp @@ -49,6 +49,7 @@ extern "C" { #include #include +#include static QofLogModule log_module = GNC_MOD_ACCOUNT; @@ -6228,6 +6229,21 @@ gboolean xaccAccountRegister (void) return qof_object_register (&account_object_def); } +using AccountSet = std::unordered_set; +static void maybe_add_descendants (Account* acc, gpointer arg) +{ + if (static_cast (arg)->insert (acc).second) + g_list_foreach (GET_PRIVATE(acc)->children, (GFunc) maybe_add_descendants, arg); +}; + +GList * +gnc_accounts_and_all_descendants (GList *accounts) +{ + AccountSet accset; + g_list_foreach (accounts, (GFunc) maybe_add_descendants, &accset); + return std::accumulate (accset.begin(), accset.end(), (GList*) nullptr, g_list_prepend); +} + /* ======================= UNIT TESTING ACCESS ======================= * The following functions are for unit testing use only. */ diff --git a/libgnucash/engine/Account.h b/libgnucash/engine/Account.h index 19093036c1..868c1b9557 100644 --- a/libgnucash/engine/Account.h +++ b/libgnucash/engine/Account.h @@ -1620,6 +1620,7 @@ void dxaccAccountSetQuoteTZ (Account *account, const char *tz); const char * dxaccAccountGetQuoteTZ (const Account *account); /** @} */ +GList * gnc_accounts_and_all_descendants (GList *accounts); /** @name Account parameter names @{