summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2012-03-05 17:50:17 -0600
committerJohn Wiegley <johnw@newartisans.com>2012-03-05 17:50:17 -0600
commit97dbf379d5e44c80c748483a688502b1cec8f075 (patch)
tree262c54e08cd86cbcdcf9f87de261fc1c56305980
parentff9cf572fe5054f2e5c5d7ab4e68d63011e4a38a (diff)
downloadfork-ledger-97dbf379d5e44c80c748483a688502b1cec8f075.tar.gz
fork-ledger-97dbf379d5e44c80c748483a688502b1cec8f075.tar.bz2
fork-ledger-97dbf379d5e44c80c748483a688502b1cec8f075.zip
Rewrote the way annotated commodities are managed
The new scheme should be much more efficient, and allows for future growth of what annotations may appear on a commodity.
-rw-r--r--src/commodity.h9
-rw-r--r--src/pool.cc161
-rw-r--r--src/pool.h49
-rw-r--r--src/py_commodity.cc11
-rw-r--r--src/textual.cc11
5 files changed, 110 insertions, 131 deletions
diff --git a/src/commodity.h b/src/commodity.h
index 524daaab..7934f1ad 100644
--- a/src/commodity.h
+++ b/src/commodity.h
@@ -164,7 +164,6 @@ protected:
commodity_pool_t * parent_;
optional<string> qualified_symbol;
- optional<string> mapping_key_;
bool annotated;
explicit commodity_t(commodity_pool_t * _parent,
@@ -218,13 +217,6 @@ public:
return qualified_symbol ? *qualified_symbol : base_symbol();
}
- string mapping_key() const {
- if (mapping_key_)
- return *mapping_key_;
- else
- return base_symbol();
- }
-
optional<std::size_t> graph_index() const {;
return base->graph_index;
}
@@ -325,7 +317,6 @@ private:
ar & base;
ar & parent_;
ar & qualified_symbol;
- ar & mapping_key_;
ar & annotated;
}
#endif // HAVE_BOOST_SERIALIZATION
diff --git a/src/pool.cc b/src/pool.cc
index 2c094d47..ca50db2c 100644
--- a/src/pool.cc
+++ b/src/pool.cc
@@ -56,7 +56,7 @@ commodity_t * commodity_pool_t::create(const string& symbol)
{
shared_ptr<commodity_t::base_t>
base_commodity(new commodity_t::base_t(symbol));
- std::auto_ptr<commodity_t> commodity(new commodity_t(this, base_commodity));
+ shared_ptr<commodity_t> commodity(new commodity_t(this, base_commodity));
DEBUG("pool.commodities", "Creating base commodity " << symbol);
@@ -71,13 +71,23 @@ commodity_t * commodity_pool_t::create(const string& symbol)
"Creating commodity '" << commodity->symbol() << "'");
std::pair<commodities_map::iterator, bool> result
- = commodities.insert(commodities_map::value_type(commodity->mapping_key(),
- commodity.get()));
+ = commodities.insert(commodities_map::value_type
+ (commodity->base_symbol(), commodity));
assert(result.second);
commodity_price_history.add_commodity(*commodity.get());
- return commodity.release();
+ return commodity.get();
+}
+
+commodity_t * commodity_pool_t::find(const string& symbol)
+{
+ DEBUG("pool.commodities", "Find commodity " << symbol);
+
+ commodities_map::const_iterator i = commodities.find(symbol);
+ if (i != commodities.end())
+ return (*i).second.get();
+ return NULL;
}
commodity_t * commodity_pool_t::find_or_create(const string& symbol)
@@ -88,97 +98,103 @@ commodity_t * commodity_pool_t::find_or_create(const string& symbol)
return create(symbol);
}
-commodity_t * commodity_pool_t::find(const string& symbol)
+commodity_t * commodity_pool_t::alias(const string& name, commodity_t& referent)
{
- DEBUG("pool.commodities", "Find commodity " << symbol);
+ commodities_map::const_iterator i = commodities.find(referent.symbol());
+ assert(i != commodities.end());
- commodities_map::const_iterator i = commodities.find(symbol);
- if (i != commodities.end())
- return (*i).second;
- return NULL;
+ std::pair<commodities_map::iterator, bool> result
+ = commodities.insert(commodities_map::value_type(name, (*i).second));
+ assert(result.second);
+
+ return (*result.first).second.get();
}
commodity_t *
commodity_pool_t::create(const string& symbol, const annotation_t& details)
{
- commodity_t * new_comm = create(symbol);
- if (! new_comm)
- return NULL;
+ DEBUG("pool.commodities", "commodity_pool_t::create[ann] "
+ << "symbol " << symbol << std::endl << details);
if (details)
- return find_or_create(*new_comm, details);
+ return create(*find_or_create(symbol), details);
else
- return new_comm;
+ return create(symbol);
}
-string commodity_pool_t::make_qualified_name(const commodity_t& comm,
- const annotation_t& details)
+commodity_t *
+commodity_pool_t::find(const string& symbol, const annotation_t& details)
{
- assert(details);
-
- if (details.price && details.price->sign() < 0)
- throw_(amount_error, _("A commodity's price may not be negative"));
+ DEBUG("pool.commodities", "commodity_pool_t::find[ann] "
+ << "symbol " << symbol << std::endl << details);
- std::ostringstream name;
- comm.print(name);
- details.print(name, comm.pool().keep_base);
-
-#if defined(DEBUG_ON)
- if (comm.qualified_symbol)
- DEBUG("pool.commodities", "make_qualified_name for "
- << *comm.qualified_symbol << std::endl << details);
-#endif
- DEBUG("pool.commodities", "qualified_name is " << name.str());
-
- return name.str();
+ if (details) {
+ annotated_commodities_map::const_iterator i =
+ annotated_commodities.find
+ (annotated_commodities_map::key_type(symbol, details));
+ if (i != annotated_commodities.end()) {
+ DEBUG("pool.commodities", "commodity_pool_t::find[ann] found "
+ << "symbol " << (*i).second->symbol() << std::endl
+ << as_annotated_commodity(*(*i).second.get()).details);
+ return (*i).second.get();
+ } else {
+ return NULL;
+ }
+ } else {
+ return find(symbol);
+ }
}
commodity_t *
-commodity_pool_t::find(const string& symbol, const annotation_t& details)
+commodity_pool_t::find_or_create(const string& symbol,
+ const annotation_t& details)
{
- commodity_t * comm = find(symbol);
- if (! comm)
- return NULL;
+ DEBUG("pool.commodities", "commodity_pool_t::find_or_create[ann] "
+ << "symbol " << symbol << std::endl << details);
if (details) {
- string name = make_qualified_name(*comm, details);
-
- if (commodity_t * ann_comm = find(name)) {
+ if (commodity_t * ann_comm = find(symbol, details)) {
assert(ann_comm->annotated && as_annotated_commodity(*ann_comm).details);
return ann_comm;
+ } else {
+ return create(symbol, details);
}
- return NULL;
} else {
- return comm;
+ return find_or_create(symbol);
}
}
commodity_t *
-commodity_pool_t::find_or_create(const string& symbol,
- const annotation_t& details)
+commodity_pool_t::find_or_create(commodity_t& comm, const annotation_t& details)
{
- commodity_t * comm = find_or_create(symbol);
- if (! comm)
- return NULL;
+ DEBUG("pool.commodities", "commodity_pool_t::find_or_create[ann:comm] "
+ << "symbol " << comm.symbol() << std::endl << details);
- if (details)
- return find_or_create(*comm, details);
- else
- return comm;
+ if (details) {
+ if (commodity_t * ann_comm = find(comm.symbol(), details)) {
+ assert(ann_comm->annotated && as_annotated_commodity(*ann_comm).details);
+ return ann_comm;
+ } else {
+ return create(comm, details);
+ }
+ } else {
+ return &comm;
+ }
}
-commodity_t *
+annotated_commodity_t *
commodity_pool_t::create(commodity_t& comm,
- const annotation_t& details,
- const string& mapping_key)
+ const annotation_t& details)
{
+ DEBUG("pool.commodities", "commodity_pool_t::create[ann:comm] "
+ << "symbol " << comm.symbol() << std::endl << details);
+
assert(comm);
assert(! comm.has_annotation());
assert(details);
- assert(! mapping_key.empty());
- unique_ptr<commodity_t> commodity
- (new annotated_commodity_t(&comm, details));
+ shared_ptr<annotated_commodity_t>
+ commodity(new annotated_commodity_t(&comm, details));
comm.add_flags(COMMODITY_SAW_ANNOTATED);
if (details.price) {
@@ -193,34 +209,15 @@ commodity_pool_t::create(commodity_t& comm,
DEBUG("pool.commodities", "Creating annotated commodity "
<< "symbol " << commodity->symbol()
- << " key " << mapping_key << std::endl << details);
-
- // Add the fully annotated name to the map, so that this symbol may
- // quickly be found again.
- commodity->mapping_key_ = mapping_key;
+ << std::endl << details);
- std::pair<commodities_map::iterator, bool> result
- = commodities.insert(commodities_map::value_type(mapping_key,
- commodity.get()));
+ std::pair<annotated_commodities_map::iterator, bool> result
+ = annotated_commodities.insert(annotated_commodities_map::value_type
+ (annotated_commodities_map::key_type
+ (comm.symbol(), details), commodity));
assert(result.second);
- return commodity.release();
-}
-
-commodity_t * commodity_pool_t::find_or_create(commodity_t& comm,
- const annotation_t& details)
-{
- assert(comm);
- assert(details);
-
- string name = make_qualified_name(comm, details);
- assert(! name.empty());
-
- if (commodity_t * ann_comm = find(name)) {
- assert(ann_comm->annotated && as_annotated_commodity(*ann_comm).details);
- return ann_comm;
- }
- return create(comm, details, name);
+ return commodity.get();
}
void commodity_pool_t::exchange(commodity_t& commodity,
diff --git a/src/pool.h b/src/pool.h
index 709f5c71..7203bc20 100644
--- a/src/pool.h
+++ b/src/pool.h
@@ -47,6 +47,7 @@
#define _POOL_H
#include "history.h"
+#include "annotate.h"
namespace ledger {
@@ -66,51 +67,48 @@ public:
* explicitly by calling the create methods of commodity_pool_t, or
* implicitly by parsing a commoditized amount.
*/
- typedef std::map<string, commodity_t *> commodities_map;
+ typedef std::map<string, shared_ptr<commodity_t> > commodities_map;
+ typedef std::map<std::pair<string, annotation_t>,
+ shared_ptr<annotated_commodity_t> > annotated_commodities_map;
- commodities_map commodities;
- commodity_history_t commodity_price_history;
- commodity_t * null_commodity;
- commodity_t * default_commodity;
+ commodities_map commodities;
+ annotated_commodities_map annotated_commodities;
+ commodity_history_t commodity_price_history;
+ commodity_t * null_commodity;
+ commodity_t * default_commodity;
- bool keep_base; // --base
-
- optional<path> price_db; // --price-db=
- long quote_leeway; // --leeway=
- bool get_quotes; // --download
-
- static shared_ptr<commodity_pool_t> current_pool;
+ bool keep_base; // --base
+ optional<path> price_db; // --price-db=
+ long quote_leeway; // --leeway=
+ bool get_quotes; // --download
function<optional<price_point_t>
(commodity_t& commodity, const optional<commodity_t&>& in_terms_of)>
get_commodity_quote;
+ static shared_ptr<commodity_pool_t> current_pool;
+
explicit commodity_pool_t();
virtual ~commodity_pool_t() {
TRACE_DTOR(commodity_pool_t);
- foreach (commodities_map::value_type& pair, commodities)
- checked_delete(pair.second);
}
- string make_qualified_name(const commodity_t& comm,
- const annotation_t& details);
-
commodity_t * create(const string& symbol);
commodity_t * find(const string& name);
commodity_t * find_or_create(const string& symbol);
+ commodity_t * alias(const string& name, commodity_t& referent);
- commodity_t * create(const string& symbol, const annotation_t& details);
- commodity_t * find(const string& symbol, const annotation_t& details);
+ commodity_t * create(const string& symbol,
+ const annotation_t& details);
+ commodity_t * find(const string& symbol,
+ const annotation_t& details);
commodity_t * find_or_create(const string& symbol,
const annotation_t& details);
+ commodity_t * find_or_create(commodity_t& comm, const annotation_t& details);
- commodity_t * create(commodity_t& comm,
- const annotation_t& details,
- const string& mapping_key);
-
- commodity_t * find_or_create(commodity_t& comm,
- const annotation_t& details);
+ annotated_commodity_t * create(commodity_t& comm,
+ const annotation_t& details);
// Exchange one commodity for another, while recording the factored price.
@@ -144,6 +142,7 @@ private:
void serialize(Archive& ar, const unsigned int /* version */) {
ar & current_pool;
ar & commodities;
+ ar & annotated_commodities;
ar & null_commodity;
ar & default_commodity;
ar & keep_base;
diff --git a/src/py_commodity.cc b/src/py_commodity.cc
index b5230850..25e5b918 100644
--- a/src/py_commodity.cc
+++ b/src/py_commodity.cc
@@ -115,7 +115,7 @@ namespace {
(string("Could not find commodity ") + symbol).c_str());
throw_error_already_set();
}
- return (*i).second;
+ return (*i).second.get();
}
python::list py_pool_keys(commodity_pool_t& pool) {
@@ -168,13 +168,15 @@ namespace {
py_pool_commodities_values_begin(commodity_pool_t& pool) {
return make_transform_iterator
(pool.commodities.begin(),
- bind(&commodity_pool_t::commodities_map::value_type::second, _1));
+ bind(&shared_ptr<commodity_t>::get,
+ bind(&commodity_pool_t::commodities_map::value_type::second, _1)));
}
commodities_map_seconds_iterator
py_pool_commodities_values_end(commodity_pool_t& pool) {
return make_transform_iterator
(pool.commodities.end(),
- bind(&commodity_pool_t::commodities_map::value_type::second, _1));
+ bind(&shared_ptr<commodity_t>::get,
+ bind(&commodity_pool_t::commodities_map::value_type::second, _1)));
}
void py_add_price_2(commodity_t& commodity,
@@ -267,8 +269,6 @@ void export_commodity()
make_getter(&commodity_pool_t::get_commodity_quote),
make_setter(&commodity_pool_t::get_commodity_quote))
- .def("make_qualified_name", &commodity_pool_t::make_qualified_name)
-
.def("create", py_create_1, return_internal_reference<>())
.def("create", py_create_2, return_internal_reference<>())
@@ -359,7 +359,6 @@ void export_commodity()
.add_property("base_symbol", &commodity_t::base_symbol)
.add_property("symbol", &commodity_t::symbol)
- .add_property("mapping_key", &commodity_t::mapping_key)
.add_property("name", &commodity_t::name, &commodity_t::set_name)
.add_property("note", &commodity_t::note, &commodity_t::set_note)
diff --git a/src/textual.cc b/src/textual.cc
index 2493dc0d..7bf67347 100644
--- a/src/textual.cc
+++ b/src/textual.cc
@@ -1031,17 +1031,10 @@ void instance_t::commodity_directive(char * line)
}
}
-void instance_t::commodity_alias_directive(commodity_t&, string)
+void instance_t::commodity_alias_directive(commodity_t& comm, string alias)
{
-#if 0
trim(alias);
- std::pair<commodity_pool_t::commodities_map::iterator, bool> result
- = commodity_pool_t::current_pool->commodities.insert
- (commodity_pool_t::commodities_map::value_type(alias, &comm));
- if (! result.second)
- throw_(parse_error,
- _("Cannot use existing commodity name as an alias: %1") << alias);
-#endif
+ commodity_pool_t::current_pool->alias(alias, comm);
}
void instance_t::commodity_format_directive(commodity_t&, string format)