UploadPack: Refactor to generalize the object reachability checks
ObjectWalk#createObjectReachabilityChecker() returns the best implementation for the repo. UploadPack can use the interface and fold the with/without commits cases in one code path. Change-Id: I857c11735d1d8e36c3ed8185ff11de8a62e86540 Signed-off-by: Ivan Frade <ifrade@google.com>
This commit is contained in:
parent
6bc04bdc02
commit
a661e2e9eb
|
@ -42,7 +42,7 @@ class BitmappedReachabilityChecker implements ReachabilityChecker {
|
|||
* @throws IOException
|
||||
* if the index or the object reader cannot be opened.
|
||||
*/
|
||||
public BitmappedReachabilityChecker(RevWalk walk)
|
||||
BitmappedReachabilityChecker(RevWalk walk)
|
||||
throws IOException {
|
||||
this.walk = walk;
|
||||
if (walk.getObjectReader().getBitmapIndex() == null) {
|
||||
|
|
|
@ -159,6 +159,29 @@ public ObjectWalk(ObjectReader or) {
|
|||
pathBuf = new byte[256];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an object reachability checker that will use bitmaps if possible.
|
||||
*
|
||||
* This reachability checker accepts any object as target. For checks
|
||||
* exclusively between commits, see
|
||||
* {@link RevWalk#createReachabilityChecker()}.
|
||||
*
|
||||
* @return an object reachability checker, using bitmaps if possible.
|
||||
*
|
||||
* @throws IOException
|
||||
* when the index fails to load.
|
||||
*
|
||||
* @since 5.8
|
||||
*/
|
||||
public ObjectReachabilityChecker createObjectReachabilityChecker()
|
||||
throws IOException {
|
||||
if (reader.getBitmapIndex() != null) {
|
||||
return new BitmappedObjectReachabilityChecker(this);
|
||||
}
|
||||
|
||||
return new PedestrianObjectReachabilityChecker(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark an object or commit to start graph traversal from.
|
||||
* <p>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
* Checks if all objects are reachable from certain starting points doing a
|
||||
* walk.
|
||||
*/
|
||||
public class PedestrianObjectReachabilityChecker implements ObjectReachabilityChecker {
|
||||
class PedestrianObjectReachabilityChecker implements ObjectReachabilityChecker {
|
||||
private ObjectWalk walk;
|
||||
|
||||
/**
|
||||
|
@ -31,7 +31,7 @@ public class PedestrianObjectReachabilityChecker implements ObjectReachabilityCh
|
|||
* @param walk
|
||||
* ObjectWalk instance to reuse. Caller retains ownership.
|
||||
*/
|
||||
public PedestrianObjectReachabilityChecker(ObjectWalk walk) {
|
||||
PedestrianObjectReachabilityChecker(ObjectWalk walk) {
|
||||
this.walk = walk;
|
||||
}
|
||||
|
||||
|
|
|
@ -75,11 +75,9 @@
|
|||
import org.eclipse.jgit.lib.RefDatabase;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.revwalk.AsyncRevObjectQueue;
|
||||
import org.eclipse.jgit.revwalk.BitmappedObjectReachabilityChecker;
|
||||
import org.eclipse.jgit.revwalk.DepthWalk;
|
||||
import org.eclipse.jgit.revwalk.ObjectReachabilityChecker;
|
||||
import org.eclipse.jgit.revwalk.ObjectWalk;
|
||||
import org.eclipse.jgit.revwalk.PedestrianObjectReachabilityChecker;
|
||||
import org.eclipse.jgit.revwalk.ReachabilityChecker;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.eclipse.jgit.revwalk.RevFlag;
|
||||
|
@ -1918,44 +1916,24 @@ private static void checkNotAdvertisedWants(UploadPack up,
|
|||
boolean repoHasBitmaps = reader.getBitmapIndex() != null;
|
||||
|
||||
if (!allWantsAreCommits) {
|
||||
if (!repoHasBitmaps) {
|
||||
if (up.transferConfig.isAllowFilter()) {
|
||||
// Use allowFilter as an indication that the server
|
||||
// operator is willing to pay the cost of these
|
||||
// reachability checks.
|
||||
try (ObjectWalk objWalk = walk.toObjectWalkWithSameObjects()) {
|
||||
List<RevObject> havesAsObjs = objectIdsToRevObjects(
|
||||
objWalk, reachableFrom);
|
||||
ObjectReachabilityChecker reachabilityChecker = new PedestrianObjectReachabilityChecker(
|
||||
objWalk);
|
||||
Optional<RevObject> unreachable = reachabilityChecker
|
||||
.areAllReachable(wantsAsObjs,
|
||||
havesAsObjs.stream());
|
||||
if (unreachable.isPresent()) {
|
||||
throw new WantNotValidException(
|
||||
unreachable.get());
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If unadvertized non-commits are requested, use
|
||||
// bitmaps. If there are no bitmaps, instead of
|
||||
// incurring the expense of a manual walk, reject
|
||||
// the request.
|
||||
if (!repoHasBitmaps && !up.transferConfig.isAllowFilter()) {
|
||||
// Checking unadvertised non-commits without bitmaps
|
||||
// requires an expensive manual walk. Use allowFilter as an
|
||||
// indication that the server operator is willing to pay
|
||||
// this cost. Reject the request otherwise.
|
||||
RevObject nonCommit = wantsAsObjs
|
||||
.stream()
|
||||
.filter(obj -> !(obj instanceof RevCommit))
|
||||
.limit(1)
|
||||
.collect(Collectors.toList()).get(0);
|
||||
throw new WantNotValidException(nonCommit);
|
||||
|
||||
}
|
||||
|
||||
try (ObjectWalk objWalk = walk.toObjectWalkWithSameObjects()) {
|
||||
List<RevObject> havesAsObjs = objectIdsToRevObjects(objWalk,
|
||||
reachableFrom);
|
||||
ObjectReachabilityChecker reachabilityChecker = new BitmappedObjectReachabilityChecker(
|
||||
objWalk);
|
||||
ObjectReachabilityChecker reachabilityChecker = objWalk
|
||||
.createObjectReachabilityChecker();
|
||||
Optional<RevObject> unreachable = reachabilityChecker
|
||||
.areAllReachable(wantsAsObjs, havesAsObjs.stream());
|
||||
if (unreachable.isPresent()) {
|
||||
|
|
Loading…
Reference in New Issue