diff options
author | John Wiegley <johnw@newartisans.com> | 2007-04-23 04:42:28 +0000 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2008-04-13 03:38:30 -0400 |
commit | be9f18ccfe81acdd2f34b27352f2843235fab69b (patch) | |
tree | 89bb8aea8ac4d367b1c054eeea5d3fd9f7bb197c | |
parent | ece13a8cf10e9afb576139411f450d8b37ec8e65 (diff) | |
download | fork-ledger-be9f18ccfe81acdd2f34b27352f2843235fab69b.tar.gz fork-ledger-be9f18ccfe81acdd2f34b27352f2843235fab69b.tar.bz2 fork-ledger-be9f18ccfe81acdd2f34b27352f2843235fab69b.zip |
Reduced memory consumption of register report.
-rw-r--r-- | debug.h | 4 | ||||
-rw-r--r-- | register.cc | 68 | ||||
-rw-r--r-- | tests/.gitignore | 1 | ||||
-rw-r--r-- | tests/python/.gitignore | 1 | ||||
-rw-r--r-- | tests/python/corelib/.gitignore | 1 | ||||
-rw-r--r-- | tests/python/corelib/numerics/.gitignore | 1 | ||||
-rw-r--r-- | util.cc | 8 | ||||
-rw-r--r-- | value.h | 2 | ||||
-rw-r--r-- | xml.cc | 103 | ||||
-rw-r--r-- | xml.h | 50 | ||||
-rw-r--r-- | xpath.cc | 12 | ||||
-rw-r--r-- | xpath.h | 5 |
12 files changed, 177 insertions, 79 deletions
@@ -70,6 +70,7 @@ void debug_assert(const ledger::string& reason, #include <new> #include <iostream> #include <cstdlib> +#include <cassert> #include <boost/regex.hpp> @@ -108,6 +109,9 @@ bool _debug_active(const char * const cls); #define VALIDATE(x) #endif +extern int new_calls; +extern int new_size; + #if 0 void * operator new(std::size_t) throw (std::bad_alloc); void * operator new[](std::size_t) throw (std::bad_alloc); diff --git a/register.cc b/register.cc index 3e75eb13..311bfda1 100644 --- a/register.cc +++ b/register.cc @@ -3,25 +3,72 @@ namespace ledger { +static void scan_for_transactions(std::ostream& out, const xml::node_t * node) +{ + if (! (node->flags & XML_NODE_IS_PARENT)) + return; + + const xml::parent_node_t * parent = + static_cast<const xml::parent_node_t *>(node); + + for (const xml::node_t * child = parent->children(); + child; + child = child->next) + if (child->name_id == xml::document_t::TRANSACTION) { + const xml::transaction_node_t * xact_node = + dynamic_cast<const xml::transaction_node_t *>(child); + assert(xact_node); + + const transaction_t * xact = xact_node->transaction; + assert(xact); + + std::cout << xact->entry->date() << ' ' + << std::setw(21) << std::left + << abbreviate(xact->entry->payee, 21) << ' ' + << std::setw(21) << std::left + << abbreviate(xact->account->fullname(), 21, + ABBREVIATE, true) << ' ' + << std::setw(12) << std::right + << xact->amount + << std::endl; + } else { + scan_for_transactions(out, child); + } +} + void register_command::print_document(std::ostream& out, xml::document_t * doc) { - value_t nodelist = xml::xpath_t::eval("//transaction", doc); +#if DEBUG_LEVEL >= BETA + std::size_t old_new_size = new_size; +#endif + +#if 1 + scan_for_transactions(out, doc->top); +#else + value_t nodelist; + xml::xpath_t::eval(nodelist, "//transaction", doc); - value_t::sequence_t * xact_list = nodelist.to_sequence(); +#if DEBUG_LEVEL >= BETA + std::cerr << "Memory requested preparing report: " + << (new_size - old_new_size) << std::endl; + old_new_size = new_size; +#endif + + const value_t::sequence_t * xact_list = nodelist.to_sequence(); assert(xact_list); - for (value_t::sequence_t::iterator i = xact_list->begin(); + for (value_t::sequence_t::const_iterator i = xact_list->begin(); i != xact_list->end(); i++) { - xml::node_t * node = (*i).to_xml_node(); + const xml::node_t * node = (*i).to_xml_node(); assert(node); - xml::transaction_node_t * xact_node = - dynamic_cast<xml::transaction_node_t *>(node); + const xml::transaction_node_t * xact_node = + dynamic_cast<const xml::transaction_node_t *>(node); assert(xact_node); - transaction_t * xact = xact_node->transaction; + const transaction_t * xact = xact_node->transaction; assert(xact); std::cout << xact->entry->date() << ' ' @@ -34,6 +81,13 @@ void register_command::print_document(std::ostream& out, << xact->amount << std::endl; } + +#if DEBUG_LEVEL >= BETA + std::cerr << "Memory requested generating report: " + << (new_size - old_new_size) << std::endl; + old_new_size = new_size; +#endif +#endif } } // namespace ledger diff --git a/tests/.gitignore b/tests/.gitignore new file mode 100644 index 00000000..0d20b648 --- /dev/null +++ b/tests/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/tests/python/.gitignore b/tests/python/.gitignore new file mode 100644 index 00000000..0d20b648 --- /dev/null +++ b/tests/python/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/tests/python/corelib/.gitignore b/tests/python/corelib/.gitignore new file mode 100644 index 00000000..0d20b648 --- /dev/null +++ b/tests/python/corelib/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/tests/python/corelib/numerics/.gitignore b/tests/python/corelib/numerics/.gitignore new file mode 100644 index 00000000..0d20b648 --- /dev/null +++ b/tests/python/corelib/numerics/.gitignore @@ -0,0 +1 @@ +*.pyc @@ -72,16 +72,16 @@ string resolve_path(const string& path) } string abbreviate(const string& str, unsigned int width, - elision_style_t elision_style, const bool is_account, - int abbrev_length) + elision_style_t elision_style, const bool is_account, + int abbrev_length) { const unsigned int len = str.length(); if (len <= width) return str; - //assert(width < 4095); + assert(width < 4095); - char buf[4096]; + static char buf[4096]; switch (elision_style) { case TRUNCATE_LEADING: @@ -8,6 +8,8 @@ #include <vector> #include <exception> +#include <boost/shared_ptr.hpp> + namespace ledger { namespace xml { @@ -9,10 +9,24 @@ namespace ledger { namespace xml { -document_t::document_t(node_t * _top, const char ** _builtins, - const int _builtins_size) - : builtins(_builtins), builtins_size(_builtins_size), stub(this), - top(_top ? _top : &stub) { +const std::size_t document_t::ledger_builtins_size = 12; +const char * document_t::ledger_builtins[] = { + "account", + "account-path", + "amount", + "code", + "commodity", + "entries", + "entry", + "journal", + "name", + "note", + "payee", + "transaction" +}; + +document_t::document_t(node_t * _top) + : stub(this), top(_top ? _top : &stub) { TRACE_CTOR(xml::document_t, "node_t *, const char **, const int"); } @@ -50,24 +64,9 @@ int document_t::register_name(const string& name) int document_t::lookup_name_id(const string& name) const { - if (builtins) { - int first = 0; - int last = builtins_size; - while (first <= last) { - int mid = (first + last) / 2; // compute mid point. - - int result; - if ((result = (int)name[0] - (int)builtins[mid][0]) == 0) - result = std::strcmp(name.c_str(), builtins[mid]); - - if (result > 0) - first = mid + 1; // repeat search in top half. - else if (result < 0) - last = mid - 1; // repeat search in bottom half. - else - return mid; - } - } + int id; + if ((id = lookup_builtin_id(name)) != -1) + return id; DEBUG_PRINT("xml.lookup", this << " Finding name: " << name); @@ -78,6 +77,29 @@ int document_t::lookup_name_id(const string& name) const return -1; } +int document_t::lookup_builtin_id(const string& name) +{ + int first = 0; + int last = (int)ledger_builtins_size; + + while (first <= last) { + int mid = (first + last) / 2; // compute mid point. + + int result; + if ((result = (int)name[0] - (int)ledger_builtins[mid][0]) == 0) + result = std::strcmp(name.c_str(), ledger_builtins[mid]); + + if (result > 0) + first = mid + 1; // repeat search in top half. + else if (result < 0) + last = mid - 1; // repeat search in bottom half. + else + return mid + 10; + } + + return -1; +} + const char * document_t::lookup_name(int id) const { if (id < 1000) { @@ -92,8 +114,7 @@ const char * document_t::lookup_name(int id) const return "ALL"; default: assert(id >= 10); - assert(builtins); - return builtins[id - 10]; + return ledger_builtins[id - 10]; } } else { return names[id - 1000].c_str(); @@ -343,10 +364,9 @@ bool parser_t::test(std::istream& in) const return true; } -document_t * parser_t::parse(std::istream& in, const char ** builtins, - const int builtins_size) +document_t * parser_t::parse(std::istream& in) { - std::auto_ptr<document_t> doc(new document_t(NULL, builtins, builtins_size)); + std::auto_ptr<document_t> doc(new document_t); document = doc.get(); @@ -410,12 +430,13 @@ node_t * transaction_node_t::children() const node_t * transaction_node_t::lookup_child(int _name_id) const { - if (_name_id == entry_node_t::payee_id) { + switch (_name_id) { + case document_t::PAYEE: payee_virtual_node = new terminal_node_t(document); payee_virtual_node->set_text(transaction->entry->payee); return payee_virtual_node; - } - else if (_name_id == journal_node_t::account_id) { + + case document_t::ACCOUNT: return new account_node_t(document, transaction->account, const_cast<transaction_node_t *>(this)); } @@ -427,9 +448,6 @@ value_t transaction_node_t::to_value() const return transaction->amount; } -int entry_node_t::code_id = -1; -int entry_node_t::payee_id = -1; - node_t * entry_node_t::children() const { if (! _children) @@ -443,19 +461,20 @@ node_t * entry_node_t::children() const node_t * entry_node_t::lookup_child(int _name_id) const { - if (_name_id == entry_node_t::code_id) { + switch (_name_id) { + case document_t::CODE: // jww (2007-04-20): I have to save this and then delete it later terminal_node_t * code_node = new terminal_node_t(document, const_cast<entry_node_t *>(this)); - code_node->set_name("code"); + code_node->set_name(document_t::CODE); code_node->set_text(entry->code); return code_node; - } - else if (_name_id == entry_node_t::payee_id) { + + case document_t::PAYEE: // jww (2007-04-20): I have to save this and then delete it later terminal_node_t * payee_node = new terminal_node_t(document, const_cast<entry_node_t *>(this)); - payee_node->set_name("payee"); + payee_node->set_name(document_t::PAYEE); payee_node->set_text(entry->payee); return payee_node; } @@ -468,14 +487,14 @@ node_t * account_node_t::children() const if (! account->name.empty()) { terminal_node_t * name_node = new terminal_node_t(document, const_cast<account_node_t *>(this)); - name_node->set_name("name"); + name_node->set_name(document_t::NAME); name_node->set_text(account->name); } if (! account->note.empty()) { terminal_node_t * note_node = new terminal_node_t(document, const_cast<account_node_t *>(this)); - note_node->set_name("note"); + note_node->set_name(document_t::NOTE); note_node->set_text(account->note); } @@ -487,8 +506,6 @@ node_t * account_node_t::children() const return parent_node_t::children(); } -int journal_node_t::account_id = -1; - node_t * journal_node_t::children() const { if (! _children) { @@ -499,7 +516,7 @@ node_t * journal_node_t::children() const parent_node_t * entries = new parent_node_t(document, const_cast<journal_node_t *>(this)); - entries->set_name("entries"); + entries->set_name(document_t::ENTRIES); for (entries_list::iterator i = journal->entries.begin(); i != journal->entries.end(); @@ -182,9 +182,26 @@ private: class document_t { - const char ** builtins; - const int builtins_size; + static const char * ledger_builtins[]; + static const std::size_t ledger_builtins_size; +public: + enum ledger_builtins_t { + ACCOUNT = 10, + ACCOUNT_PATH, + AMOUNT, + CODE, + COMMODITY, + ENTRIES, + ENTRY, + JOURNAL, + NAME, + NOTE, + PAYEE, + TRANSACTION + }; + +private: typedef std::vector<string> names_array; names_array names; @@ -205,14 +222,14 @@ class document_t CURRENT, PARENT, ROOT, ALL }; - document_t(node_t * _top = NULL, const char ** _builtins = NULL, - const int _builtins_size = 0); + document_t(node_t * _top = NULL); ~document_t(); void set_top(node_t * _top); int register_name(const string& name); int lookup_name_id(const string& name) const; + static int lookup_builtin_id(const string& name); const char * lookup_name(int id) const; void write(std::ostream& out) const; @@ -237,9 +254,7 @@ class parser_t virtual ~parser_t() {} virtual bool test(std::istream& in) const; - virtual document_t * parse(std::istream& in, - const char ** builtins = NULL, - const int builtins_size = 0); + virtual document_t * parse(std::istream& in); }; class parse_error : public error { @@ -262,7 +277,7 @@ public: parent_node_t * _parent = NULL) : parent_node_t(_document, _parent), commodity(_commodity) { TRACE_CTOR(commodity_node_t, "document_t *, commodity_t *, parent_node_t *"); - set_name("commodity"); + set_name(document_t::COMMODITY); } virtual ~commodity_node_t() { TRACE_DTOR(commodity_node_t); @@ -281,7 +296,7 @@ public: parent_node_t * _parent = NULL) : parent_node_t(_document, _parent), amount(_amount) { TRACE_CTOR(amount_node_t, "document_t *, amount_t *, parent_node_t *"); - set_name("amount"); + set_name(document_t::AMOUNT); } virtual ~amount_node_t() { TRACE_DTOR(amount_node_t); @@ -307,7 +322,7 @@ public: : parent_node_t(_document, _parent), payee_virtual_node(NULL), transaction(_transaction) { TRACE_CTOR(transaction_node_t, "document_t *, transaction_t *, parent_node_t *"); - set_name("transaction"); + set_name(document_t::TRANSACTION); } virtual ~transaction_node_t() { TRACE_DTOR(transaction_node_t); @@ -322,8 +337,6 @@ public: class entry_node_t : public parent_node_t { - static int code_id; - static int payee_id; entry_t * entry; public: @@ -331,11 +344,7 @@ public: parent_node_t * _parent = NULL) : parent_node_t(_document, _parent), entry(_entry) { TRACE_CTOR(entry_node_t, "document_t *, entry_t *, parent_node_t *"); - set_name("entry"); - if (code_id == -1) - payee_id = document->register_name("code"); - if (payee_id == -1) - payee_id = document->register_name("payee"); + set_name(document_t::ENTRY); } virtual ~entry_node_t() { TRACE_DTOR(entry_node_t); @@ -356,7 +365,7 @@ public: parent_node_t * _parent = NULL) : parent_node_t(_document, _parent), account(_account) { TRACE_CTOR(account_node_t, "document_t *, account_t *, parent_node_t *"); - set_name("account"); + set_name(document_t::ACCOUNT); } virtual ~account_node_t() { TRACE_DTOR(account_node_t); @@ -367,7 +376,6 @@ public: class journal_node_t : public parent_node_t { - static int account_id; journal_t * journal; public: @@ -375,9 +383,7 @@ public: parent_node_t * _parent = NULL) : parent_node_t(_document, _parent), journal(_journal) { TRACE_CTOR(journal_node_t, "document_t *, journal_t *, parent_node_t *"); - set_name("journal"); - if (account_id == -1) - account_id = document->register_name("account"); + set_name(document_t::JOURNAL); } virtual ~journal_node_t() { TRACE_DTOR(journal_node_t); @@ -655,10 +655,16 @@ xpath_t::parse_value_term(std::istream& in, unsigned short tflags) const #endif string ident = tok.value.to_string(); + int id = -1; if (std::isdigit(ident[0])) { node.reset(new op_t(op_t::ARG_INDEX)); node->arg_index = std::atol(ident.c_str()); - } else { + } + else if ((id = document_t::lookup_builtin_id(ident)) != -1) { + node.reset(new op_t(op_t::NODE_ID)); + node->name_id = id; + } + else { node.reset(new op_t(op_t::NODE_NAME)); node->name = new string(ident); } @@ -1312,7 +1318,7 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope, // First, look up the symbol as a node name within the current // context. If any exist, then return the set of names. - value_t::sequence_t * nodes = new value_t::sequence_t; + std::auto_ptr<value_t::sequence_t> nodes(new value_t::sequence_t); if (ptr->flags & XML_NODE_IS_PARENT) { parent_node_t * parent = static_cast<parent_node_t *>(ptr); @@ -1325,7 +1331,7 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope, nodes->push_back(node); } } - return wrap_value(nodes)->acquire(); + return wrap_value(nodes.release())->acquire(); } else { assert(ptr); int id = ptr->document->lookup_name_id(*name); @@ -734,6 +734,11 @@ public: return temp; } + static void eval(value_t& result, const string& _expr, + document_t * document, scope_t * scope = NULL) { + xpath_t temp(_expr); + temp.calc(result, document->top, scope); + } static value_t eval(const string& _expr, document_t * document, scope_t * scope = NULL) { xpath_t temp(_expr); |