diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/PackWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/PackWriter.java index 0c8210f64..4a205fffb 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/PackWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/PackWriter.java @@ -623,7 +623,7 @@ private void searchForReuse( selectDeltaReuseForObject(otp, reuseLoaders); } // delta reuse is preferred over object reuse - if (reuseObjects && !otp.hasReuseLoader()) { + if (reuseObjects && !otp.isCopyable()) { selectObjectReuseForObject(otp, reuseLoaders); } } @@ -649,7 +649,7 @@ && isBetterDeltaReuseLoader(bestLoader, loader)) { } if (bestLoader != null) { - otp.setReuseLoader(bestLoader); + otp.setCopyFromPack(bestLoader); otp.setDeltaBase(bestBase); } } @@ -670,7 +670,7 @@ private void selectObjectReuseForObject(final ObjectToPack otp, final Collection loaders) { for (final PackedObjectLoader loader : loaders) { if (loader instanceof WholePackedObjectLoader) { - otp.setReuseLoader(loader); + otp.setCopyFromPack(loader); return; } } @@ -703,7 +703,7 @@ private void writeObject(final ObjectToPack otp) throws IOException { if (deltaBase != null && !deltaBase.isWritten()) { if (deltaBase.wantWrite()) { otp.clearDeltaBase(); // cycle detected - otp.disposeLoader(); + otp.clearSourcePack(); } else { writeObject(deltaBase); } @@ -737,13 +737,9 @@ private void writeObject(final ObjectToPack otp) throws IOException { } private PackedObjectLoader open(final ObjectToPack otp) throws IOException { - for (;;) { - PackedObjectLoader reuse = otp.useLoader(); - if (reuse == null) { - return null; - } - + while (otp.isCopyable()) { try { + PackedObjectLoader reuse = otp.getCopyLoader(windowCursor); reuse.beginCopyRawData(); return reuse; } catch (IOException err) { @@ -751,10 +747,12 @@ private PackedObjectLoader open(final ObjectToPack otp) throws IOException { // it has been overwritten with a different layout. // otp.clearDeltaBase(); + otp.clearSourcePack(); searchForReuse(new ArrayList(), otp); continue; } } + return null; } private void writeWholeObjectDeflate(final ObjectToPack otp) @@ -904,9 +902,14 @@ public void addObject(final RevObject object) * */ static class ObjectToPack extends PackedObjectInfo { + /** Other object being packed that this will delta against. */ private ObjectId deltaBase; - private PackedObjectLoader reuseLoader; + /** Pack to reuse compressed data from, otherwise null. */ + private PackFile copyFromPack; + + /** Offset of the object's header in {@link #copyFromPack}. */ + private long copyOffset; /** * Bit field, from bit 0 to bit 31: @@ -989,22 +992,21 @@ boolean isWritten() { return getOffset() != 0; } - PackedObjectLoader useLoader() { - final PackedObjectLoader r = reuseLoader; - reuseLoader = null; - return r; + boolean isCopyable() { + return copyFromPack != null; } - boolean hasReuseLoader() { - return reuseLoader != null; + PackedObjectLoader getCopyLoader(WindowCursor curs) throws IOException { + return copyFromPack.resolveBase(curs, copyOffset); } - void setReuseLoader(PackedObjectLoader reuseLoader) { - this.reuseLoader = reuseLoader; + void setCopyFromPack(PackedObjectLoader loader) { + this.copyFromPack = loader.pack; + this.copyOffset = loader.objectOffset; } - void disposeLoader() { - this.reuseLoader = null; + void clearSourcePack() { + copyFromPack = null; } int getType() {