Search in sources :

Example 1 with GraphNode

use of org.locationtech.geogig.storage.GraphDatabase.GraphNode in project GeoGig by boundlessgeo.

the class CheckSparsePath method isSparsePath.

/**
     * Recursive brute force function to exhaustively search for all paths between the start and end
     * node. This should be optimized to avoid unnecessary work in the future.
     */
private boolean isSparsePath(GraphNode node, ObjectId end, boolean sparse) {
    if (node.getIdentifier().equals(end)) {
        return sparse;
    }
    Iterator<GraphEdge> outgoing = node.getEdges(Direction.OUT);
    if (outgoing.hasNext()) {
        boolean node_sparse = node.isSparse();
        boolean combined_sparse = false;
        while (outgoing.hasNext()) {
            GraphEdge parent = outgoing.next();
            GraphNode parentNode = parent.getToNode();
            combined_sparse = combined_sparse || isSparsePath(parentNode, end, sparse || node_sparse);
        }
        return combined_sparse;
    }
    return false;
}
Also used : GraphNode(org.locationtech.geogig.storage.GraphDatabase.GraphNode) GraphEdge(org.locationtech.geogig.storage.GraphDatabase.GraphEdge)

Example 2 with GraphNode

use of org.locationtech.geogig.storage.GraphDatabase.GraphNode in project GeoGig by boundlessgeo.

the class FindCommonAncestor method processCommit.

/**
     * Process a commit to see if it has already been seen. If it has, prevent unnecessary work from
     * continuing on the other traversal queue. If it hasn't, add it's parents to the traversal
     * queue.
     * 
     * @param commit commit to process
     * @param myQueue my traversal queue
     * @param mySet my visited nodes
     * @param theirQueue other traversal queue
     * @param theirSet other traversal's visited nodes
     * @return
     */
private boolean processCommit(GraphNode commit, Queue<GraphNode> myQueue, Set<GraphNode> mySet, Queue<GraphNode> theirQueue, Set<GraphNode> theirSet) {
    if (mySet.add(commit)) {
        if (theirSet.contains(commit)) {
            stopAncestryPath(commit, theirQueue, theirSet);
            return true;
        }
        Iterator<GraphEdge> edges = commit.getEdges(Direction.OUT);
        while (edges.hasNext()) {
            GraphEdge parentEdge = edges.next();
            GraphNode parent = parentEdge.getToNode();
            myQueue.add(parent);
        }
    }
    return false;
}
Also used : GraphNode(org.locationtech.geogig.storage.GraphDatabase.GraphNode) GraphEdge(org.locationtech.geogig.storage.GraphDatabase.GraphEdge)

Example 3 with GraphNode

use of org.locationtech.geogig.storage.GraphDatabase.GraphNode in project GeoGig by boundlessgeo.

the class FindCommonAncestor method verifyAncestors.

/**
     * This function is called at the end of the traversal to make sure none of our results have a
     * more recent ancestor in the result list.
     * 
     * @param potentialCommonAncestors the result list
     * @param leftSet the visited nodes of the left traversal
     * @param rightSet the visited nodes of the right traversal
     */
private void verifyAncestors(List<GraphNode> potentialCommonAncestors, Set<GraphNode> leftSet, Set<GraphNode> rightSet) {
    Queue<GraphNode> ancestorQueue = new LinkedList<GraphNode>();
    List<GraphNode> falseAncestors = new LinkedList<GraphNode>();
    List<GraphNode> processed = new LinkedList<GraphNode>();
    for (GraphNode v : potentialCommonAncestors) {
        if (falseAncestors.contains(v)) {
            continue;
        }
        ancestorQueue.add(v);
        while (!ancestorQueue.isEmpty()) {
            GraphNode ancestor = ancestorQueue.poll();
            Iterator<GraphEdge> edges = ancestor.getEdges(Direction.OUT);
            while (edges.hasNext()) {
                GraphEdge parent = edges.next();
                GraphNode parentNode = parent.getToNode();
                if (parentNode.getIdentifier() != ancestor.getIdentifier()) {
                    if (leftSet.contains(parentNode) || rightSet.contains(parentNode)) {
                        if (!processed.contains(parentNode)) {
                            ancestorQueue.add(parentNode);
                            processed.add(parentNode);
                        }
                        if (potentialCommonAncestors.contains(parentNode)) {
                            falseAncestors.add(parentNode);
                        }
                    }
                }
            }
        }
    }
    potentialCommonAncestors.removeAll(falseAncestors);
}
Also used : GraphNode(org.locationtech.geogig.storage.GraphDatabase.GraphNode) GraphEdge(org.locationtech.geogig.storage.GraphDatabase.GraphEdge) LinkedList(java.util.LinkedList)

Example 4 with GraphNode

use of org.locationtech.geogig.storage.GraphDatabase.GraphNode in project GeoGig by boundlessgeo.

the class FindCommonAncestor method stopAncestryPath.

/**
     * This function is called when a common ancestor is found and the other traversal queue should
     * stop traversing down the history of that particular commit. Any ancestors caught after this
     * one will be an older ancestor. This function follows the ancestry of the common ancestor
     * until it has been removed from the opposite traversal queue.
     * 
     * @param commit the common ancestor
     * @param theirQueue the opposite traversal queue
     * @param theirSet the opposite visited nodes
     */
private void stopAncestryPath(GraphNode commit, Queue<GraphNode> theirQueue, Set<GraphNode> theirSet) {
    Queue<GraphNode> ancestorQueue = new LinkedList<GraphNode>();
    ancestorQueue.add(commit);
    Set<GraphNode> processed = new HashSet<GraphNode>();
    while (!ancestorQueue.isEmpty()) {
        GraphNode ancestor = ancestorQueue.poll();
        Iterator<GraphEdge> edges = ancestor.getEdges(Direction.OUT);
        while (edges.hasNext()) {
            GraphEdge relationship = edges.next();
            GraphNode parentNode = relationship.getToNode();
            if (theirSet.contains(parentNode)) {
                if (!processed.contains(parentNode)) {
                    ancestorQueue.add(parentNode);
                    processed.add(parentNode);
                }
            } else {
                theirQueue.remove(parentNode);
            }
        }
    }
}
Also used : GraphNode(org.locationtech.geogig.storage.GraphDatabase.GraphNode) GraphEdge(org.locationtech.geogig.storage.GraphDatabase.GraphEdge) LinkedList(java.util.LinkedList) HashSet(java.util.HashSet)

Example 5 with GraphNode

use of org.locationtech.geogig.storage.GraphDatabase.GraphNode in project GeoGig by boundlessgeo.

the class FindCommonAncestor method findLowestCommonAncestor.

/**
     * Finds the lowest common ancestor of two commits.
     * 
     * @param leftId the commit id of the left commit
     * @param rightId the commit id of the right commit
     * @return An {@link Optional} of the lowest common ancestor of the two commits, or
     *         {@link Optional#absent()} if a common ancestor could not be found.
     */
public Optional<ObjectId> findLowestCommonAncestor(ObjectId leftId, ObjectId rightId) {
    Set<GraphNode> leftSet = new HashSet<GraphNode>();
    Set<GraphNode> rightSet = new HashSet<GraphNode>();
    Queue<GraphNode> leftQueue = new LinkedList<GraphNode>();
    Queue<GraphNode> rightQueue = new LinkedList<GraphNode>();
    GraphDatabase graphDb = graphDatabase();
    GraphNode leftNode = graphDb.getNode(leftId);
    leftQueue.add(leftNode);
    GraphNode rightNode = graphDb.getNode(rightId);
    rightQueue.add(rightNode);
    List<GraphNode> potentialCommonAncestors = new LinkedList<GraphNode>();
    while (!leftQueue.isEmpty() || !rightQueue.isEmpty()) {
        if (!leftQueue.isEmpty()) {
            GraphNode commit = leftQueue.poll();
            if (processCommit(commit, leftQueue, leftSet, rightQueue, rightSet)) {
                potentialCommonAncestors.add(commit);
            }
        }
        if (!rightQueue.isEmpty()) {
            GraphNode commit = rightQueue.poll();
            if (processCommit(commit, rightQueue, rightSet, leftQueue, leftSet)) {
                potentialCommonAncestors.add(commit);
            }
        }
    }
    verifyAncestors(potentialCommonAncestors, leftSet, rightSet);
    Optional<ObjectId> ancestor = Optional.absent();
    if (potentialCommonAncestors.size() > 0) {
        ancestor = Optional.of(potentialCommonAncestors.get(0).getIdentifier());
    }
    return ancestor;
}
Also used : GraphDatabase(org.locationtech.geogig.storage.GraphDatabase) ObjectId(org.locationtech.geogig.api.ObjectId) GraphNode(org.locationtech.geogig.storage.GraphDatabase.GraphNode) LinkedList(java.util.LinkedList) HashSet(java.util.HashSet)

Aggregations

GraphNode (org.locationtech.geogig.storage.GraphDatabase.GraphNode)6 GraphEdge (org.locationtech.geogig.storage.GraphDatabase.GraphEdge)4 LinkedList (java.util.LinkedList)3 HashSet (java.util.HashSet)2 ObjectId (org.locationtech.geogig.api.ObjectId)1 GraphDatabase (org.locationtech.geogig.storage.GraphDatabase)1