sorting optimization

This commit is contained in:
John Wiegley 2004-09-25 06:50:18 -04:00
parent 2eb2b1428b
commit b1aa1344ae
3 changed files with 84 additions and 20 deletions

View file

@ -1050,14 +1050,14 @@ beginning of the ledger. For food spending just this month
(September), use:
@example
ledger -d sep balance expenses:food
ledger -p sep balance expenses:food
@end example
Or maybe I want to see all of my assets, in which case the -s (show
sub-accounts) option comes in handy:
@example
ledger balance -s
ledger -s balance
@end example
To exclude a particular account, use a regular expression with a
@ -1068,13 +1068,20 @@ food spending:
ledger balance expenses -food
@end example
If you want to show all accounts but for one account, remember to use
``--'' to separate the exclusion pattern from the options list:
A query like the following will show the largest expense categories
since a given date:
@example
ledger balance -- -equity
ledger -b 2003/10 -s -S -AT -d "T>1000" bal ^expenses -internet
@end example
From left to right the options used mean: Show entries since October,
2003; showa all sub-accounts; sort in verse order by the absolute
value of the total; display only accounts with a total value greater
than 1000 units (of whichever commodities the account contains); and
report the balance for all expenses, except for those matching
``internet''.
@node File format, , Typical queries, Running Ledger
@section File format

46
walk.cc
View file

@ -9,6 +9,28 @@ std::list<void **> transactions_xdata_ptrs;
std::list<account_xdata_t> accounts_xdata;
std::list<void **> accounts_xdata_ptrs;
template <>
bool compare_items<transaction_t>::operator()(const transaction_t * left,
const transaction_t * right)
{
assert(left);
assert(right);
transaction_xdata_t& lxdata(transaction_xdata(*left));
if (! (lxdata.dflags & TRANSACTION_SORT_CALC)) {
sort_order->compute(lxdata.sort_value, details_t(*left));
lxdata.dflags |= TRANSACTION_SORT_CALC;
}
transaction_xdata_t& rxdata(transaction_xdata(*right));
if (! (rxdata.dflags & TRANSACTION_SORT_CALC)) {
sort_order->compute(rxdata.sort_value, details_t(*right));
rxdata.dflags |= TRANSACTION_SORT_CALC;
}
return lxdata.sort_value < rxdata.sort_value;
}
void sort_transactions::flush()
{
std::stable_sort(transactions.begin(), transactions.end(),
@ -123,7 +145,7 @@ static void handle_value(const value_t& value,
}
}
void determine_amount(value_t& result, balance_pair_t& bal_pair)
static inline void determine_amount(value_t& result, balance_pair_t& bal_pair)
{
account_xdata_t xdata;
xdata.value = bal_pair;
@ -319,6 +341,28 @@ void clear_transactions_xdata()
**i = NULL;
}
template <>
bool compare_items<account_t>::operator()(const account_t * left,
const account_t * right)
{
assert(left);
assert(right);
account_xdata_t& lxdata(account_xdata(*left));
if (! (lxdata.dflags & ACCOUNT_SORT_CALC)) {
sort_order->compute(lxdata.sort_value, details_t(*left));
lxdata.dflags |= ACCOUNT_SORT_CALC;
}
account_xdata_t& rxdata(account_xdata(*right));
if (! (rxdata.dflags & ACCOUNT_SORT_CALC)) {
sort_order->compute(rxdata.sort_value, details_t(*right));
rxdata.dflags |= ACCOUNT_SORT_CALC;
}
return lxdata.sort_value < rxdata.sort_value;
}
void sum_accounts(account_t& account)
{
for (accounts_map::iterator i = account.accounts.begin();

41
walk.h
View file

@ -38,28 +38,37 @@ struct item_handler {
template <typename T>
class compare_items {
value_t left_result;
value_t right_result;
const value_expr_t * sort_order;
public:
compare_items(const value_expr_t * _sort_order)
: sort_order(_sort_order) {
assert(sort_order);
}
bool operator()(const T * left, const T * right) {
assert(left);
assert(right);
sort_order->compute(left_result, details_t(*left));
sort_order->compute(right_result, details_t(*right));
return left_result < right_result;
}
bool operator()(const T * left, const T * right);
};
template <typename T>
bool compare_items<T>::operator()(const T * left, const T * right)
{
assert(left);
assert(right);
value_t left_result;
value_t right_result;
sort_order->compute(left_result, details_t(*left));
sort_order->compute(right_result, details_t(*right));
return left_result < right_result;
}
template <>
bool compare_items<transaction_t>::operator()(const transaction_t * left,
const transaction_t * right);
template <>
bool compare_items<account_t>::operator()(const account_t * left,
const account_t * right);
//////////////////////////////////////////////////////////////////////
//
// Transaction handlers
@ -69,10 +78,12 @@ class compare_items {
#define TRANSACTION_TO_DISPLAY 0x0002
#define TRANSACTION_DISPLAYED 0x0004
#define TRANSACTION_NO_TOTAL 0x0008
#define TRANSACTION_SORT_CALC 0x0010
struct transaction_xdata_t
{
value_t total;
value_t sort_value;
unsigned int index;
unsigned short dflags;
@ -400,11 +411,13 @@ class related_transactions : public item_handler<transaction_t>
#define ACCOUNT_TO_DISPLAY 0x1
#define ACCOUNT_DISPLAYED 0x2
#define ACCOUNT_SORT_CALC 0x4
struct account_xdata_t
{
value_t value;
value_t total;
value_t sort_value;
unsigned int count; // transactions counted toward total
unsigned int subcount;
unsigned short dflags;