Skip to content

Commit

Permalink
refactor traverse output
Browse files Browse the repository at this point in the history
  • Loading branch information
nevermore3 committed Mar 31, 2023
1 parent 2adc045 commit e4cc5bf
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 33 deletions.
2 changes: 2 additions & 0 deletions src/graph/context/ast/CypherAstContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ struct EdgeInfo {
MatchEdge::Direction direction{MatchEdge::Direction::OUT_EDGE};
std::vector<std::string> types;
std::string alias;
// use for construct path struct
std::string innerAlias;
const MapExpression* props{nullptr};
Expression* filter{nullptr};
};
Expand Down
64 changes: 47 additions & 17 deletions src/graph/executor/query/TraverseExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ namespace graph {

folly::Future<Status> TraverseExecutor::execute() {
range_ = traverse_->stepRange();
genPath_ = traverse_->genPath();
NG_RETURN_IF_ERROR(buildRequestVids());
if (vids_.empty()) {
DataSet emptyDs;
Expand Down Expand Up @@ -477,46 +478,61 @@ std::vector<Row> TraverseExecutor::buildPath(const Value& initVertex,
return std::vector<Row>();
}

std::vector<Row> result;
result.reserve(adjEdges.size());
std::vector<Row> oneStepPath;
oneStepPath.reserve(adjEdges.size());
for (auto& edge : adjEdges) {
List edgeList;
edgeList.values.emplace_back(edge);
Row row;
row.values.emplace_back(src);
row.values.emplace_back(std::move(edgeList));
result.emplace_back(std::move(row));
// only contain edges
row.values.emplace_back(edgeList);
if (genPath_) {
// contain nodes & edges
row.values.emplace_back(std::move(edgeList));
}
oneStepPath.emplace_back(std::move(row));
}

if (maxStep == 1) {
if (traverse_->trackPrevPath()) {
return joinPrevPath(initVertex, result);
return joinPrevPath(initVertex, oneStepPath);
}
return result;
return oneStepPath;
}

size_t step = 2;
std::vector<Row> newResult;
std::queue<std::vector<Value>*> queue;
std::queue<std::vector<Value>*> edgeListQueue;
std::list<std::unique_ptr<std::vector<Value>>> holder;
for (auto& edge : adjEdges) {
auto ptr = std::make_unique<std::vector<Value>>(std::vector<Value>({edge}));
queue.emplace(ptr.get());
edgeListQueue.emplace(ptr.get());
holder.emplace_back(std::move(ptr));
}
size_t adjSize = queue.size();
while (!queue.empty()) {
auto edgeListPtr = queue.front();

size_t adjSize = edgeListQueue.size();
while (!edgeListQueue.empty()) {
auto edgeListPtr = edgeListQueue.front();
auto& dst = edgeListPtr->back().getEdge().dst;
queue.pop();
edgeListQueue.pop();

std::vector<Value>* vertexEdgeListPtr = nullptr;
if (genPath_) {
vertexEdgeListPtr = queue.front();
queue.pop();
}

--adjSize;
auto dstIter = adjList_.find(dst);
if (dstIter == adjList_.end()) {
if (adjSize == 0) {
if (++step > maxStep) {
break;
}
adjSize = queue.size();
adjSize = edgeListQueue.size();
}
continue;
}
Expand All @@ -527,17 +543,32 @@ std::vector<Row> TraverseExecutor::buildPath(const Value& initVertex,
continue;
}
auto newEdgeListPtr = std::make_unique<std::vector<Value>>(*edgeListPtr);
newEdgeListPtr->emplace_back(dstIter->first);
newEdgeListPtr->emplace_back(edge);

std::unique_ptr<std::vector<Value>> newVertexEdgeListPtr = nullptr;
if (genPath_) {
newVertexEdgeListPtr = std::make_unique<std::vector<Value>>(*vertexEdgeListPtr);
newVertexEdgeListPtr->emplace_back(dstIter->first);
newVertexEdgeListPtr->emplace_back(edge);
}

if (step >= minStep) {
Row row;
row.values.emplace_back(src);
// only contain edges
row.values.emplace_back(List(*newEdgeListPtr));
if (genPath_) {
// contain nodes & edges
row.values.emplace_back(List(*newVertexEdgeListPtr));
}
newResult.emplace_back(std::move(row));
}
queue.emplace(newEdgeListPtr.get());
edgeListQueue.emplace(newEdgeListPtr.get());
holder.emplace_back(std::move(newEdgeListPtr));
if (genPath_ && newVertexEdgeListPtr != nullptr) {
queue.emplace(newVertexEdgeListPtr.get());
holder.emplace_back(std::move(newVertexEdgeListPtr));
}
}
if (adjSize == 0) {
if (++step > maxStep) {
Expand All @@ -548,8 +579,8 @@ std::vector<Row> TraverseExecutor::buildPath(const Value& initVertex,
}
if (minStep <= 1) {
newResult.insert(newResult.begin(),
std::make_move_iterator(result.begin()),
std::make_move_iterator(result.end()));
std::make_move_iterator(oneStepPath.begin()),
std::make_move_iterator(oneStepPath.end()));
}
if (traverse_->trackPrevPath()) {
return joinPrevPath(initVertex, newResult);
Expand All @@ -570,8 +601,7 @@ std::vector<Row> TraverseExecutor::joinPrevPath(const Value& initVertex,
if (!hasSameEdgeInPath(prevPath, p)) {
// copy
Row row = prevPath;
row.values.emplace_back(p.values.front());
row.values.emplace_back(p.values.back());
row.values.insert(row.values.end(), p.values.begin(), p.values.end());
newPaths.emplace_back(std::move(row));
}
}
Expand Down
1 change: 1 addition & 0 deletions src/graph/executor/query/TraverseExecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ class TraverseExecutor final : public StorageAccessExecutor {
private:
ObjectPool objPool_;

bool genPath_{false};
VidHashSet vids_;
std::vector<Value> initVertices_;
DataSet result_;
Expand Down
13 changes: 10 additions & 3 deletions src/graph/planner/match/MatchPathPlanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,17 @@ MatchPathPlanner::MatchPathPlanner(CypherClauseContextBase* ctx, const Path& pat
static std::vector<std::string> genTraverseColNames(const std::vector<std::string>& inputCols,
const NodeInfo& node,
const EdgeInfo& edge,
bool trackPrev) {
bool trackPrev,
bool genPath = false) {
std::vector<std::string> cols;
if (trackPrev) {
cols = inputCols;
}
cols.emplace_back(node.alias);
cols.emplace_back(edge.alias);
if (genPath) {
cols.emplace_back(edge.innerAlias);
}
return cols;
}

Expand Down Expand Up @@ -218,11 +222,13 @@ Status MatchPathPlanner::leftExpandFromNode(size_t startIndex, SubPlan& subplan)
traverse->setEdgeDirection(edge.direction);
traverse->setStepRange(stepRange);
traverse->setDedup();
traverse->setGenPath(path_.genPath);
// If start from end of the path pattern, the first traverse would not
// track the previous path, otherwise, it should.
bool trackPrevPath = (startIndex + 1 == nodeInfos.size() ? i != startIndex : true);
traverse->setTrackPrevPath(trackPrevPath);
traverse->setColNames(genTraverseColNames(subplan.root->colNames(), node, edge, trackPrevPath));
traverse->setColNames(
genTraverseColNames(subplan.root->colNames(), node, edge, trackPrevPath, path_.genPath));
subplan.root = traverse;
nextTraverseStart = genNextTraverseStart(qctx->objPool(), edge);
if (expandInto) {
Expand Down Expand Up @@ -290,8 +296,9 @@ Status MatchPathPlanner::rightExpandFromNode(size_t startIndex, SubPlan& subplan
traverse->setStepRange(stepRange);
traverse->setDedup();
traverse->setTrackPrevPath(i != startIndex);
traverse->setGenPath(path_.genPath);
traverse->setColNames(
genTraverseColNames(subplan.root->colNames(), node, edge, i != startIndex));
genTraverseColNames(subplan.root->colNames(), node, edge, i != startIndex, path_.genPath));
subplan.root = traverse;
nextTraverseStart = genNextTraverseStart(qctx->objPool(), edge);
if (expandInto) {
Expand Down
33 changes: 21 additions & 12 deletions src/graph/planner/match/MatchSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,21 +231,23 @@ static YieldColumn* buildVertexColumn(ObjectPool* pool, const std::string& alias
return new YieldColumn(InputPropertyExpression::make(pool, alias), alias);
}

static YieldColumn* buildEdgeColumn(QueryContext* qctx, const EdgeInfo& edge) {
static YieldColumn* buildEdgeColumn(QueryContext* qctx, const EdgeInfo& edge, bool genPath) {
Expression* expr = nullptr;
const std::string& edgeName = genPath ? edge.innerAlias : edge.alias;
auto pool = qctx->objPool();
if (edge.range == nullptr) {
expr = SubscriptExpression::make(
pool, InputPropertyExpression::make(pool, edge.alias), ConstantExpression::make(pool, 0));
pool, InputPropertyExpression::make(pool, edgeName), ConstantExpression::make(pool, 0));
} else {
auto innerVar = qctx->vctx()->anonVarGen()->getVar();
auto* args = ArgumentList::make(pool);
args->addArgument(VariableExpression::makeInner(pool, innerVar));
auto* filter = FunctionCallExpression::make(pool, "is_edge", args);
expr = ListComprehensionExpression::make(
pool, innerVar, InputPropertyExpression::make(pool, edge.alias), filter);
expr = InputPropertyExpression::make(pool, edgeName);
// auto innerVar = qctx->vctx()->anonVarGen()->getVar();
// auto* args = ArgumentList::make(pool);
// args->addArgument(VariableExpression::makeInner(pool, innerVar));
// auto* filter = FunctionCallExpression::make(pool, "is_edge", args);
// expr = ListComprehensionExpression::make(
// pool, innerVar, InputPropertyExpression::make(pool, edge.alias), filter);
}
return new YieldColumn(expr, edge.alias);
return new YieldColumn(expr, edgeName);
}

// static
Expand All @@ -262,16 +264,23 @@ void MatchSolver::buildProjectColumns(QueryContext* qctx, const Path& path, SubP
}
};

auto addEdge = [columns, &colNames, qctx](auto& edgeInfo) {
auto addEdge = [columns, &colNames, qctx](auto& edgeInfo, bool genPath = false) {
if (!edgeInfo.alias.empty() && !edgeInfo.anonymous) {
columns->addColumn(buildEdgeColumn(qctx, edgeInfo));
colNames.emplace_back(edgeInfo.alias);
columns->addColumn(buildEdgeColumn(qctx, edgeInfo, genPath));
if (genPath) {
colNames.emplace_back(edgeInfo.innerAlias);
} else {
colNames.emplace_back(edgeInfo.alias);
}
}
};

for (size_t i = 0; i < edgeInfos.size(); i++) {
addNode(nodeInfos[i]);
addEdge(edgeInfos[i]);
if (path.genPath) {
addEdge(edgeInfos[i], true);
}
}

// last vertex
Expand Down
1 change: 1 addition & 0 deletions src/graph/planner/plan/Query.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,7 @@ void Traverse::cloneMembers(const Traverse& g) {
if (g.tagFilter_ != nullptr) {
setTagFilter(g.tagFilter_->clone());
}
genPath_ = g.genPath();
}

std::unique_ptr<PlanNodeDescription> Traverse::explain() const {
Expand Down
9 changes: 9 additions & 0 deletions src/graph/planner/plan/Query.h
Original file line number Diff line number Diff line change
Expand Up @@ -1713,10 +1713,18 @@ class Traverse final : public GetNeighbors {
firstStepFilter_ = filter;
}

void setGenPath(bool genPath) {
genPath_ = genPath;
}

Expression* tagFilter() const {
return tagFilter_;
}

bool genPath() const {
return genPath_;
}

void setTagFilter(Expression* tagFilter) {
tagFilter_ = tagFilter;
}
Expand All @@ -1738,6 +1746,7 @@ class Traverse final : public GetNeighbors {
// Push down filter in first step
Expression* firstStepFilter_{nullptr};
Expression* tagFilter_{nullptr};
bool genPath_{false};
};

// Append vertices to a path.
Expand Down
3 changes: 2 additions & 1 deletion src/graph/validator/MatchValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ Status MatchValidator::buildPathExpr(const MatchPath *path,
auto pathBuild = PathBuildExpression::make(pool);
for (size_t i = 0; i < edgeInfos.size(); ++i) {
pathBuild->add(InputPropertyExpression::make(pool, nodeInfos[i].alias));
pathBuild->add(InputPropertyExpression::make(pool, edgeInfos[i].alias));
pathBuild->add(InputPropertyExpression::make(pool, edgeInfos[i].innerAlias));
}
pathBuild->add(InputPropertyExpression::make(pool, nodeInfos.back().alias));
pathInfo.pathBuild = std::move(pathBuild);
Expand Down Expand Up @@ -332,6 +332,7 @@ Status MatchValidator::buildEdgeInfo(const MatchPath *path,
edgeInfos[i].anonymous = anonymous;
edgeInfos[i].direction = direction;
edgeInfos[i].alias = alias;
edgeInfos[i].innerAlias = alias + "-";
edgeInfos[i].props = props;
edgeInfos[i].filter = filter;
}
Expand Down

0 comments on commit e4cc5bf

Please sign in to comment.