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 1af3cb2de..d0351f867 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java @@ -135,6 +135,34 @@ public abstract class ObjectReader { throws MissingObjectException, IncorrectObjectTypeException, IOException; + /** + * Get only the size of an object. + *
+ * The default implementation of this method opens an ObjectLoader. + * Databases are encouraged to override this if a faster access method is + * available to them. + * + * @param objectId + * identity of the object to open. + * @param typeHint + * hint about the type of object being requested; + * {@link #OBJ_ANY} if the object type is not known, or does not + * matter to the caller. + * @return size of object in bytes. + * @throws MissingObjectException + * the object does not exist. + * @throws IncorrectObjectTypeException + * typeHint was not OBJ_ANY, and the object's actual type does + * not match typeHint. + * @throws IOException + * the object store cannot be accessed. + */ + public long getObjectSize(AnyObjectId objectId, int typeHint) + throws MissingObjectException, IncorrectObjectTypeException, + IOException { + return open(objectId, typeHint).getSize(); + } + /** * Release any resources used by this reader. *
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/CachedObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/CachedObjectDirectory.java
index 505850c42..8ea0b854c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/CachedObjectDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/CachedObjectDirectory.java
@@ -186,6 +186,20 @@ class CachedObjectDirectory extends FileObjectDatabase {
throw new UnsupportedOperationException();
}
+ @Override
+ long getObjectSize1(WindowCursor curs, AnyObjectId objectId) throws IOException {
+ if (unpackedObjects.contains(objectId))
+ return wrapped.getObjectSize2(curs, objectId.name(), objectId);
+ return wrapped.getObjectSize1(curs, objectId);
+ }
+
+ @Override
+ long getObjectSize2(WindowCursor curs, String objectName, AnyObjectId objectId)
+ throws IOException {
+ // This method should never be invoked.
+ throw new UnsupportedOperationException();
+ }
+
@Override
void selectObjectRepresentation(PackWriter packer, ObjectToPack otp,
WindowCursor curs) throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileObjectDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileObjectDatabase.java
index 444fd809b..250c7cac0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileObjectDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileObjectDatabase.java
@@ -166,6 +166,55 @@ abstract class FileObjectDatabase extends ObjectDatabase {
return null;
}
+ long getObjectSize(WindowCursor curs, AnyObjectId objectId)
+ throws IOException {
+ long sz = getObjectSizeImpl1(curs, objectId);
+ if (0 <= sz)
+ return sz;
+ return getObjectSizeImpl2(curs, objectId.name(), objectId);
+ }
+
+ final long getObjectSizeImpl1(final WindowCursor curs,
+ final AnyObjectId objectId) throws IOException {
+ long sz;
+
+ sz = getObjectSize1(curs, objectId);
+ if (0 <= sz)
+ return sz;
+
+ for (final AlternateHandle alt : myAlternates()) {
+ sz = alt.db.getObjectSizeImpl1(curs, objectId);
+ if (0 <= sz)
+ return sz;
+ }
+
+ if (tryAgain1()) {
+ sz = getObjectSize1(curs, objectId);
+ if (0 <= sz)
+ return sz;
+ }
+
+ return -1;
+ }
+
+ final long getObjectSizeImpl2(final WindowCursor curs,
+ final String objectName, final AnyObjectId objectId)
+ throws IOException {
+ long sz;
+
+ sz = getObjectSize2(curs, objectName, objectId);
+ if (0 <= sz)
+ return sz;
+
+ for (final AlternateHandle alt : myAlternates()) {
+ sz = alt.db.getObjectSizeImpl2(curs, objectName, objectId);
+ if (0 <= sz)
+ return sz;
+ }
+
+ return -1;
+ }
+
abstract void selectObjectRepresentation(PackWriter packer,
ObjectToPack otp, WindowCursor curs) throws IOException;
@@ -185,6 +234,12 @@ abstract class FileObjectDatabase extends ObjectDatabase {
abstract ObjectLoader openObject2(WindowCursor curs, String objectName,
AnyObjectId objectId) throws IOException;
+ abstract long getObjectSize1(WindowCursor curs, AnyObjectId objectId)
+ throws IOException;
+
+ abstract long getObjectSize2(WindowCursor curs, String objectName,
+ AnyObjectId objectId) throws IOException;
+
abstract FileObjectDatabase newCachedFileObjectDatabase();
abstract int getStreamFileThreshold();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectory.java
index 8177155f4..6fe4fd754 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectory.java
@@ -304,6 +304,46 @@ public class ObjectDirectory extends FileObjectDatabase implements
}
}
+ long getObjectSize1(final WindowCursor curs, final AnyObjectId objectId)
+ throws IOException {
+ PackList pList = packList.get();
+ SEARCH: for (;;) {
+ for (final PackFile p : pList.packs) {
+ try {
+ long sz = p.getObjectSize(curs, objectId);
+ if (0 <= sz)
+ return sz;
+ } catch (PackMismatchException e) {
+ // Pack was modified; refresh the entire pack list.
+ //
+ pList = scanPacks(pList);
+ continue SEARCH;
+ } catch (IOException e) {
+ // Assume the pack is corrupted.
+ //
+ removePack(p);
+ }
+ }
+ return -1;
+ }
+ }
+
+ @Override
+ long getObjectSize2(WindowCursor curs, String objectName,
+ AnyObjectId objectId) throws IOException {
+ try {
+ File path = fileFor(objectName);
+ FileInputStream in = new FileInputStream(path);
+ try {
+ return UnpackedObject.getSize(in, objectId, curs);
+ } finally {
+ in.close();
+ }
+ } catch (FileNotFoundException noFile) {
+ return -1;
+ }
+ }
+
@Override
void selectObjectRepresentation(PackWriter packer, ObjectToPack otp,
WindowCursor curs) throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/PackFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/PackFile.java
index 40bb07100..e74a7c014 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/PackFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/PackFile.java
@@ -779,6 +779,59 @@ public class PackFile implements Iterable