in flex/engines/graph_db/runtime/common/operators/retrieve/path_expand.cc [618:783]
static void all_shortest_path_with_given_source_and_dest_impl(
const GraphReadInterface& graph, const ShortestPathParams& params,
vid_t src, vid_t dst, std::vector<std::vector<vid_t>>& paths) {
GraphReadInterface::vertex_array_t<int8_t> dist_from_src(
graph.GetVertexSet(params.labels[0].src_label), -1);
GraphReadInterface::vertex_array_t<int8_t> dist_from_dst(
graph.GetVertexSet(params.labels[0].dst_label), -1);
dist_from_src[src] = 0;
dist_from_dst[dst] = 0;
std::queue<vid_t> q1, q2, tmp;
q1.push(src);
q2.push(dst);
std::vector<vid_t> vec;
int8_t src_dep = 0, dst_dep = 0;
while (true) {
if (src_dep >= params.hop_upper || dst_dep >= params.hop_upper ||
!vec.empty()) {
break;
}
if (q1.size() <= q2.size()) {
if (q1.empty()) {
break;
}
while (!q1.empty()) {
vid_t v = q1.front();
q1.pop();
auto oe_iter = graph.GetOutEdgeIterator(params.labels[0].src_label, v,
params.labels[0].dst_label,
params.labels[0].edge_label);
while (oe_iter.IsValid()) {
vid_t nbr = oe_iter.GetNeighbor();
if (dist_from_src[nbr] == -1) {
dist_from_src[nbr] = src_dep + 1;
tmp.push(nbr);
if (dist_from_dst[nbr] != -1) {
vec.push_back(nbr);
}
}
oe_iter.Next();
}
auto ie_iter = graph.GetInEdgeIterator(params.labels[0].dst_label, v,
params.labels[0].src_label,
params.labels[0].edge_label);
while (ie_iter.IsValid()) {
vid_t nbr = ie_iter.GetNeighbor();
if (dist_from_src[nbr] == -1) {
dist_from_src[nbr] = src_dep + 1;
tmp.push(nbr);
if (dist_from_dst[nbr] != -1) {
vec.push_back(nbr);
}
}
ie_iter.Next();
}
}
std::swap(q1, tmp);
++src_dep;
} else {
if (q2.empty()) {
break;
}
while (!q2.empty()) {
vid_t v = q2.front();
q2.pop();
auto oe_iter = graph.GetOutEdgeIterator(params.labels[0].dst_label, v,
params.labels[0].src_label,
params.labels[0].edge_label);
while (oe_iter.IsValid()) {
vid_t nbr = oe_iter.GetNeighbor();
if (dist_from_dst[nbr] == -1) {
dist_from_dst[nbr] = dst_dep + 1;
tmp.push(nbr);
if (dist_from_src[nbr] != -1) {
vec.push_back(nbr);
}
}
oe_iter.Next();
}
auto ie_iter = graph.GetInEdgeIterator(params.labels[0].src_label, v,
params.labels[0].dst_label,
params.labels[0].edge_label);
while (ie_iter.IsValid()) {
vid_t nbr = ie_iter.GetNeighbor();
if (dist_from_dst[nbr] == -1) {
dist_from_dst[nbr] = dst_dep + 1;
tmp.push(nbr);
if (dist_from_src[nbr] != -1) {
vec.push_back(nbr);
}
}
ie_iter.Next();
}
}
std::swap(q2, tmp);
++dst_dep;
}
}
while (!q1.empty()) {
q1.pop();
}
if (vec.empty()) {
return;
}
if (src_dep + dst_dep >= params.hop_upper) {
return;
}
GraphReadInterface::vertex_array_t<bool> visited(
graph.GetVertexSet(params.labels[0].src_label), false);
for (auto v : vec) {
q1.push(v);
visited[v] = true;
}
while (!q1.empty()) {
auto v = q1.front();
q1.pop();
auto oe_iter = graph.GetOutEdgeIterator(params.labels[0].src_label, v,
params.labels[0].dst_label,
params.labels[0].edge_label);
while (oe_iter.IsValid()) {
vid_t nbr = oe_iter.GetNeighbor();
if (visited[nbr]) {
oe_iter.Next();
continue;
}
if (dist_from_src[nbr] != -1 &&
dist_from_src[nbr] + 1 == dist_from_src[v]) {
q1.push(nbr);
visited[nbr] = true;
}
if (dist_from_dst[nbr] != -1 &&
dist_from_dst[nbr] + 1 == dist_from_dst[v]) {
q1.push(nbr);
visited[nbr] = true;
dist_from_src[nbr] = dist_from_src[v] + 1;
}
oe_iter.Next();
}
auto ie_iter = graph.GetInEdgeIterator(params.labels[0].dst_label, v,
params.labels[0].src_label,
params.labels[0].edge_label);
while (ie_iter.IsValid()) {
vid_t nbr = ie_iter.GetNeighbor();
if (visited[nbr]) {
ie_iter.Next();
continue;
}
if (dist_from_src[nbr] != -1 &&
dist_from_src[nbr] + 1 == dist_from_src[v]) {
q1.push(nbr);
visited[nbr] = true;
}
if (dist_from_dst[nbr] != -1 &&
dist_from_dst[nbr] + 1 == dist_from_dst[v]) {
q1.push(nbr);
visited[nbr] = true;
dist_from_src[nbr] = dist_from_src[v] + 1;
}
ie_iter.Next();
}
}
std::vector<vid_t> cur_path;
dfs(graph, src, dst, visited, dist_from_src, params, paths, cur_path);
}