mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
changes to defer date sorting until the commit phase. Also, changes to make
re-ordering due to a date change a tad more efficient. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@1247 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
565e304965
commit
49ab81302d
@ -222,6 +222,7 @@ xaccAccountInsertSplit ( Account *acc, Split *split )
|
|||||||
{
|
{
|
||||||
int i,j;
|
int i,j;
|
||||||
Split **oldsplits;
|
Split **oldsplits;
|
||||||
|
Account *oldacc;
|
||||||
|
|
||||||
if (!acc) return;
|
if (!acc) return;
|
||||||
if (!split) return;
|
if (!split) return;
|
||||||
@ -254,39 +255,73 @@ disable for now till we figure out what the right thing is.
|
|||||||
* there first. We don't want to ever leave the system
|
* there first. We don't want to ever leave the system
|
||||||
* in an inconsistent state.
|
* in an inconsistent state.
|
||||||
*/
|
*/
|
||||||
|
oldacc = split->acc;
|
||||||
if (split->acc) xaccAccountRemoveSplit (split->acc, split);
|
if (split->acc) xaccAccountRemoveSplit (split->acc, split);
|
||||||
split->acc = acc;
|
split->acc = acc;
|
||||||
|
|
||||||
oldsplits = acc->splits;
|
/* enlarge the size of the split array to accomadate the new split,
|
||||||
acc->numSplits ++;
|
* and copy all the splits over to the new array.
|
||||||
acc->splits = (Split **)_malloc(((acc->numSplits) + 1) * sizeof(Split *));
|
* If the old and new accounts are the same account, then we
|
||||||
|
* are just shuffling around the split, resumably due to a
|
||||||
/* Find the insertion point */
|
* date reordering. In this case, most of the malloc/copy/free bit
|
||||||
/* to get realy fancy, could use binary search. */
|
* can be avoided.
|
||||||
for(i = 0; i < (acc->numSplits - 1);) {
|
*/
|
||||||
if(xaccSplitOrder(&(oldsplits[i]), &split) > 0) {
|
if (oldacc != acc) {
|
||||||
break;
|
oldsplits = acc->splits;
|
||||||
} else {
|
acc->numSplits ++;
|
||||||
acc->splits[i] = oldsplits[i];
|
|
||||||
}
|
acc->splits = (Split **)_malloc(((acc->numSplits) + 1) * sizeof(Split *));
|
||||||
i++; /* Don't put this in the loop guard! It'll go too far. */
|
|
||||||
|
/* Find the insertion point */
|
||||||
|
/* to get realy fancy, could use binary search. */
|
||||||
|
for(i = 0; i < (acc->numSplits - 1);) {
|
||||||
|
if(xaccSplitOrder(&(oldsplits[i]), &split) > 0) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
acc->splits[i] = oldsplits[i];
|
||||||
|
}
|
||||||
|
i++; /* Don't put this in the loop guard! It'll go too far. */
|
||||||
|
}
|
||||||
|
/* Insertion point is now i */
|
||||||
|
|
||||||
|
//fprintf(stderr, "Insertion position is: %d\n", i);
|
||||||
|
|
||||||
|
/* Move all the other splits down (this could be done faster with memmove)*/
|
||||||
|
for( j = acc->numSplits; j > i; j--) {
|
||||||
|
acc->splits[j] = oldsplits[j - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now insert the new split */
|
||||||
|
acc->splits[i] = split;
|
||||||
|
|
||||||
|
/* make sure the array is NULL terminated */
|
||||||
|
acc->splits[acc->numSplits] = NULL;
|
||||||
|
|
||||||
|
_free(oldsplits);
|
||||||
|
} else {
|
||||||
|
acc->numSplits ++;
|
||||||
|
|
||||||
|
/* Find the insertion point */
|
||||||
|
/* to get realy fancy, could use binary search. */
|
||||||
|
for(i = 0; i < (acc->numSplits - 1);) {
|
||||||
|
if(xaccSplitOrder(&(acc->splits[i]), &split) > 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++; /* Don't put this in the loop guard! It'll go too far. */
|
||||||
|
}
|
||||||
|
/* Insertion point is now i */
|
||||||
|
|
||||||
|
/* Move all the other splits down (this could be done faster with memmove)*/
|
||||||
|
for( j = acc->numSplits; j > i; j--) {
|
||||||
|
acc->splits[j] = acc->splits[j - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now insert the new split */
|
||||||
|
acc->splits[i] = split;
|
||||||
|
|
||||||
|
/* make sure the array is NULL terminated */
|
||||||
|
acc->splits[acc->numSplits] = NULL;
|
||||||
}
|
}
|
||||||
/* Insertion point is now i */
|
|
||||||
|
|
||||||
//fprintf(stderr, "Insertion position is: %d\n", i);
|
|
||||||
|
|
||||||
/* Move all the other splits down (this could be done faster with memmove)*/
|
|
||||||
for( j = acc->numSplits; j > i; j--) {
|
|
||||||
acc->splits[j] = oldsplits[j - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now insert the new split */
|
|
||||||
acc->splits[i] = split;
|
|
||||||
|
|
||||||
/* make sure the array is NULL terminated */
|
|
||||||
acc->splits[acc->numSplits] = NULL;
|
|
||||||
|
|
||||||
_free(oldsplits);
|
|
||||||
|
|
||||||
xaccAccountRecomputeBalance (acc);
|
xaccAccountRecomputeBalance (acc);
|
||||||
}
|
}
|
||||||
@ -485,7 +520,6 @@ xaccCheckDateOrder (Account * acc, Split *split )
|
|||||||
|
|
||||||
/* take care of re-ordering, if necessary */
|
/* take care of re-ordering, if necessary */
|
||||||
if( outOfOrder ) {
|
if( outOfOrder ) {
|
||||||
xaccAccountRemoveSplit( acc, split );
|
|
||||||
xaccAccountInsertSplit( acc, split );
|
xaccAccountInsertSplit( acc, split );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -414,6 +414,11 @@ xaccFreeTransaction( Transaction *trans )
|
|||||||
|
|
||||||
trans->open = 0;
|
trans->open = 0;
|
||||||
|
|
||||||
|
if (trans->orig) {
|
||||||
|
xaccFreeTransaction (trans->orig);
|
||||||
|
trans->orig = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
_free(trans);
|
_free(trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -767,12 +772,6 @@ xaccTransCommitEdit (Transaction *trans)
|
|||||||
if (!trans) return;
|
if (!trans) return;
|
||||||
CHECK_OPEN (trans);
|
CHECK_OPEN (trans);
|
||||||
|
|
||||||
/* get rid of the copy we made. We won't be rolling back,
|
|
||||||
* so we don't need i any more.
|
|
||||||
*/
|
|
||||||
xaccFreeTransaction (trans->orig);
|
|
||||||
trans->orig = NULL;
|
|
||||||
|
|
||||||
/* At this point, we check to see if we have a valid transaction.
|
/* At this point, we check to see if we have a valid transaction.
|
||||||
* As a result of editing, we could end up with a transaction that
|
* As a result of editing, we could end up with a transaction that
|
||||||
* has no splits in it, in which case we delete the transaction and
|
* has no splits in it, in which case we delete the transaction and
|
||||||
@ -807,17 +806,26 @@ xaccTransCommitEdit (Transaction *trans)
|
|||||||
trans->open &= ~DEFER_REBALANCE;
|
trans->open &= ~DEFER_REBALANCE;
|
||||||
xaccTransRebalance (trans);
|
xaccTransRebalance (trans);
|
||||||
|
|
||||||
/* um, theoritically, it is impossible for splits
|
/* check to see if the date has changed. We use the date as the sort key. */
|
||||||
* to get inserted out of order. But we'll get paranoid,
|
if ((trans->orig->date_entered.tv_sec != trans->date_entered.tv_sec) ||
|
||||||
* and check anyway, at the loss of some performance.
|
(trans->orig->date_posted.tv_sec != trans->date_posted.tv_sec))
|
||||||
*/
|
{
|
||||||
i=0;
|
|
||||||
split = trans->splits[i];
|
/* since the date has changed, we need to be careful to
|
||||||
while (split) {
|
* make sure all associated splits are in proper order
|
||||||
acc = split ->acc;
|
* in thier accounts. The easiest way of ensuring this
|
||||||
xaccCheckDateOrder(acc, trans->splits[i]);
|
* is to remove and reinsert every split. The reinsertion
|
||||||
i++;
|
* process will place the split in the correct date-sorted
|
||||||
|
* order.
|
||||||
|
*/
|
||||||
|
i=0;
|
||||||
split = trans->splits[i];
|
split = trans->splits[i];
|
||||||
|
while (split) {
|
||||||
|
acc = split ->acc;
|
||||||
|
xaccCheckDateOrder(acc, trans->splits[i]);
|
||||||
|
i++;
|
||||||
|
split = trans->splits[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
i=0;
|
i=0;
|
||||||
@ -831,6 +839,12 @@ xaccTransCommitEdit (Transaction *trans)
|
|||||||
|
|
||||||
trans->open = 0;
|
trans->open = 0;
|
||||||
xaccTransWriteLog (trans, 'C');
|
xaccTransWriteLog (trans, 'C');
|
||||||
|
|
||||||
|
/* get rid of the copy we made. We won't be rolling back,
|
||||||
|
* so we don't need it any more. */
|
||||||
|
xaccFreeTransaction (trans->orig);
|
||||||
|
trans->orig = NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1203,40 +1217,22 @@ xaccCountTransactions (Transaction **tarray)
|
|||||||
void
|
void
|
||||||
xaccTransSetDateSecs (Transaction *trans, time_t secs)
|
xaccTransSetDateSecs (Transaction *trans, time_t secs)
|
||||||
{
|
{
|
||||||
Split *split;
|
|
||||||
Account *acc;
|
|
||||||
int i=0;
|
|
||||||
|
|
||||||
if (!trans) return;
|
if (!trans) return;
|
||||||
CHECK_OPEN (trans);
|
CHECK_OPEN (trans);
|
||||||
|
|
||||||
/* hack alert -- for right now, keep the posted and the entered
|
/* hack alert -- for right now, keep the posted and the entered
|
||||||
* dates in sync. Later, we'll have to split these up. */
|
* dates in sync. Later, we'll have to split these up. */
|
||||||
|
|
||||||
|
|
||||||
trans->date_entered.tv_sec = secs;
|
trans->date_entered.tv_sec = secs;
|
||||||
trans->date_posted.tv_sec = secs;
|
trans->date_posted.tv_sec = secs;
|
||||||
|
|
||||||
/* since the date has changed, we need to be careful to
|
/* Because the date has changed, we need to make sure that each of the
|
||||||
* make sure all associated splits are in proper order
|
* splits is properly ordered in each of thier accounts. We could do that
|
||||||
* in thier accounts. The easiest way of ensuring this
|
* here, simply by reinserting each split into its account. However, in
|
||||||
* is to remove and reinsert every split. The reinsertion
|
* some ways this is bad behaviour, and it seems much better/nicer to defer
|
||||||
* process will place the split in the correct date-sorted
|
* that until the commit phase, i.e. until the user has called the
|
||||||
* order.
|
* xaccTransCommitEdit() routine. So, for now, we are done.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
assert (trans->splits);
|
|
||||||
|
|
||||||
i=0;
|
|
||||||
split = trans->splits[i];
|
|
||||||
while (split) {
|
|
||||||
acc = split->acc;
|
|
||||||
xaccAccountRemoveSplit (acc, split);
|
|
||||||
xaccAccountInsertSplit (acc, split);
|
|
||||||
|
|
||||||
i++;
|
|
||||||
split = trans->splits[i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user