Browse Source

UploadPack: Use more relevant refs first in object reachability check

The bitmap-bassed object reachability checker, tries to find the objects
in the first starter, then adding the second starter... and so on. This
rewards passing the most popular refs first.

Order the refs with heads first, then tags, then others (e.g. changes)
for the object reachability checker. Using streams, delay also the
resolution of the ref to RevObject until necessary.

Change-Id: I9414b76754d7c0ffee1e2eeed6939895c8e92cbe
Signed-off-by: Ivan Frade <ifrade@google.com>
stable-5.8
Ivan Frade 4 years ago
parent
commit
c9d7285e80
  1. 33
      org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java

33
org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java

@ -1903,7 +1903,6 @@ public class UploadPack {
try (RevWalk walk = new RevWalk(reader)) {
walk.setRetainBody(false);
Set<ObjectId> reachableFrom = refIdSet(visibleRefs);
// Missing "wants" throw exception here
List<RevObject> wantsAsObjs = objectIdsToRevObjects(walk,
notAdvertisedWants);
@ -1930,12 +1929,15 @@ public class UploadPack {
}
try (ObjectWalk objWalk = walk.toObjectWalkWithSameObjects()) {
List<RevObject> havesAsObjs = objectIdsToRevObjects(objWalk,
reachableFrom);
Stream<RevObject> startersAsObjs = importantRefsFirst(visibleRefs)
.map(UploadPack::refToObjectId)
.map(objId -> objectIdToRevObject(objWalk, objId))
.filter(Objects::nonNull); // Ignore missing tips
ObjectReachabilityChecker reachabilityChecker = objWalk
.createObjectReachabilityChecker();
Optional<RevObject> unreachable = reachabilityChecker
.areAllReachable(wantsAsObjs, havesAsObjs.stream());
.areAllReachable(wantsAsObjs, startersAsObjs);
if (unreachable.isPresent()) {
throw new WantNotValidException(unreachable.get());
}
@ -2007,6 +2009,29 @@ public class UploadPack {
}
}
/**
* Translate an object id to a RevObject.
*
* @param walk
* walk on the relevant object storage
* @param objectId
* Object Id
* @return RevObject instance or null if the object is missing
*/
@Nullable
private static RevObject objectIdToRevObject(RevWalk walk,
ObjectId objectId) {
if (objectId == null) {
return null;
}
try {
return walk.parseAny(objectId);
} catch (IOException e) {
return null;
}
}
// Resolve the ObjectIds into RevObjects. Any missing object raises an
// exception
private static List<RevObject> objectIdsToRevObjects(RevWalk walk,

Loading…
Cancel
Save