diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsObjectRepresentation.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsObjectRepresentation.java index 1b8e3a3d4..2b45ffa20 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsObjectRepresentation.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsObjectRepresentation.java @@ -43,7 +43,11 @@ package org.eclipse.jgit.storage.dfs; +import static org.eclipse.jgit.storage.dfs.DfsObjDatabase.PackSource.GC; +import static org.eclipse.jgit.storage.dfs.DfsObjDatabase.PackSource.UNREACHABLE_GARBAGE; + import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.storage.dfs.DfsObjDatabase.PackSource; import org.eclipse.jgit.storage.pack.ObjectToPack; import org.eclipse.jgit.storage.pack.StoredObjectRepresentation; @@ -87,4 +91,13 @@ class DfsObjectRepresentation extends StoredObjectRepresentation { public ObjectId getDeltaBase() { return baseId; } + + @Override + public boolean wasDeltaAttempted() { + if (pack != null) { + PackSource source = pack.getPackDescription().getPackSource(); + return source == GC || source == UNREACHABLE_GARBAGE; + } + return false; + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsPackDescription.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsPackDescription.java index 1bd5a7827..6b90454b9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsPackDescription.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsPackDescription.java @@ -46,6 +46,7 @@ package org.eclipse.jgit.storage.dfs; import java.util.Set; import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.storage.dfs.DfsObjDatabase.PackSource; import org.eclipse.jgit.storage.pack.PackWriter; /** @@ -61,6 +62,8 @@ public class DfsPackDescription implements Comparable { private final String packName; + private PackSource packSource; + private long lastModified; private long packSize; @@ -114,6 +117,21 @@ public class DfsPackDescription implements Comparable { return name.substring(0, dot) + ".idx"; } + /** @return the source of the pack. */ + public PackSource getPackSource() { + return packSource; + } + + /** + * @param source + * the source of the pack. + * @return {@code this} + */ + public DfsPackDescription setPackSource(PackSource source) { + packSource = source; + return this; + } + /** @return time the pack was created, in milliseconds. */ public long getLastModified() { return lastModified; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/InMemoryRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/InMemoryRepository.java index 270f23fae..d1ceae00c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/InMemoryRepository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/InMemoryRepository.java @@ -76,8 +76,10 @@ public class InMemoryRepository extends DfsRepository { @Override protected DfsPackDescription newPack(PackSource source) { int id = packId.incrementAndGet(); - return new MemPack("pack-" + id + "-" + source.name(), + DfsPackDescription desc = new MemPack( + "pack-" + id + "-" + source.name(), getRepository().getDescription()); + return desc.setPackSource(source); } @Override diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/DeltaWindow.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/DeltaWindow.java index 07dcd943c..fead2147b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/DeltaWindow.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/DeltaWindow.java @@ -141,7 +141,7 @@ class DeltaWindow { } res.set(toSearch[off]); - if (res.object.isEdge()) { + if (res.object.isEdge() || res.object.doNotAttemptDelta()) { // We don't actually want to make a delta for // them, just need to push them into the window // so they can be read by other objects. diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/ObjectToPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/ObjectToPack.java index 1f4e3e7e2..9c50f8d01 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/ObjectToPack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/ObjectToPack.java @@ -66,6 +66,10 @@ public class ObjectToPack extends PackedObjectInfo { private static final int EDGE = 1 << 3; + private static final int DELTA_ATTEMPTED = 1 << 4; + + private static final int ATTEMPT_DELTA_MASK = REUSE_AS_IS | DELTA_ATTEMPTED; + private static final int TYPE_SHIFT = 5; private static final int EXT_SHIFT = 8; @@ -88,7 +92,7 @@ public class ObjectToPack extends PackedObjectInfo { *
  • 1 bit: canReuseAsIs
  • *
  • 1 bit: doNotDelta
  • *
  • 1 bit: edgeObject
  • - *
  • 1 bit: unused
  • + *
  • 1 bit: deltaAttempted
  • *
  • 3 bits: type
  • *
  • 4 bits: subclass flags (if any)
  • *
  • --
  • @@ -265,6 +269,22 @@ public class ObjectToPack extends PackedObjectInfo { flags |= EDGE; } + boolean doNotAttemptDelta() { + // Do not attempt if delta attempted and object reuse. + return (flags & ATTEMPT_DELTA_MASK) == ATTEMPT_DELTA_MASK; + } + + boolean isDeltaAttempted() { + return (flags & DELTA_ATTEMPTED) != 0; + } + + void setDeltaAttempted(boolean deltaAttempted) { + if (deltaAttempted) + flags |= DELTA_ATTEMPTED; + else + flags &= ~DELTA_ATTEMPTED; + } + /** @return the extended flags on this object, in the range [0x0, 0xf]. */ protected int getExtendedFlags() { return (flags >>> EXT_SHIFT) & EXT_MASK; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java index d93e2d680..99ec75cf9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java @@ -1870,6 +1870,7 @@ public class PackWriter { otp.clearReuseAsIs(); } + otp.setDeltaAttempted(next.wasDeltaAttempted()); otp.select(next); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/StoredObjectRepresentation.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/StoredObjectRepresentation.java index 334ea5ea1..543bc2f79 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/StoredObjectRepresentation.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/StoredObjectRepresentation.java @@ -72,8 +72,9 @@ public class StoredObjectRepresentation { } /** - * @return true if this is a delta against another object and this is stored - * in pack delta format. + * @return the storage format type, which must be one of + * {@link #PACK_DELTA}, {@link #PACK_WHOLE}, or + * {@link #FORMAT_OTHER}. */ public int getFormat() { return FORMAT_OTHER; @@ -87,4 +88,13 @@ public class StoredObjectRepresentation { public ObjectId getDeltaBase() { return null; } + + /** + * @return whether the current representation of the object has had delta + * compression attempted on it. + */ + public boolean wasDeltaAttempted() { + int fmt = getFormat(); + return fmt == PACK_DELTA || fmt == PACK_WHOLE; + } }