use of org.openkilda.pce.model.PathWeight in project open-kilda by telstra.
the class BestWeightAndShortestPathFinder method getPath.
/**
* Call this method to find a path from start to end (srcDpid to dstDpid), particularly if you have no idea if the
* path exists or what the best path is.
*
* @return A pair of ordered lists that represents the path from start to end, or an empty list
*/
private List<Edge> getPath(Node start, Node end, WeightFunction weightFunction) {
PathWeight bestWeight = new PathWeight(Long.MAX_VALUE);
SearchNode bestPath = null;
// working list
Deque<SearchNode> toVisit = new LinkedList<>();
Map<Node, SearchNode> visited = new HashMap<>();
toVisit.add(new SearchNode(weightFunction, start, allowedDepth, new PathWeight(), emptyList()));
while (!toVisit.isEmpty()) {
SearchNode current = toVisit.pop();
log.trace("Going to visit node {} with weight {}.", current.dstSw, current.getParentWeight().toLong());
// Determine if this node is the destination node.
if (current.dstSw.equals(end)) {
// We found the destination
if (current.parentWeight.compareTo(bestWeight) < 0) {
// We found a best path. If we don't get here, then the entire graph will be
// searched until we run out of nodes or the depth is reached.
bestWeight = current.parentWeight;
bestPath = current;
}
// We found dest, no need to keep processing
log.trace("Found destination using {} with path {}", current.dstSw, current.parentPath);
continue;
}
// Otherwise, if we've been here before, see if this path is better
SearchNode prior = visited.get(current.dstSw);
if (prior != null && current.parentWeight.compareTo(prior.parentWeight) >= 0) {
continue;
}
// Stop processing entirely if we've gone too far, or over bestWeight
if (current.allowedDepth <= 0 || current.parentWeight.compareTo(bestWeight) > 0) {
log.trace("Skip node {} processing", current.dstSw);
continue;
}
// Either this is the first time, or this one has less weight .. either way, this node should
// be the one in the visited list
visited.put(current.dstSw, current);
log.trace("Save new path to node {} and process it's outgoing links", current.dstSw);
// At this stage .. haven't found END, haven't gone too deep, and we are not over weight.
// So, add the outbound isls.
current.dstSw.getOutgoingLinks().stream().sorted(Comparator.comparing(edge -> edge.getDestSwitch().getSwitchId())).forEach(edge -> toVisit.add(current.addNode(edge)));
}
return (bestPath != null) ? bestPath.parentPath : new LinkedList<>();
}
Aggregations