in hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/algorithm/SingleSourceShortestPathTraverser.java [244:309]
public void forward() {
long degree = this.skipDegree > 0L ? this.skipDegree : this.degree;
for (NodeWithWeight node : this.sources) {
Iterator<Edge> edges = edgesOfVertex(node.node().id(),
this.direction,
this.label, degree);
edges = this.skipSuperNodeIfNeeded(edges);
while (edges.hasNext()) {
HugeEdge edge = (HugeEdge) edges.next();
Id target = edge.id().otherVertexId();
this.edgeCount += 1L;
if (this.foundNodes.containsKey(target) ||
this.source.equals(target)) {
// Already find shortest path for target, skip
continue;
}
this.edgeRecord.addEdge(node.node().id(), target, edge);
double currentWeight = this.edgeWeight(edge);
double weight = currentWeight + node.weight();
NodeWithWeight nw = new NodeWithWeight(weight, target, node);
NodeWithWeight exist = this.findingNodes.get(target);
if (exist == null || weight < exist.weight()) {
/*
* There are 2 scenarios to update finding nodes:
* 1. The 'target' found first time, add current path
* 2. Already exist path for 'target' and current
* path is shorter, update path for 'target'
*/
this.findingNodes.put(target, nw);
}
}
}
this.vertexCount += sources.size();
Map<Id, NodeWithWeight> sorted = CollectionUtil.sortByValue(
this.findingNodes, true);
double minWeight = 0;
Set<NodeWithWeight> newSources = InsertionOrderUtil.newSet();
for (Map.Entry<Id, NodeWithWeight> entry : sorted.entrySet()) {
Id id = entry.getKey();
NodeWithWeight wn = entry.getValue();
if (minWeight == 0) {
minWeight = wn.weight();
} else if (wn.weight() > minWeight) {
break;
}
// Move shortest paths from 'findingNodes' to 'foundNodes'
this.foundNodes.put(id, wn);
if (this.limit != NO_LIMIT &&
this.foundNodes.size() >= this.limit) {
this.done = true;
return;
}
this.findingNodes.remove(id);
// Re-init 'sources'
newSources.add(wn);
}
this.sources = newSources;
if (this.sources.isEmpty()) {
this.done = true;
}
}