From d21d6f934437949d060b8761ece950cfe7e8a610 Mon Sep 17 00:00:00 2001 From: Christopher Lam Date: Sun, 19 May 2024 19:30:45 +0800 Subject: [PATCH 1/3] [qofid.cpp] qof_collection_foreach_sorted --- libgnucash/engine/qofid.cpp | 13 +++++++++++-- libgnucash/engine/qofid.h | 3 +++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/libgnucash/engine/qofid.cpp b/libgnucash/engine/qofid.cpp index cd23c46365d..f295ccec00e 100644 --- a/libgnucash/engine/qofid.cpp +++ b/libgnucash/engine/qofid.cpp @@ -318,8 +318,8 @@ foreach_cb (gpointer item, gpointer arg) } void -qof_collection_foreach (const QofCollection *col, QofInstanceForeachCB cb_func, - gpointer user_data) +qof_collection_foreach_sorted (const QofCollection *col, QofInstanceForeachCB cb_func, + gpointer user_data, GCompareFunc sort_fn) { struct _qofid_iterate iter; GList *entries; @@ -333,9 +333,18 @@ qof_collection_foreach (const QofCollection *col, QofInstanceForeachCB cb_func, PINFO("Hash Table size of %s before is %d", col->e_type, g_hash_table_size(col->hash_of_entities)); entries = g_hash_table_get_values (col->hash_of_entities); + if (sort_fn) + entries = g_list_sort (entries, sort_fn); g_list_foreach (entries, foreach_cb, &iter); g_list_free (entries); PINFO("Hash Table size of %s after is %d", col->e_type, g_hash_table_size(col->hash_of_entities)); } + +void +qof_collection_foreach (const QofCollection *col, QofInstanceForeachCB cb_func, + gpointer user_data) +{ + qof_collection_foreach_sorted (col, cb_func, user_data, nullptr); +} /* =============================================================== */ diff --git a/libgnucash/engine/qofid.h b/libgnucash/engine/qofid.h index a7c9bc0bcf0..8a6f6157faa 100644 --- a/libgnucash/engine/qofid.h +++ b/libgnucash/engine/qofid.h @@ -146,6 +146,9 @@ QofInstance * qof_collection_lookup_entity (const QofCollection *, const GncGUID typedef void (*QofInstanceForeachCB) (QofInstance *, gpointer user_data); /** Call the callback for each entity in the collection. */ +void qof_collection_foreach_sorted (const QofCollection *col, QofInstanceForeachCB cb_func, + gpointer user_data, GCompareFunc sort_fn); + void qof_collection_foreach (const QofCollection *, QofInstanceForeachCB, gpointer user_data); From fe2cdf42c700618d2549ae48a6ada26dd5d3c31e Mon Sep 17 00:00:00 2001 From: Christopher Lam Date: Sun, 19 May 2024 19:31:54 +0800 Subject: [PATCH 2/3] [transaction.cpp] speed up book close --- libgnucash/engine/Transaction.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/libgnucash/engine/Transaction.cpp b/libgnucash/engine/Transaction.cpp index dc6d5186bd8..d50dce9073b 100644 --- a/libgnucash/engine/Transaction.cpp +++ b/libgnucash/engine/Transaction.cpp @@ -3070,6 +3070,12 @@ destroy_tx_on_book_close(QofInstance *ent, gpointer data) xaccTransDestroy(tx); } +static int +trans_reverse_order (const Transaction* a, const Transaction* b) +{ + return xaccTransOrder (b, a); +} + /** Handles book end - frees all transactions from the book * * @param book Book being closed @@ -3080,7 +3086,12 @@ gnc_transaction_book_end(QofBook* book) QofCollection *col; col = qof_book_get_collection(book, GNC_ID_TRANS); - qof_collection_foreach(col, destroy_tx_on_book_close, nullptr); + + // destroy all transactions from latest to earliest, because + // accounts' splits are stored chronologically and removing from + // the end is faster than from the middle. + qof_collection_foreach_sorted (col, destroy_tx_on_book_close, nullptr, + (GCompareFunc)trans_reverse_order); } #ifdef _MSC_VER From 370a06fb611f73ce91c2521837afdfa8eae779db Mon Sep 17 00:00:00 2001 From: Christopher Lam Date: Mon, 20 May 2024 08:05:01 +0800 Subject: [PATCH 3/3] [qofid.cpp] remove unnecessary struct --- libgnucash/engine/qofid.cpp | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/libgnucash/engine/qofid.cpp b/libgnucash/engine/qofid.cpp index f295ccec00e..78fefff1dff 100644 --- a/libgnucash/engine/qofid.cpp +++ b/libgnucash/engine/qofid.cpp @@ -302,40 +302,21 @@ qof_collection_set_data (QofCollection *col, gpointer user_data) /* =============================================================== */ -struct _qofid_iterate -{ - QofInstanceForeachCB fcn; - gpointer data; -}; - -static void -foreach_cb (gpointer item, gpointer arg) -{ - struct _qofid_iterate *iter = static_cast<_qofid_iterate*>(arg); - QofInstance *ent = static_cast(item); - - iter->fcn (ent, iter->data); -} - void qof_collection_foreach_sorted (const QofCollection *col, QofInstanceForeachCB cb_func, gpointer user_data, GCompareFunc sort_fn) { - struct _qofid_iterate iter; GList *entries; g_return_if_fail (col); g_return_if_fail (cb_func); - iter.fcn = cb_func; - iter.data = user_data; - PINFO("Hash Table size of %s before is %d", col->e_type, g_hash_table_size(col->hash_of_entities)); entries = g_hash_table_get_values (col->hash_of_entities); if (sort_fn) entries = g_list_sort (entries, sort_fn); - g_list_foreach (entries, foreach_cb, &iter); + g_list_foreach (entries, (GFunc)cb_func, user_data); g_list_free (entries); PINFO("Hash Table size of %s after is %d", col->e_type, g_hash_table_size(col->hash_of_entities));