Skip to content

Commit

Permalink
Rewrote the way annotated commodities are managed
Browse files Browse the repository at this point in the history
The new scheme should be much more efficient, and allows for future
growth of what annotations may appear on a commodity.
  • Loading branch information
jwiegley committed Mar 5, 2012
1 parent ff9cf57 commit 97dbf37
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 131 deletions.
9 changes: 0 additions & 9 deletions src/commodity.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,6 @@ class commodity_t

commodity_pool_t * parent_;
optional<string> qualified_symbol;
optional<string> mapping_key_;
bool annotated;

explicit commodity_t(commodity_pool_t * _parent,
Expand Down Expand Up @@ -218,13 +217,6 @@ class commodity_t
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;
}
Expand Down Expand Up @@ -325,7 +317,6 @@ class commodity_t
ar & base;
ar & parent_;
ar & qualified_symbol;
ar & mapping_key_;
ar & annotated;
}
#endif // HAVE_BOOST_SERIALIZATION
Expand Down
161 changes: 79 additions & 82 deletions src/pool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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)
Expand All @@ -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) {
Expand All @@ -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,
Expand Down
49 changes: 24 additions & 25 deletions src/pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#define _POOL_H

#include "history.h"
#include "annotate.h"

namespace ledger {

Expand All @@ -66,51 +67,48 @@ class commodity_pool_t : public noncopyable
* 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.

Expand Down Expand Up @@ -144,6 +142,7 @@ class commodity_pool_t : public noncopyable
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;
Expand Down
11 changes: 5 additions & 6 deletions src/py_commodity.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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<>())

Expand Down Expand Up @@ -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)
Expand Down
Loading

0 comments on commit 97dbf37

Please sign in to comment.