summaryrefslogtreecommitdiff
path: root/src/history.cc
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2012-03-09 06:06:17 -0600
committerJohn Wiegley <johnw@newartisans.com>2012-03-09 06:06:17 -0600
commit1a6ec4e8b4b71ef36cf81bea6e42abbc8610f1ac (patch)
tree58b6a36ca3fc4c09cb6c52679e7f2e0a10aa4afd /src/history.cc
parent9fd1fc1c228eeba8324972d0d034027ad9de6f41 (diff)
downloadfork-ledger-1a6ec4e8b4b71ef36cf81bea6e42abbc8610f1ac.tar.gz
fork-ledger-1a6ec4e8b4b71ef36cf81bea6e42abbc8610f1ac.tar.bz2
fork-ledger-1a6ec4e8b4b71ef36cf81bea6e42abbc8610f1ac.zip
Fixed the way adjacency_list was being used
Diffstat (limited to 'src/history.cc')
-rw-r--r--src/history.cc107
1 files changed, 95 insertions, 12 deletions
diff --git a/src/history.cc b/src/history.cc
index 7c49b343..83326728 100644
--- a/src/history.cc
+++ b/src/history.cc
@@ -42,13 +42,89 @@ struct f_max : public std::binary_function<T, T, bool> {
namespace ledger {
+template <typename EdgeWeightMap,
+ typename PricePointMap,
+ typename PriceRatioMap>
+class recent_edge_weight
+{
+public:
+ EdgeWeightMap weight;
+ PricePointMap price_point;
+ PriceRatioMap ratios;
+
+ datetime_t reftime;
+ optional<datetime_t> oldest;
+
+ recent_edge_weight() { }
+ recent_edge_weight(EdgeWeightMap _weight,
+ PricePointMap _price_point,
+ PriceRatioMap _ratios,
+ datetime_t _reftime,
+ const optional<datetime_t>& _oldest = none)
+ : weight(_weight), price_point(_price_point), ratios(_ratios),
+ reftime(_reftime), oldest(_oldest) { }
+
+ template <typename Edge>
+ bool operator()(const Edge& e) const
+ {
+#if defined(DEBUG_ON)
+ DEBUG("history.find", " reftime = " << reftime);
+ if (oldest) {
+ DEBUG("history.find", " oldest = " << *oldest);
+ }
+#endif
+
+ const price_map_t& prices(get(ratios, e));
+ if (prices.empty()) {
+ DEBUG("history.find", " prices map is empty for this edge");
+ return false;
+ }
+
+ price_map_t::const_iterator low = prices.upper_bound(reftime);
+ if (low != prices.end() && low == prices.begin()) {
+ DEBUG("history.find", " don't use this edge");
+ return false;
+ } else {
+ --low;
+ assert(((*low).first <= reftime));
+
+ if (oldest && (*low).first < *oldest) {
+ DEBUG("history.find", " edge is out of range");
+ return false;
+ }
+
+ long secs = (reftime - (*low).first).total_seconds();
+ assert(secs >= 0);
+
+ put(weight, e, secs);
+ put(price_point, e, price_point_t((*low).first, (*low).second));
+
+ DEBUG("history.find", " using edge at price point "
+ << (*low).first << " " << (*low).second);
+ return true;
+ }
+ }
+};
+
+typedef filtered_graph
+ <commodity_history_t::Graph,
+ recent_edge_weight<commodity_history_t::EdgeWeightMap,
+ commodity_history_t::PricePointMap,
+ commodity_history_t::PriceRatioMap> > FGraph;
+
+typedef property_map<FGraph, vertex_name_t>::type FNameMap;
+typedef property_map<FGraph, vertex_index_t>::type FIndexMap;
+typedef iterator_property_map
+ <commodity_history_t::vertex_descriptor*, FIndexMap,
+ commodity_history_t::vertex_descriptor,
+ commodity_history_t::vertex_descriptor&> FPredecessorMap;
+typedef iterator_property_map<long*, FIndexMap, long, long&> FDistanceMap;
+
void commodity_history_t::add_commodity(commodity_t& comm)
{
if (! comm.graph_index()) {
- std::size_t index = num_vertices(price_graph);
- comm.set_graph_index(index);
- const vertex_descriptor vert = add_vertex(&comm, price_graph);
- put(indexmap, vert, index);
+ comm.set_graph_index(num_vertices(price_graph));
+ add_vertex(/* vertex_name= */ &comm, price_graph);
}
}
@@ -59,7 +135,10 @@ void commodity_history_t::add_price(const commodity_t& source,
vertex_descriptor sv = vertex(*source.graph_index(), price_graph);
vertex_descriptor tv = vertex(*price.commodity().graph_index(), price_graph);
- std::pair<edge_descriptor, bool> e1 = add_edge(sv, tv, 0, price_graph);
+ std::pair<edge_descriptor, bool> e1 = edge(sv, tv, price_graph);
+ if (! e1.second)
+ e1 = add_edge(sv, tv, price_graph);
+
price_map_t& prices(get(ratiomap, e1.first));
std::pair<price_map_t::iterator, bool> result =
@@ -77,11 +156,16 @@ void commodity_history_t::remove_price(const commodity_t& source,
vertex_descriptor sv = vertex(*source.graph_index(), price_graph);
vertex_descriptor tv = vertex(*target.graph_index(), price_graph);
- std::pair<edge_descriptor, bool> e1 = add_edge(sv, tv, 0, price_graph);
- price_map_t& prices(get(ratiomap, e1.first));
+ std::pair<Graph::edge_descriptor, bool> e1 = edge(sv, tv, price_graph);
+ if (e1.second) {
+ price_map_t& prices(get(ratiomap, e1.first));
- // jww (2012-03-04): If it fails, should we give a warning?
- prices.erase(date);
+ // jww (2012-03-04): If it fails, should we give a warning?
+ prices.erase(date);
+
+ if (prices.empty())
+ remove_edge(e1.first, price_graph);
+ }
}
void commodity_history_t::map_prices(function<void(datetime_t,
@@ -208,9 +292,8 @@ commodity_history_t::find_price(const commodity_t& source,
std::vector<vertex_descriptor> predecessors(vector_len);
std::vector<long> distances(vector_len);
- FIndexMap indexMap(get(vertex_index, fg));
- FPredecessorMap predecessorMap(&predecessors[0], indexMap);
- FDistanceMap distanceMap(&distances[0], indexMap);
+ FPredecessorMap predecessorMap(&predecessors[0]);
+ FDistanceMap distanceMap(&distances[0]);
dijkstra_shortest_paths(fg, /* start= */ sv,
predecessor_map(predecessorMap)