@@ -39,10 +39,17 @@ folly::Future<Status> MultiShortestPathExecutor::execute() {
39
39
})
40
40
.thenValue ([this ](auto && resp) {
41
41
UNUSED (resp);
42
- preLeftPaths_.swap (leftPaths_);
43
- preRightPaths_.swap (rightPaths_);
44
- leftPaths_.clear ();
45
- rightPaths_.clear ();
42
+ preRightPaths_ = rightPaths_;
43
+ // update history
44
+ for (auto & iter : leftPaths_) {
45
+ historyLeftPaths_[iter.first ].insert (std::make_move_iterator (iter.second .begin ()),
46
+ std::make_move_iterator (iter.second .end ()));
47
+ }
48
+ for (auto & iter : rightPaths_) {
49
+ historyRightPaths_[iter.first ].insert (std::make_move_iterator (iter.second .begin ()),
50
+ std::make_move_iterator (iter.second .end ()));
51
+ }
52
+
46
53
step_++;
47
54
DataSet ds;
48
55
ds.colNames = pathNode_->colNames ();
@@ -58,7 +65,8 @@ void MultiShortestPathExecutor::init() {
58
65
for (; rIter->valid (); rIter->next ()) {
59
66
auto & vid = rIter->getColumn (0 );
60
67
if (rightVids.emplace (vid).second ) {
61
- preRightPaths_[vid].push_back ({Path (Vertex (vid, {}), {})});
68
+ std::vector<Path> tmp ({Path (Vertex (vid, {}), {})});
69
+ preRightPaths_[vid].emplace (vid, std::move (tmp));
62
70
}
63
71
}
64
72
@@ -70,12 +78,24 @@ void MultiShortestPathExecutor::init() {
70
78
for (const auto & leftVid : leftVids) {
71
79
for (const auto & rightVid : rightVids) {
72
80
if (leftVid != rightVid) {
73
- terminationMap_.emplace (std::make_pair (leftVid, rightVid) , true );
81
+ terminationMap_.emplace (leftVid, std::make_pair (rightVid, true ) );
74
82
}
75
83
}
76
84
}
77
85
}
78
86
87
+ std::vector<Path> MultiShortestPathExecutor::createPaths (const std::vector<Path>& paths,
88
+ const Edge& edge) {
89
+ std::vector<Path> newPaths;
90
+ newPaths.reserve (paths.size ());
91
+ for (const auto & p : paths) {
92
+ Path path = p;
93
+ path.steps .emplace_back (Step (Vertex (edge.dst , {}), edge.type , edge.name , edge.ranking , {}));
94
+ newPaths.emplace_back (std::move (path));
95
+ }
96
+ return newPaths;
97
+ }
98
+
79
99
Status MultiShortestPathExecutor::buildPath (bool reverse) {
80
100
auto iter = reverse ? ectx_->getResult (pathNode_->rightInputVar ()).iter ()
81
101
: ectx_->getResult (pathNode_->leftInputVar ()).iter ();
@@ -96,10 +116,25 @@ Status MultiShortestPathExecutor::buildPath(bool reverse) {
96
116
Path path;
97
117
path.src = Vertex (src, {});
98
118
path.steps .emplace_back (Step (Vertex (dst, {}), edge.type , edge.name , edge.ranking , {}));
99
- currentPaths[dst].emplace_back (std::move (path));
119
+ auto foundDst = currentPaths.find (dst);
120
+ if (foundDst != currentPaths.end ()) {
121
+ auto foundSrc = foundDst->second .find (src);
122
+ if (foundSrc != foundDst->second .end ()) {
123
+ // same <src, dst>, different edge type or rank
124
+ foundSrc->second .emplace_back (std::move (path));
125
+ } else {
126
+ std::vector<Path> tmp ({std::move (path)});
127
+ foundDst->second .emplace (src, std::move (tmp));
128
+ }
129
+ } else {
130
+ std::vector<Path> tmp ({std::move (path)});
131
+ currentPaths[dst].emplace (src, std::move (tmp));
132
+ }
133
+ std::vector<Path> start ({Path (Vertex (src, {}), {})});
134
+ currentPaths[src].emplace (src, std::move (start));
100
135
}
101
136
} else {
102
- auto & historyPaths = reverse ? preRightPaths_ : preLeftPaths_ ;
137
+ auto & historyPaths = reverse ? historyRightPaths_ : historyLeftPaths_ ;
103
138
for (; iter->valid (); iter->next ()) {
104
139
auto edgeVal = iter->getEdge ();
105
140
if (UNLIKELY (!edgeVal.isEdge ())) {
@@ -108,16 +143,59 @@ Status MultiShortestPathExecutor::buildPath(bool reverse) {
108
143
auto & edge = edgeVal.getEdge ();
109
144
auto & src = edge.src ;
110
145
auto & dst = edge.dst ;
111
- for (const auto & histPath : historyPaths[src]) {
112
- Path path = histPath;
113
- path.steps .emplace_back (Step (Vertex (dst, {}), edge.type , edge.name , edge.ranking , {}));
114
- if (path.hasDuplicateVertices ()) {
115
- continue ;
146
+ auto & prePaths = historyPaths[src];
147
+
148
+ auto foundHistDst = historyPaths.find (dst);
149
+ if (foundHistDst == historyPaths.end ()) {
150
+ // dst not in history
151
+ auto foundDst = currentPaths.find (dst);
152
+ if (foundDst == currentPaths.end ()) {
153
+ // dst not in current, new edge
154
+ for (const auto & prePath : prePaths) {
155
+ currentPaths[dst].emplace (prePath.first , createPaths (prePath.second , edge));
156
+ }
157
+ } else {
158
+ // dst in current
159
+ for (const auto & prePath : prePaths) {
160
+ auto newPaths = createPaths (prePath.second , edge);
161
+ auto foundSrc = foundDst->second .find (prePath.first );
162
+ if (foundSrc == foundDst->second .end ()) {
163
+ foundDst->second .emplace (prePath.first , std::move (newPaths));
164
+ } else {
165
+ foundSrc->second .insert (foundSrc->second .begin (),
166
+ std::make_move_iterator (newPaths.begin ()),
167
+ std::make_move_iterator (newPaths.end ()));
168
+ }
169
+ }
170
+ }
171
+ } else {
172
+ // dst in history
173
+ auto & historyDstPaths = foundHistDst->second ;
174
+ for (const auto & prePath : prePaths) {
175
+ if (historyDstPaths.find (prePath.first ) != historyDstPaths.end ()) {
176
+ // loop: a->b->c->a or a->b->c->b,
177
+ // filter out path that with duplicate vertex or have already been found before
178
+ continue ;
179
+ }
180
+ auto foundDst = currentPaths.find (dst);
181
+ if (foundDst == currentPaths.end ()) {
182
+ currentPaths[dst].emplace (prePath.first , createPaths (prePath.second , edge));
183
+ } else {
184
+ auto newPaths = createPaths (prePath.second , edge);
185
+ auto foundSrc = foundDst->second .find (prePath.first );
186
+ if (foundSrc == foundDst->second .end ()) {
187
+ foundDst->second .emplace (prePath.first , std::move (newPaths));
188
+ } else {
189
+ foundSrc->second .insert (foundSrc->second .begin (),
190
+ std::make_move_iterator (newPaths.begin ()),
191
+ std::make_move_iterator (newPaths.end ()));
192
+ }
193
+ }
116
194
}
117
- currentPaths[dst].emplace_back (std::move (path));
118
195
}
119
196
}
120
197
}
198
+
121
199
// set nextVid
122
200
const auto & nextVidVar = reverse ? pathNode_->rightVidVar () : pathNode_->leftVidVar ();
123
201
setNextStepVid (currentPaths, nextVidVar);
@@ -126,46 +204,33 @@ Status MultiShortestPathExecutor::buildPath(bool reverse) {
126
204
127
205
DataSet MultiShortestPathExecutor::doConjunct (
128
206
const std::vector<std::pair<Interims::iterator, Interims::iterator>>& iters) {
207
+ auto buildPaths =
208
+ [](const std::vector<Path>& leftPaths, const std::vector<Path>& rightPaths, DataSet& ds) {
209
+ for (const auto & leftPath : leftPaths) {
210
+ for (const auto & rightPath : rightPaths) {
211
+ auto forwardPath = leftPath;
212
+ auto backwardPath = rightPath;
213
+ backwardPath.reverse ();
214
+ forwardPath.append (std::move (backwardPath));
215
+ Row row;
216
+ row.values .emplace_back (std::move (forwardPath));
217
+ ds.rows .emplace_back (std::move (row));
218
+ }
219
+ }
220
+ };
221
+
129
222
DataSet ds;
130
223
for (const auto & iter : iters) {
131
224
const auto & leftPaths = iter.first ->second ;
132
225
const auto & rightPaths = iter.second ->second ;
133
- if (leftPaths.size () < rightPaths.size ()) {
134
- for (const auto & leftPath : leftPaths) {
135
- const auto & srcVid = leftPath.src .vid ;
136
- for (const auto & rightPath : rightPaths) {
137
- const auto & dstVid = rightPath.src .vid ;
138
- auto found = terminationMap_.find ({srcVid, dstVid});
139
- if (found == terminationMap_.end ()) {
140
- continue ;
141
- }
142
- auto forwardPath = leftPath;
143
- auto backwardPath = rightPath;
144
- backwardPath.reverse ();
145
- forwardPath.append (std::move (backwardPath));
146
- Row row;
147
- row.values .emplace_back (std::move (forwardPath));
148
- ds.rows .emplace_back (std::move (row));
149
- found->second = false ;
150
- }
151
- }
152
- } else {
226
+ for (const auto & leftPath : leftPaths) {
227
+ auto range = terminationMap_.equal_range (leftPath.first );
153
228
for (const auto & rightPath : rightPaths) {
154
- const auto & dstVid = rightPath.src .vid ;
155
- for (const auto & leftPath : leftPaths) {
156
- const auto & srcVid = leftPath.src .vid ;
157
- auto found = terminationMap_.find ({srcVid, dstVid});
158
- if (found == terminationMap_.end ()) {
159
- continue ;
229
+ for (auto found = range.first ; found != range.second ; ++found) {
230
+ if (found->second .first == rightPath.first ) {
231
+ buildPaths (leftPath.second , rightPath.second , ds);
232
+ found->second .second = false ;
160
233
}
161
- auto forwardPath = leftPath;
162
- auto backwardPath = rightPath;
163
- backwardPath.reverse ();
164
- forwardPath.append (std::move (backwardPath));
165
- Row row;
166
- row.values .emplace_back (std::move (forwardPath));
167
- ds.rows .emplace_back (std::move (row));
168
- found->second = false ;
169
234
}
170
235
}
171
236
}
@@ -228,7 +293,7 @@ folly::Future<bool> MultiShortestPathExecutor::conjunctPath(bool oddStep) {
228
293
}
229
294
230
295
for (auto iter = terminationMap_.begin (); iter != terminationMap_.end ();) {
231
- if (!iter->second ) {
296
+ if (!iter->second . second ) {
232
297
iter = terminationMap_.erase (iter);
233
298
} else {
234
299
++iter;
0 commit comments