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>
This commit is contained in:
parent
a661e2e9eb
commit
c9d7285e80
|
@ -1903,7 +1903,6 @@ private static void checkNotAdvertisedWants(UploadPack up,
|
||||||
|
|
||||||
try (RevWalk walk = new RevWalk(reader)) {
|
try (RevWalk walk = new RevWalk(reader)) {
|
||||||
walk.setRetainBody(false);
|
walk.setRetainBody(false);
|
||||||
Set<ObjectId> reachableFrom = refIdSet(visibleRefs);
|
|
||||||
// Missing "wants" throw exception here
|
// Missing "wants" throw exception here
|
||||||
List<RevObject> wantsAsObjs = objectIdsToRevObjects(walk,
|
List<RevObject> wantsAsObjs = objectIdsToRevObjects(walk,
|
||||||
notAdvertisedWants);
|
notAdvertisedWants);
|
||||||
|
@ -1930,12 +1929,15 @@ private static void checkNotAdvertisedWants(UploadPack up,
|
||||||
}
|
}
|
||||||
|
|
||||||
try (ObjectWalk objWalk = walk.toObjectWalkWithSameObjects()) {
|
try (ObjectWalk objWalk = walk.toObjectWalkWithSameObjects()) {
|
||||||
List<RevObject> havesAsObjs = objectIdsToRevObjects(objWalk,
|
Stream<RevObject> startersAsObjs = importantRefsFirst(visibleRefs)
|
||||||
reachableFrom);
|
.map(UploadPack::refToObjectId)
|
||||||
|
.map(objId -> objectIdToRevObject(objWalk, objId))
|
||||||
|
.filter(Objects::nonNull); // Ignore missing tips
|
||||||
|
|
||||||
ObjectReachabilityChecker reachabilityChecker = objWalk
|
ObjectReachabilityChecker reachabilityChecker = objWalk
|
||||||
.createObjectReachabilityChecker();
|
.createObjectReachabilityChecker();
|
||||||
Optional<RevObject> unreachable = reachabilityChecker
|
Optional<RevObject> unreachable = reachabilityChecker
|
||||||
.areAllReachable(wantsAsObjs, havesAsObjs.stream());
|
.areAllReachable(wantsAsObjs, startersAsObjs);
|
||||||
if (unreachable.isPresent()) {
|
if (unreachable.isPresent()) {
|
||||||
throw new WantNotValidException(unreachable.get());
|
throw new WantNotValidException(unreachable.get());
|
||||||
}
|
}
|
||||||
|
@ -2007,6 +2009,29 @@ private static RevCommit objectIdToRevCommit(RevWalk walk,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
// Resolve the ObjectIds into RevObjects. Any missing object raises an
|
||||||
// exception
|
// exception
|
||||||
private static List<RevObject> objectIdsToRevObjects(RevWalk walk,
|
private static List<RevObject> objectIdsToRevObjects(RevWalk walk,
|
||||||
|
|
Loading…
Reference in New Issue