gnucash stable: Multiple changes pushed
Christopher Lam
clam at code.gnucash.org
Mon May 13 00:58:42 EDT 2024
Updated via https://github.com/Gnucash/gnucash/commit/7b46466e (commit)
via https://github.com/Gnucash/gnucash/commit/e54e9d80 (commit)
via https://github.com/Gnucash/gnucash/commit/b28ca9bd (commit)
from https://github.com/Gnucash/gnucash/commit/579da58a (commit)
commit 7b46466ebd8e8a74ec49610813b2c73f86e9aa3e
Author: Christopher Lam <christopher.lck at gmail.com>
Date: Mon May 13 12:42:26 2024 +0800
[account.cpp] fix regression caused by 3f7a5a8267
whereby deleting an account and moving all splits to another account
would segfault. make a copy of priv->splits and work on the copy
rather than the original.
diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index 1fcd9928d9..e82fb8d9c0 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -2251,8 +2251,8 @@ xaccAccountMoveAllSplits (Account *accfrom, Account *accto)
* Convert each split's amount to accto's commodity.
* Commit to editing each transaction.
*/
- std::for_each (from_priv->splits.begin(), from_priv->splits.end(),
- [accto](Split *s){ xaccPostSplitMove (s, accto); });
+ auto splits = from_priv->splits;
+ std::for_each (splits.begin(), splits.end(), [accto](auto s){ xaccPostSplitMove (s, accto); });
/* Finally empty accfrom. */
g_assert(from_priv->splits.empty());
commit e54e9d808677f4b8fb21a546cc5b1232c492cc48
Author: Christopher Lam <christopher.lck at gmail.com>
Date: Sun May 12 23:58:44 2024 +0800
[account.cpp] use HashTable for splits
reduces xml loading time from 3.5s to 3.1s, i.e. 11% improvement
diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index 1290d1157c..1fcd9928d9 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -333,6 +333,7 @@ gnc_account_init(Account* acc)
priv->include_sub_account_balances = {};
new (&priv->splits) SplitsVec ();
+ priv->splits_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
priv->sort_dirty = FALSE;
}
@@ -1470,6 +1471,7 @@ xaccFreeAccount (Account *acc)
priv->balance_dirty = FALSE;
priv->sort_dirty = FALSE;
priv->splits.~SplitsVec();
+ g_hash_table_destroy (priv->splits_hash);
/* qof_instance_release (&acc->inst); */
g_object_unref(acc);
@@ -1556,6 +1558,7 @@ xaccAccountCommitEdit (Account *acc)
else
{
priv->splits.clear();
+ g_hash_table_remove_all (priv->splits_hash);
}
/* It turns out there's a case where this assertion does not hold:
@@ -1966,8 +1969,8 @@ gnc_account_insert_split (Account *acc, Split *s)
g_return_val_if_fail(GNC_IS_SPLIT(s), FALSE);
priv = GET_PRIVATE(acc);
- if (std::find (priv->splits.begin(), priv->splits.end(), s) != priv->splits.end())
- return FALSE;
+ if (!g_hash_table_add (priv->splits_hash, s))
+ return false;
priv->splits.push_back (s);
@@ -1997,10 +2000,9 @@ gnc_account_remove_split (Account *acc, Split *s)
priv = GET_PRIVATE(acc);
+ if (!g_hash_table_remove (priv->splits_hash, s))
+ return false;
auto it = std::remove (priv->splits.begin(), priv->splits.end(), s);
- if (it == priv->splits.end())
- return FALSE;
-
priv->splits.erase (it, priv->splits.end());
//FIXME: find better event type
qof_event_gen(&acc->inst, QOF_EVENT_MODIFY, nullptr);
diff --git a/libgnucash/engine/AccountP.hpp b/libgnucash/engine/AccountP.hpp
index abd43f69c8..d71f4ef313 100644
--- a/libgnucash/engine/AccountP.hpp
+++ b/libgnucash/engine/AccountP.hpp
@@ -120,6 +120,7 @@ typedef struct AccountPrivate
gboolean balance_dirty; /* balances in splits incorrect */
std::vector<Split*> splits; /* list of split pointers */
+ GHashTable* splits_hash;
gboolean sort_dirty; /* sort order of splits is bad */
LotList *lots; /* list of lot pointers */
commit b28ca9bdb4781e9dfde0664bf9e1fd109ef9636e
Author: Christopher Lam <christopher.lck at gmail.com>
Date: Sun May 12 20:16:37 2024 +0800
use c++ placement new
to initialize non-c++ object members
diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index f164e18720..1290d1157c 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -332,7 +332,7 @@ gnc_account_init(Account* acc)
priv->lower_balance_limit = {};
priv->include_sub_account_balances = {};
- priv->splits.clear();
+ new (&priv->splits) SplitsVec ();
priv->sort_dirty = FALSE;
}
diff --git a/libgnucash/engine/gnc-budget.cpp b/libgnucash/engine/gnc-budget.cpp
index 737c241e5a..ec8638df0c 100644
--- a/libgnucash/engine/gnc-budget.cpp
+++ b/libgnucash/engine/gnc-budget.cpp
@@ -29,7 +29,6 @@
#include <optional>
#include <unordered_map>
#include <vector>
-#include <memory>
#include "Account.h"
@@ -84,7 +83,7 @@ typedef struct GncBudgetPrivate
/* Recurrence (period info) for the budget */
Recurrence recurrence;
- std::unique_ptr<AcctMap> acct_map;
+ AcctMap acct_map;
/* Number of periods */
guint num_periods;
@@ -110,7 +109,7 @@ gnc_budget_init(GncBudget* budget)
priv = GET_PRIVATE(budget);
priv->name = CACHE_INSERT(_("Unnamed Budget"));
priv->description = CACHE_INSERT("");
- priv->acct_map = std::make_unique<AcctMap>();
+ new (&priv->acct_map) AcctMap ();
priv->num_periods = 12;
date = gnc_g_date_new_today ();
@@ -280,7 +279,7 @@ gnc_budget_free(QofInstance *inst)
CACHE_REMOVE(priv->name);
CACHE_REMOVE(priv->description);
- priv->acct_map = nullptr; // nullify to ensure unique_ptr is freed.
+ priv->acct_map.~AcctMap();
/* qof_instance_release (&budget->inst); */
g_object_unref(budget);
@@ -477,12 +476,8 @@ gnc_budget_set_num_periods(GncBudget* budget, guint num_periods)
gnc_budget_begin_edit(budget);
priv->num_periods = num_periods;
- std::for_each (priv->acct_map->begin(),
- priv->acct_map->end(),
- [num_periods](auto& it)
- {
- it.second.resize(num_periods);
- });
+ std::for_each (priv->acct_map.begin(), priv->acct_map.end(),
+ [num_periods](auto& it){ it.second.resize(num_periods); });
qof_instance_set_dirty(&budget->inst);
gnc_budget_commit_edit(budget);
@@ -681,7 +676,7 @@ get_perioddata (const GncBudget *budget, const Account *account, guint period_nu
if (period_num >= priv->num_periods)
throw std::out_of_range("period_num >= num_periods");
- auto& vec = priv->acct_map->operator[](account);
+ auto& vec = priv->acct_map[account];
if (vec.empty())
{
Summary of changes:
libgnucash/engine/Account.cpp | 18 ++++++++++--------
libgnucash/engine/AccountP.hpp | 1 +
libgnucash/engine/gnc-budget.cpp | 17 ++++++-----------
3 files changed, 17 insertions(+), 19 deletions(-)
More information about the gnucash-changes
mailing list