diff --git a/src/graph/executor/algo/SubgraphExecutor.cpp b/src/graph/executor/algo/SubgraphExecutor.cpp index da0e66262a1..caa2d22b5f2 100644 --- a/src/graph/executor/algo/SubgraphExecutor.cpp +++ b/src/graph/executor/algo/SubgraphExecutor.cpp @@ -29,13 +29,13 @@ folly::Future SubgraphExecutor::execute() { VLOG(1) << "input: " << subgraph->inputVar() << " output: " << node()->outputVar(); auto iter = ectx_->getResult(subgraph->inputVar()).iter(); - std::unordered_set currentVids; + std::unordered_map currentVids; currentVids.reserve(iter->size()); historyVids_.reserve(historyVids_.size() + iter->size()); if (currentStep == 1) { for (; iter->valid(); iter->next()) { const auto& src = iter->getColumn(nebula::kVid); - currentVids.emplace(src); + currentVids.emplace(src, 0); } iter->reset(); } @@ -46,15 +46,24 @@ folly::Future SubgraphExecutor::execute() { if (biDirectEdgeTypes.empty()) { iter->next(); } else { - const auto& type = iter->getEdgeProp("*", nebula::kType); - if (type.isInt() && biDirectEdgeTypes.find(type.getInt()) != biDirectEdgeTypes.end()) { + const auto& typeVal = iter->getEdgeProp("*", nebula::kType); + if (UNLIKELY(!typeVal.isInt())) { iter->erase(); + continue; + } + auto type = typeVal.getInt(); + if (biDirectEdgeTypes.find(type) != biDirectEdgeTypes.end()) { + if (type < 0 || historyVids_[dst] + 2 == currentStep) { + iter->erase(); + } else { + iter->next(); + } } else { iter->next(); } } } else { - if (currentVids.emplace(dst).second) { + if (currentVids.emplace(dst, currentStep).second) { Row row; row.values.emplace_back(std::move(dst)); ds.rows.emplace_back(std::move(row)); @@ -72,6 +81,7 @@ folly::Future SubgraphExecutor::execute() { void SubgraphExecutor::oneMoreStep() { auto* subgraph = asNode(node()); + auto currentStep = subgraph->steps(); auto output = subgraph->oneMoreStepOutput(); VLOG(1) << "OneMoreStep Input: " << subgraph->inputVar() << " Output: " << output; auto iter = ectx_->getResult(subgraph->inputVar()).iter(); @@ -86,9 +96,18 @@ void SubgraphExecutor::oneMoreStep() { if (biDirectEdgeTypes.empty()) { iter->next(); } else { - const auto& type = iter->getEdgeProp("*", nebula::kType); - if (type.isInt() && biDirectEdgeTypes.find(type.getInt()) != biDirectEdgeTypes.end()) { + const auto& typeVal = iter->getEdgeProp("*", nebula::kType); + if (UNLIKELY(!typeVal.isInt())) { iter->erase(); + continue; + } + auto type = typeVal.getInt(); + if (biDirectEdgeTypes.find(type) != biDirectEdgeTypes.end()) { + if (type < 0 || historyVids_[dst] + 2 == currentStep) { + iter->erase(); + } else { + iter->next(); + } } else { iter->next(); } diff --git a/src/graph/executor/algo/SubgraphExecutor.h b/src/graph/executor/algo/SubgraphExecutor.h index 83da2e6cc82..1915a2444ba 100644 --- a/src/graph/executor/algo/SubgraphExecutor.h +++ b/src/graph/executor/algo/SubgraphExecutor.h @@ -21,7 +21,7 @@ class SubgraphExecutor : public Executor { void oneMoreStep(); private: - std::unordered_set historyVids_; + std::unordered_map historyVids_; }; } // namespace graph