Linkgraph: Replace a std::list with a std::vector.

This commit is contained in:
Jonathan G Rennison
2017-02-08 20:38:05 +00:00
parent c86a027e88
commit 117b56caeb
4 changed files with 30 additions and 25 deletions

View File

@@ -24,8 +24,9 @@ void FlowMapper::Run(LinkGraphJob &job) const
Node prev_node = job[node_id]; Node prev_node = job[node_id];
StationID prev = prev_node.Station(); StationID prev = prev_node.Station();
PathList &paths = prev_node.Paths(); PathList &paths = prev_node.Paths();
for (PathList::iterator i = paths.begin(); i != paths.end(); ++i) { for (PathList::reverse_iterator i = paths.rbegin(); i != paths.rend(); ++i) {
Path *path = *i; Path *path = *i;
if (!path) continue;
uint flow = path->GetFlow(); uint flow = path->GetFlow();
if (flow == 0) break; if (flow == 0) break;
Node node = job[path->GetNode()]; Node node = job[path->GetNode()];

View File

@@ -303,7 +303,7 @@ uint Path::AddFlow(uint new_flow, LinkGraphJob &job, uint max_saturation)
} }
new_flow = this->parent->AddFlow(new_flow, job, max_saturation); new_flow = this->parent->AddFlow(new_flow, job, max_saturation);
if (this->flow == 0 && new_flow > 0) { if (this->flow == 0 && new_flow > 0) {
job[this->parent->node].Paths().push_front(this); job[this->parent->node].Paths().push_back(this);
} }
edge.AddFlow(new_flow); edge.AddFlow(new_flow);
} }

View File

@@ -15,13 +15,13 @@
#include "../thread/thread.h" #include "../thread/thread.h"
#include "../core/dyn_arena_alloc.hpp" #include "../core/dyn_arena_alloc.hpp"
#include "linkgraph.h" #include "linkgraph.h"
#include <list> #include <vector>
#include <memory> #include <memory>
class LinkGraphJob; class LinkGraphJob;
class Path; class Path;
class LinkGraphJobGroup; class LinkGraphJobGroup;
typedef std::list<Path *> PathList; typedef std::vector<Path *> PathList;
/** Type of the pool for link graph jobs. */ /** Type of the pool for link graph jobs. */
typedef Pool<LinkGraphJob, LinkGraphJobID, 32, 0xFFFF> LinkGraphJobPool; typedef Pool<LinkGraphJob, LinkGraphJobID, 32, 0xFFFF> LinkGraphJobPool;

View File

@@ -493,10 +493,9 @@ void MCF1stPass::EliminateCycle(PathVector &path, Path *cycle_begin, uint flow)
cycle_begin->ReduceFlow(flow); cycle_begin->ReduceFlow(flow);
if (cycle_begin->GetFlow() == 0) { if (cycle_begin->GetFlow() == 0) {
PathList &node_paths = this->job[cycle_begin->GetParent()->GetNode()].Paths(); PathList &node_paths = this->job[cycle_begin->GetParent()->GetNode()].Paths();
for (PathList::iterator i = node_paths.begin(); i != node_paths.end(); ++i) { for (PathList::reverse_iterator i = node_paths.rbegin(); i != node_paths.rend(); ++i) {
if (*i == cycle_begin) { if (*i == cycle_begin) {
node_paths.erase(i); *i = nullptr;
node_paths.push_back(cycle_begin);
break; break;
} }
} }
@@ -528,30 +527,35 @@ bool MCF1stPass::EliminateCycles(PathVector &path, NodeID origin_id, NodeID next
* in one path each. */ * in one path each. */
PathList &paths = this->job[next_id].Paths(); PathList &paths = this->job[next_id].Paths();
PathViaMap next_hops; PathViaMap next_hops;
for (PathList::iterator i = paths.begin(); i != paths.end();) { uint holes = 0;
for (PathList::reverse_iterator i = paths.rbegin(); i != paths.rend();) {
Path *new_child = *i; Path *new_child = *i;
uint new_flow = new_child->GetFlow(); if (new_child) {
if (new_flow == 0) break; uint new_flow = new_child->GetFlow();
if (new_child->GetOrigin() == origin_id) { if (new_flow == 0) break;
PathViaMap::iterator via_it = next_hops.find(new_child->GetNode()); if (new_child->GetOrigin() == origin_id) {
if (via_it == next_hops.end()) { PathViaMap::iterator via_it = next_hops.find(new_child->GetNode());
next_hops[new_child->GetNode()] = new_child; if (via_it == next_hops.end()) {
++i; next_hops[new_child->GetNode()] = new_child;
} else { } else {
Path *child = via_it->second; Path *child = via_it->second;
child->AddFlow(new_flow); child->AddFlow(new_flow);
new_child->ReduceFlow(new_flow); new_child->ReduceFlow(new_flow);
/* We might hit end() with with the ++ here and skip the *i = nullptr;
* newly push_back'ed path. That's good as the flow of that holes++;
* path is 0 anyway. */ }
paths.erase(i++);
paths.push_back(new_child);
} }
} else { } else {
++i; holes++;
} }
++i;
} }
if (holes >= paths.size() / 8) {
/* remove any holes */
paths.erase(std::remove(paths.begin(), paths.end(), nullptr), paths.end());
}
bool found = false; bool found = false;
/* Search the next hops for nodes we have already visited */ /* Search the next hops for nodes we have already visited */
for (PathViaMap::iterator via_it = next_hops.begin(); for (PathViaMap::iterator via_it = next_hops.begin();