From b58ea5c6c90533614600e7ca06fa779532c734bc Mon Sep 17 00:00:00 2001 From: Ivan Frade Date: Fri, 3 Dec 2021 16:11:10 -0800 Subject: [PATCH] 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 --- .../internal/storage/pack/PackWriter.java | 20 +++++------ .../org/eclipse/jgit/lib/ObjectReader.java | 33 +++++++++++++++++++ 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java index 59aa5c908..8653c3228 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java @@ -2245,17 +2245,17 @@ private void filterAndAddObject(@NonNull AnyObjectId src, int type, int pathHashCode, @NonNull Set 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) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java index 26c3ff671..081f40e9d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java @@ -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. *