diff options
author | Ivan Frade <ifrade@google.com> | 2020-04-03 22:04:15 -0700 |
---|---|---|
committer | Ivan Frade <ifrade@google.com> | 2020-04-28 22:44:33 -0700 |
commit | 003002c1cbc140502eb9066b43c8c56796947f85 (patch) | |
tree | 0ee204bacce5168c73a2a9d93c71abf4bc65653a /org.eclipse.jgit/src/org/eclipse/jgit | |
parent | 20bb3124218ed93956450fb30a95b2277db590c5 (diff) | |
download | jgit-003002c1cbc140502eb9066b43c8c56796947f85.tar.gz jgit-003002c1cbc140502eb9066b43c8c56796947f85.zip |
revwalk: Introduce bitmap-based object reachability checker
Change-Id: I0b1a2bd21f98894862aab339f8c2e4a417897b89
Signed-off-by: Ivan Frade <ifrade@google.com>
Diffstat (limited to 'org.eclipse.jgit/src/org/eclipse/jgit')
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedObjectReachabilityChecker.java | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedObjectReachabilityChecker.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedObjectReachabilityChecker.java new file mode 100644 index 0000000000..252811dde6 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedObjectReachabilityChecker.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2020, Google LLC and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * https://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +package org.eclipse.jgit.revwalk; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; + +import org.eclipse.jgit.errors.IncorrectObjectTypeException; +import org.eclipse.jgit.errors.MissingObjectException; +import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder; + +/** + * Checks if all objects are reachable from certain starting points using + * bitmaps. + */ +public class BitmappedObjectReachabilityChecker + implements ObjectReachabilityChecker { + + private ObjectWalk walk; + + /** + * New instance of the reachability checker using a existing walk. + * + * @param walk + * ObjectWalk instance to reuse. Caller retains ownership. + */ + public BitmappedObjectReachabilityChecker(ObjectWalk walk) { + this.walk = walk; + } + + /** + * {@inheritDoc} + * + * This implementation tries to shortcut the check adding starters + * incrementally. Ordering the starters by relevance can improve performance + * in the average case. + */ + @Override + public Optional<RevObject> areAllReachable(Collection<RevObject> targets, + Stream<RevObject> starters) throws IOException { + + try { + List<RevObject> remainingTargets = new ArrayList<>(targets); + BitmapWalker bitmapWalker = new BitmapWalker(walk, + walk.getObjectReader().getBitmapIndex(), null); + + Iterator<RevObject> starterIt = starters.iterator(); + BitmapBuilder seen = null; + while (starterIt.hasNext()) { + List<RevObject> asList = Arrays.asList(starterIt.next()); + BitmapBuilder visited = bitmapWalker.findObjects(asList, seen, + true); + seen = seen == null ? visited : seen.or(visited); + + remainingTargets.removeIf(seen::contains); + if (remainingTargets.isEmpty()) { + return Optional.empty(); + } + } + + return Optional.of(remainingTargets.get(0)); + } catch (MissingObjectException | IncorrectObjectTypeException e) { + throw new IllegalStateException(e); + } + } +} |