warning about timespec; more transaction/split sorting.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@1156 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Linas Vepstas 1998-09-13 07:22:45 +00:00
parent 2020f2ab82
commit a1dadd6c08
2 changed files with 96 additions and 29 deletions

View File

@ -12,8 +12,15 @@
* Copyright (c) 1998 Linas Vepstas
*/
#include <limits.h>
#include "config.h"
#include "Account.h"
#include "AccountP.h"
#include "Query.h"
#include "Transaction.h"
#include "TransactionP.h"
#include "util.h"
struct _Query {
@ -22,6 +29,10 @@ struct _Query {
/* maximum number of splits to return */
int max_num_splits;
/* the earliest, and the latest transaction dates to include */
Timespec earliest;
Timespec latest;
char changed; /* flag, has the query changed? */
Split **split_list;
};
@ -47,7 +58,14 @@ xaccInitQuery (Query *q)
q->acc_list = NULL;
q->split_list = NULL;
q->changed = 0;
q->max_num_splits = 2<<30;
q->max_num_splits = INT_MAX ;
q->earliest.tv_sec = 0;
q->earliest.tv_nsec = 0;
/* q->latest.tv_sec = ULONG_MAX; */
q->latest.tv_sec = LONG_MAX;
q->latest.tv_nsec = 0;
}
/* ================================================== */
@ -145,7 +163,7 @@ xaccQuerySetMaxSplits (Query *q, int max)
/* ================================================== */
static void
SortSplits (Query *q)
SortSplits (Query *q, Split **slist)
{
}
@ -155,13 +173,15 @@ SortSplits (Query *q)
Split **
xaccQueryGetSplits (Query *q)
{
int i=0, j=0;
int nlist, nstart, nret, nsplits;
int i=0, j=0, k=0;
int nstart, nret, nsplits;
Split *s, **slist;
Account *acc;
if (!q) return NULL;
/* tmp hack alert */
q->changed = 1;
/* if not changed then don't recompute cache */
if (!(q->changed)) return q->split_list;
q->changed = 0;
@ -169,41 +189,83 @@ xaccQueryGetSplits (Query *q)
if (q->split_list) _free (q->split_list);
q->split_list = NULL;
/* count the number of splits in each account */
/* count up the number of splits we'll have to deal with.
* Try to limit the CPU pain by trimming out stuff that's
* too early and too late now.
*/
nsplits = 0;
if (q->acc_list) {
i=0; acc = q->acc_list[0];
while (acc) {
nsplits += xaccAccountGetNumSplits (acc);
/* now go through the splits */
j=0; s = acc->splits[0];
while (s) {
if (s->parent->date_posted.tv_sec >= q->earliest.tv_sec) {
nsplits ++;
}
if (s->parent->date_posted.tv_sec > q->latest.tv_sec) {
break;
}
j++; s = acc->splits[j];
}
i++; acc = q->acc_list[i];
}
}
/* hack alert */
slist = xaccAccountGetSplitList (q->acc_list[0]);
if (!slist) return NULL;
/* OK, now get some storage ... concatenate all of the accounts in */
slist = (Split **) malloc ((nsplits+1) * sizeof (Split *));
i=0; s = slist[0];
while (s) { i++; s = slist [i]; }
nlist = i;
/* make sure we don't return too many splits */
nret = nlist;
if (nret > q->max_num_splits) nret = q->max_num_splits;
q->split_list = (Split **) malloc ((nret+1) * sizeof (Split *));
/* return only the last few splits */
nstart = nlist - nret;
if (0 > nstart) nstart = 0;
k=0;
if (q->acc_list) {
i=0; acc = q->acc_list[0];
while (acc) {
/* copy over */
i=nstart; s = slist[i];
j = 0;
while (s) {
q->split_list [j] = s;
j++; i++; s = slist [i];
/* now go through the splits */
j=0; s = acc->splits[0];
while (s) {
if (s->parent->date_posted.tv_sec >= q->earliest.tv_sec) {
slist[k] = s; k++;
}
if (s->parent->date_posted.tv_sec > q->latest.tv_sec) {
break;
}
j++; s = acc->splits[j];
}
i++; acc = q->acc_list[i];
}
}
slist[k] = NULL;
/* sort them ... */
SortSplits (q, slist);
/* make sure we don't return too many splits */
nret = nsplits;
if (nret > q->max_num_splits) {
nret = q->max_num_splits;
q->split_list = (Split **) malloc ((nret+1) * sizeof (Split *));
/* return only the last few splits */
nstart = nsplits - nret;
if (0 > nstart) nstart = 0;
/* copy over */
i=nstart; s = slist[i];
j = 0;
while (s) {
q->split_list [j] = s;
j++; i++; s = slist [i];
}
q->split_list [j] = NULL;
/* cleanup memory */
free (slist);
} else {
/* avoid excess mallocs, copies, etc. */
q->split_list = slist;
}
q->split_list [j] = NULL;
return q->split_list;
}

View File

@ -50,6 +50,12 @@
#include "config.h"
#include "Transaction.h" /* for typedefs */
/* Major-League Hack Alert -- bit Y2K problem: struct timespec seems
* to have declared tv_sec to be a signed long, not an unsigned long.
* This majorly hoses in the year 2004, as date comparisons suddenly
* fail because the seconds value will go negative.
*/
typedef struct timespec Timespec;
/** STRUCTS *********************************************************/
/*
@ -69,7 +75,6 @@
* A "split" is more commonly refered to as a "entry" in a "transaction".
*/
typedef struct timespec Timespec;
struct _split
{