mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
performance enhancement
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@4639 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
50bbf91b4b
commit
79e5ebb8d2
@ -109,6 +109,7 @@ xaccInitAccount (Account * acc)
|
||||
acc->splits = NULL;
|
||||
|
||||
acc->version = 0;
|
||||
acc->version_check = 0;
|
||||
acc->editlevel = 0;
|
||||
acc->balance_dirty = FALSE;
|
||||
acc->sort_dirty = FALSE;
|
||||
|
@ -141,6 +141,7 @@ struct _account {
|
||||
|
||||
/* version number, used for tracking multiuser updates */
|
||||
gint32 version;
|
||||
guint32 version_check; /* data aging timestamp */
|
||||
|
||||
GList *splits; /* list of split pointers */
|
||||
|
||||
|
@ -666,6 +666,7 @@ xaccInitTransaction (Transaction * trans)
|
||||
trans->date_posted.tv_nsec = 0;
|
||||
|
||||
trans->version = 0;
|
||||
trans->version_check = 0;
|
||||
trans->marker = 0;
|
||||
trans->editlevel = 0;
|
||||
trans->do_free = FALSE;
|
||||
|
@ -173,6 +173,7 @@ struct _transaction
|
||||
|
||||
/* version number, used for tracking multiuser updates */
|
||||
gint32 version;
|
||||
guint32 version_check; /* data aging timestamp */
|
||||
|
||||
GList * splits; /* list of splits */
|
||||
|
||||
|
@ -40,6 +40,7 @@ struct _GNCPrice {
|
||||
char *type;
|
||||
gnc_numeric value;
|
||||
gint32 version; /* version number, for syncing with backend */
|
||||
guint32 version_check; /* data aging timestamp */
|
||||
|
||||
/* 'private' object management fields */
|
||||
guint32 refcount; /* garbage collection reference count */
|
||||
|
@ -58,6 +58,7 @@ gnc_price_create(void)
|
||||
p->not_saved = FALSE;
|
||||
p->do_free = FALSE;
|
||||
p->version = 0;
|
||||
p->version_check = 0;
|
||||
xaccGUIDNew (&p->guid);
|
||||
xaccStoreEntity(p, &p->guid, GNC_ID_PRICE);
|
||||
gnc_engine_generate_event (&p->guid, GNC_EVENT_CREATE);
|
||||
|
@ -446,8 +446,9 @@ pgendRunQuery (Backend *bend, Query *q)
|
||||
sqlQuery *sq;
|
||||
GList *node, *anode, *xaction_list= NULL, *acct_list = NULL;
|
||||
|
||||
ENTER (" ");
|
||||
ENTER ("be=%p, qry=%p", be, q);
|
||||
if (!be || !q) return;
|
||||
be->version_check = (guint32) time(0);
|
||||
|
||||
gnc_engine_suspend_events();
|
||||
pgendDisable(be);
|
||||
@ -564,6 +565,8 @@ pgendSync (Backend *bend, AccountGroup *grp)
|
||||
PGBackend *be = (PGBackend *)bend;
|
||||
ENTER ("be=%p, grp=%p", be, grp);
|
||||
|
||||
be->version_check = (guint32) time(0);
|
||||
|
||||
/* store the account group hierarchy, and then all transactions */
|
||||
pgendStoreGroup (be, grp);
|
||||
pgendStoreAllTransactions (be, grp);
|
||||
@ -662,7 +665,9 @@ pgendSyncPriceDB (Backend *bend, GNCPriceDB *prdb)
|
||||
{
|
||||
PGBackend *be = (PGBackend *)bend;
|
||||
ENTER ("be=%p, prdb=%p", be, prdb);
|
||||
if (!be || !prdb) return;
|
||||
|
||||
be->version_check = (guint32) time(0);
|
||||
pgendStorePriceDB (be, prdb);
|
||||
|
||||
/* don't send events to GUI, don't accept callbacks to backend */
|
||||
@ -1033,6 +1038,7 @@ pgend_book_load_poll (Backend *bend)
|
||||
/* don't send events to GUI, don't accept callbacks to backend */
|
||||
gnc_engine_suspend_events();
|
||||
pgendDisable(be);
|
||||
be->version_check = (guint32) time(0);
|
||||
|
||||
pgendKVPInit(be);
|
||||
grp = pgendGetAllAccounts (be, NULL);
|
||||
@ -1088,6 +1094,7 @@ pgend_book_load_single (Backend *bend)
|
||||
/* don't send events to GUI, don't accept callbacks to backend */
|
||||
gnc_engine_suspend_events();
|
||||
pgendDisable(be);
|
||||
be->version_check = (guint32) time(0);
|
||||
|
||||
pgendKVPInit(be);
|
||||
grp = pgendGetAllAccounts (be, NULL);
|
||||
@ -1116,6 +1123,7 @@ pgend_price_load_single (Backend *bend)
|
||||
/* don't send events to GUI, don't accept callbacks to backend */
|
||||
gnc_engine_suspend_events();
|
||||
pgendDisable(be);
|
||||
be->version_check = (guint32) time(0);
|
||||
|
||||
prdb = pgendGetAllPrices (be, NULL);
|
||||
|
||||
@ -1751,6 +1759,8 @@ pgendInit (PGBackend *be)
|
||||
be->last_price = ts;
|
||||
be->last_transaction = ts;
|
||||
|
||||
be->version_check = (guint32) ts.tv_sec;
|
||||
|
||||
be->builder = sqlBuilder_new();
|
||||
|
||||
be->buff = g_malloc (QBUFSIZE);
|
||||
|
@ -53,6 +53,8 @@ typedef enum {
|
||||
MODE_EVENT
|
||||
} AccessMode;
|
||||
|
||||
#define MAX_VERSION_AGE 10
|
||||
|
||||
struct _pgend {
|
||||
Backend be;
|
||||
|
||||
@ -91,6 +93,8 @@ struct _pgend {
|
||||
Timespec last_price;
|
||||
Timespec last_transaction;
|
||||
|
||||
guint32 version_check; /* data aging timestamp */
|
||||
|
||||
/* scratch space for constructing queries */
|
||||
int bufflen;
|
||||
char *buff;
|
||||
|
@ -336,8 +336,8 @@ operation is probably OK.
|
||||
backend can't contact its server, then we should just save up caches,
|
||||
and then when contact with backend re-established, we should spit
|
||||
them out. The pgendSync routine should more or less do the trick;
|
||||
note, however, that the file format needs to save the version number
|
||||
...
|
||||
note, however, that the XML file format needs to save the version
|
||||
number ...
|
||||
|
||||
-- Implement various advanced database features, such as checking the
|
||||
user's permission to view/edit account by account ... (hmmm this
|
||||
|
@ -107,6 +107,7 @@ pgendStoreAccountNoLock (PGBackend *be, Account *acct,
|
||||
if (0 < pgendAccountCompareVersion (be, acct)) return;
|
||||
}
|
||||
acct->version ++; /* be sure to update the version !! */
|
||||
acct->version_check = be->version_check;
|
||||
|
||||
pgendPutOneAccountOnly (be, acct);
|
||||
|
||||
@ -395,7 +396,16 @@ pgendCopyAccountToEngine (PGBackend *be, const GUID *acct_guid)
|
||||
}
|
||||
else
|
||||
{
|
||||
engine_data_is_newer = - pgendAccountCompareVersion (be, acc);
|
||||
/* save some performance, don't go to the backend if the data is recent. */
|
||||
if (MAX_VERSION_AGE >= be->version_check - acc->version_check)
|
||||
{
|
||||
PINFO ("fresh data, skip check");
|
||||
engine_data_is_newer = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
engine_data_is_newer = - pgendAccountCompareVersion (be, acc);
|
||||
}
|
||||
}
|
||||
|
||||
if (0 > engine_data_is_newer)
|
||||
@ -416,6 +426,8 @@ pgendCopyAccountToEngine (PGBackend *be, const GUID *acct_guid)
|
||||
acc->kvp_data = pgendKVPFetch (be, &(acc->guid), acc->kvp_data);
|
||||
|
||||
pgendGetAccountCurrencyHack (be, acc);
|
||||
|
||||
acc->version_check = be->version_check;
|
||||
}
|
||||
|
||||
/* re-enable events to the backend and GUI */
|
||||
@ -478,6 +490,7 @@ pgend_account_commit_edit (Backend * bend,
|
||||
return 445;
|
||||
}
|
||||
acct->version ++; /* be sure to update the version !! */
|
||||
acct->version_check = be->version_check;
|
||||
|
||||
if (acct->do_free)
|
||||
{
|
||||
|
@ -214,8 +214,6 @@ are not using NTP for time synchronization; or, e.g. if one machine failed
|
||||
to have daylight-savings time set correctly: its transactions would be
|
||||
an hour newer/older than the others, leading to bad updates).
|
||||
|
||||
Prices need to have version numbers added.
|
||||
|
||||
/* The pgendAccountCompareVersion() routine compares the version
|
||||
* number of the account in the engine and the sql database. It
|
||||
* returns a negative number if the sql version is older (or the
|
||||
@ -224,6 +222,23 @@ Prices need to have version numbers added.
|
||||
* two are equal.
|
||||
*/
|
||||
|
||||
Version numbers need to be written to XML file
|
||||
|
||||
Version Timestamp
|
||||
-----------------
|
||||
The engine is structured so that whenever the GUI issues a query, that
|
||||
query is passed to the backend. (The engine assumes the worst: that
|
||||
the engine data cache is out of date and needs to be upgraded.)
|
||||
Unforunately, the GUI frequently queries for the same data several
|
||||
times in rapid succession. If this is taken at face value, then
|
||||
multiple redundant queries to the SQL server occur in quick succession.
|
||||
|
||||
The version_check field is used to minimize these redundant queries.
|
||||
It stores a timestamp; if the timestamp is less than 10 seconds old
|
||||
(MAX_VERSION_AGE), then the backend assumes that the engine data is
|
||||
sufficiently recent, and the sql query is skipped. Under certain
|
||||
situations, a considerable amount of querying can be avoided.
|
||||
|
||||
|
||||
Audit Trails
|
||||
------------
|
||||
|
@ -117,6 +117,7 @@ pgendStorePriceNoLock (PGBackend *be, GNCPrice *pr,
|
||||
if (0 < pgendPriceCompareVersion (be, pr)) return;
|
||||
}
|
||||
pr->version ++; /* be sure to update the version !! */
|
||||
pr->version_check = be->version_check;
|
||||
|
||||
/* make sure that we've stored the commodity
|
||||
* and currency before we store the price.
|
||||
@ -442,6 +443,7 @@ pgend_price_commit_edit (Backend * bend, GNCPrice *pr)
|
||||
return 445;
|
||||
}
|
||||
pr->version ++; /* be sure to update the version !! */
|
||||
pr->version_check = be->version_check;
|
||||
|
||||
if (pr->do_free)
|
||||
{
|
||||
|
@ -129,6 +129,7 @@ pgendStoreTransactionNoLock (PGBackend *be, Transaction *trans,
|
||||
if (0 < pgendTransactionCompareVersion (be, trans)) return;
|
||||
}
|
||||
trans->version ++; /* be sure to update the version !! */
|
||||
trans->version_check = be->version_check;
|
||||
|
||||
/* first, we need to see which splits are in the database
|
||||
* since what is there may not match what we have cached in
|
||||
@ -368,6 +369,17 @@ pgendCopyTransactionToEngine (PGBackend *be, const GUID *trans_guid)
|
||||
do_set_guid=TRUE;
|
||||
engine_data_is_newer = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* save some performance, don't go to the backend if the data is recent. */
|
||||
if (MAX_VERSION_AGE >= be->version_check - trans->version_check)
|
||||
{
|
||||
PINFO ("fresh data, skip check");
|
||||
pgendEnable(be);
|
||||
gnc_engine_resume_events();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* build the sql query to get the transaction */
|
||||
pbuff = be->buff;
|
||||
@ -470,6 +482,9 @@ pgendCopyTransactionToEngine (PGBackend *be, const GUID *trans_guid)
|
||||
i++;
|
||||
} while (result);
|
||||
|
||||
/* set timestamp as 'recent' for this data */
|
||||
trans->version_check = be->version_check;
|
||||
|
||||
/* if engine data was newer, we are done */
|
||||
if (0 <= engine_data_is_newer)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user