|
|
@@ -623,7 +623,7 @@ public class PackWriter { |
|
|
|
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 @@ public class PackWriter { |
|
|
|
} |
|
|
|
|
|
|
|
if (bestLoader != null) { |
|
|
|
otp.setReuseLoader(bestLoader); |
|
|
|
otp.setCopyFromPack(bestLoader); |
|
|
|
otp.setDeltaBase(bestBase); |
|
|
|
} |
|
|
|
} |
|
|
@@ -670,7 +670,7 @@ public class PackWriter { |
|
|
|
final Collection<PackedObjectLoader> loaders) { |
|
|
|
for (final PackedObjectLoader loader : loaders) { |
|
|
|
if (loader instanceof WholePackedObjectLoader) { |
|
|
|
otp.setReuseLoader(loader); |
|
|
|
otp.setCopyFromPack(loader); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
@@ -703,7 +703,7 @@ public class PackWriter { |
|
|
|
if (deltaBase != null && !deltaBase.isWritten()) { |
|
|
|
if (deltaBase.wantWrite()) { |
|
|
|
otp.clearDeltaBase(); // cycle detected |
|
|
|
otp.disposeLoader(); |
|
|
|
otp.clearSourcePack(); |
|
|
|
} else { |
|
|
|
writeObject(deltaBase); |
|
|
|
} |
|
|
@@ -737,13 +737,9 @@ public class PackWriter { |
|
|
|
} |
|
|
|
|
|
|
|
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 @@ public class PackWriter { |
|
|
|
// it has been overwritten with a different layout. |
|
|
|
// |
|
|
|
otp.clearDeltaBase(); |
|
|
|
otp.clearSourcePack(); |
|
|
|
searchForReuse(new ArrayList<PackedObjectLoader>(), otp); |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
private void writeWholeObjectDeflate(final ObjectToPack otp) |
|
|
@@ -904,9 +902,14 @@ public class PackWriter { |
|
|
|
* |
|
|
|
*/ |
|
|
|
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 @@ public class PackWriter { |
|
|
|
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() { |