Search in sources :

Example 1 with PathWeight

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<>();
}
Also used : HashMap(java.util.HashMap) Node(org.openkilda.pce.model.Node) PathWeight(org.openkilda.pce.model.PathWeight) LinkedList(java.util.LinkedList)

Aggregations

HashMap (java.util.HashMap)1 LinkedList (java.util.LinkedList)1 Node (org.openkilda.pce.model.Node)1 PathWeight (org.openkilda.pce.model.PathWeight)1