ObjectReader: New #isNotLargerThan method

Partial clones filter the objects to send by size calling
ObjectReader#getObjectSize per object. This method reads the object from
storage to get the size, which can be expensive.

Offer a #isNotLargerThan method. The default implementation reads the
object, but subclasses can override it with more efficient lookups (e.g.
adding an index).

isNotLargerThan gives implementors more options to optimize than
getObjectIndex (e.g. can be implemented storing only object over certain
size).

Change-Id: Iefd4b1370cb9144f15cc0391286aeeb365e6ea87
This commit is contained in:
Ivan Frade 2021-12-03 16:11:10 -08:00
parent b398bb91ab
commit b58ea5c6c9
2 changed files with 43 additions and 10 deletions

View File

@ -2245,17 +2245,17 @@ private void filterAndAddObject(@NonNull AnyObjectId src, int type,
int pathHashCode, @NonNull Set<? extends AnyObjectId> want)
throws IOException {
// Check if this object needs to be rejected, doing the cheaper
// checks first.
boolean reject =
(!filterSpec.allowsType(type) && !want.contains(src)) ||
(filterSpec.getBlobLimit() >= 0 &&
type == OBJ_BLOB &&
!want.contains(src) &&
reader.getObjectSize(src, OBJ_BLOB) > filterSpec.getBlobLimit());
if (!reject) {
addObject(src, type, pathHashCode);
// Cheaper checks first
if (!filterSpec.allowsType(type) && !want.contains(src)) {
return;
}
long blobLimit = filterSpec.getBlobLimit();
if (blobLimit >= 0 && type == OBJ_BLOB && !want.contains(src)
&& !reader.isNotLargerThan(src, OBJ_BLOB, blobLimit)) {
return;
}
addObject(src, type, pathHashCode);
}
private boolean exclude(AnyObjectId objectId) {

View File

@ -332,6 +332,39 @@ public long getObjectSize(AnyObjectId objectId, int typeHint)
return open(objectId, typeHint).getSize();
}
/**
* Check if the object size is less or equal than certain value
*
* By default, it reads the object from storage to get the size. Subclasses
* can implement more efficient lookups.
*
* @param objectId
* identity of the object to open.
* @param typeHint
* hint about the type of object being requested, e.g.
* {@link org.eclipse.jgit.lib.Constants#OBJ_BLOB};
* {@link #OBJ_ANY} if the object type is not known, or does not
* matter to the caller.
* @param size
* threshold value for the size of the object in bytes.
* @return true if the object size is equal or smaller than the threshold
* value
* @throws org.eclipse.jgit.errors.MissingObjectException
* the object does not exist.
* @throws org.eclipse.jgit.errors.IncorrectObjectTypeException
* typeHint was not OBJ_ANY, and the object's actual type does
* not match typeHint.
* @throws java.io.IOException
* the object store cannot be accessed.
*
* @since 6.4
*/
public boolean isNotLargerThan(AnyObjectId objectId, int typeHint, long size)
throws MissingObjectException, IncorrectObjectTypeException,
IOException {
return open(objectId, typeHint).getSize() <= size;
}
/**
* Asynchronous object size lookup.
*