in hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/CustomizePathsTraverser.java [76:173]
public List<Path> customizedPaths(Iterator<Vertex> vertices,
List<WeightedEdgeStep> steps, boolean sorted,
long capacity, long limit) {
E.checkArgument(vertices.hasNext(),
"The source vertices can't be empty");
E.checkArgument(!steps.isEmpty(), "The steps can't be empty");
checkCapacity(capacity);
checkLimit(limit);
MultivaluedMap<Id, Node> sources = newMultivalueMap();
while (vertices.hasNext()) {
HugeVertex vertex = (HugeVertex) vertices.next();
Node node = sorted ?
new WeightNode(vertex.id(), null, 0) :
new Node(vertex.id(), null);
sources.add(vertex.id(), node);
}
int stepNum = steps.size();
int pathCount = 0;
long access = 0;
MultivaluedMap<Id, Node> newVertices = null;
root:
for (WeightedEdgeStep step : steps) {
stepNum--;
newVertices = newMultivalueMap();
Iterator<Edge> edges;
// Traversal vertices of previous level
for (Map.Entry<Id, List<Node>> entry : sources.entrySet()) {
List<Node> adjacency = newList();
edges = this.edgesOfVertex(entry.getKey(), step.step());
while (edges.hasNext()) {
HugeEdge edge = (HugeEdge) edges.next();
this.edgeIterCounter.addAndGet(1L);
Id target = edge.id().otherVertexId();
this.edgeResults.addEdge(entry.getKey(), target, edge);
for (Node n : entry.getValue()) {
// If have loop, skip target
if (n.contains(target)) {
continue;
}
Node newNode;
if (sorted) {
double w = step.weightBy() != null ?
edge.value(step.weightBy().name()) :
step.defaultWeight();
newNode = new WeightNode(target, n, w);
} else {
newNode = new Node(target, n);
}
adjacency.add(newNode);
checkCapacity(capacity, ++access, "customized paths");
}
}
if (step.sample() > 0) {
// Sample current node's adjacent nodes
adjacency = sample(adjacency, step.sample());
}
// Add current node's adjacent nodes
for (Node node : adjacency) {
newVertices.add(node.id(), node);
// Avoid exceeding limit
if (stepNum == 0) {
if (limit != NO_LIMIT && !sorted &&
++pathCount >= limit) {
break root;
}
}
}
}
this.vertexIterCounter.addAndGet(sources.size());
// Re-init sources
sources = newVertices;
}
if (stepNum != 0) {
return ImmutableList.of();
}
List<Path> paths = newList();
if (newVertices == null) {
return ImmutableList.of();
}
for (List<Node> nodes : newVertices.values()) {
for (Node n : nodes) {
if (sorted) {
WeightNode wn = (WeightNode) n;
paths.add(new WeightPath(wn.path(), wn.weights()));
} else {
paths.add(new Path(n.path()));
}
}
}
return paths;
}