1
1
#include " forward.h"
2
+ #include " pagoda/graph/node.h"
2
3
4
+ #include < algorithm>
5
+ #include < map>
3
6
#include < pagoda/graph/query/input_node.h>
4
7
#include < iterator>
5
8
@@ -9,8 +12,51 @@ namespace pagoda::graph::traversal
9
12
{
10
13
Forward::Forward (Graph& graph) : Traversal(graph)
11
14
{
12
- query::InputNode q (graph, [this ](NodePtr n) { m_nodesToVisit.push (n); });
15
+ std::queue<NodePtr> nodes;
16
+ std::map<NodePtr, uint32_t > nodeDistances;
17
+ query::InputNode q (graph, [&nodes, &nodeDistances](NodePtr n) {
18
+ nodes.push (n);
19
+ nodeDistances.emplace (n, 0 );
20
+ });
13
21
graph.ExecuteQuery (q);
22
+
23
+ while (!nodes.empty ()) {
24
+ NodePtr front = nodes.front ();
25
+ nodes.pop ();
26
+ const uint32_t thisNodeDistance = nodeDistances[front];
27
+
28
+ NodeSet outNodes;
29
+ GetOutputNodes (front, std::inserter (outNodes, std::end (outNodes)));
30
+ for (auto n : outNodes) {
31
+ auto iter = nodeDistances.find (n);
32
+ const auto nextNodeDistance = iter == nodeDistances.end () ?
33
+ 0 : // First time seeing this node
34
+ iter->second ; // We've seen this node
35
+
36
+ // Update distance
37
+ if (thisNodeDistance + 1 > nextNodeDistance) {
38
+ // We have found a longer path
39
+ nodeDistances[n] = iter->second = thisNodeDistance + 1 ;
40
+ }
41
+
42
+ nodes.push (n);
43
+ }
44
+ }
45
+
46
+ std::vector<NodePtr> sortedNodes;
47
+ sortedNodes.reserve (nodeDistances.size ());
48
+ for (const auto & [n, dist] : nodeDistances) {
49
+ sortedNodes.emplace_back (n);
50
+ }
51
+
52
+ std::sort (sortedNodes.begin (), sortedNodes.end (),
53
+ [&nodeDistances] (const NodePtr& lhs, const NodePtr& rhs) {
54
+ return nodeDistances[lhs] < nodeDistances[rhs];
55
+ });
56
+
57
+ for (const auto & n : sortedNodes) {
58
+ m_nodesToVisit.push (n);
59
+ }
14
60
}
15
61
16
62
Forward::~Forward () {}
@@ -19,13 +65,7 @@ NodePtr Forward::Get() { return m_nodesToVisit.front(); }
19
65
20
66
bool Forward::Advance ()
21
67
{
22
- auto front = m_nodesToVisit.front ();
23
- m_nodesToVisit.pop ();
24
- NodeSet outNodes;
25
- GetOutputNodes (front, std::inserter (outNodes, std::end (outNodes)));
26
- for (auto n : outNodes) {
27
- m_nodesToVisit.push (n);
28
- }
68
+ m_nodesToVisit.pop ();
29
69
return HasNext ();
30
70
}
31
71
0 commit comments