Browse Source

PackWriter: support excluding objects already in other packs

This can be useful when implementing garbage collection and there
are packs that should not be copied, such as huge packs that have
a sibling ".keep" file alongside of them.

Callers driving PackWriter need to initialize the list of packs not
to include objects from by passing each index to excludeObjects().

Change-Id: Id7f34df69df97be406bcae184308e92b0e8690fd
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
stable-1.1
Shawn O. Pearce 13 years ago committed by Chris Aniszczyk
parent
commit
a1a8c6d77e
  1. 48
      org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java

48
org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java

@ -99,6 +99,7 @@ import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevSort; import org.eclipse.jgit.revwalk.RevSort;
import org.eclipse.jgit.revwalk.RevTag; import org.eclipse.jgit.revwalk.RevTag;
import org.eclipse.jgit.revwalk.RevTree; import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.storage.file.PackIndex;
import org.eclipse.jgit.storage.file.PackIndexWriter; import org.eclipse.jgit.storage.file.PackIndexWriter;
import org.eclipse.jgit.util.BlockList; import org.eclipse.jgit.util.BlockList;
import org.eclipse.jgit.util.TemporaryBuffer; import org.eclipse.jgit.util.TemporaryBuffer;
@ -157,6 +158,10 @@ public class PackWriter {
private Set<ObjectId> tagTargets = Collections.emptySet(); private Set<ObjectId> tagTargets = Collections.emptySet();
private PackIndex[] excludeInPacks;
private PackIndex excludeInPackLast;
private Deflater myDeflater; private Deflater myDeflater;
private final ObjectReader reader; private final ObjectReader reader;
@ -425,6 +430,25 @@ public class PackWriter {
return stats.totalObjects; return stats.totalObjects;
} }
/**
* Add a pack index whose contents should be excluded from the result.
*
* @param idx
* objects in this index will not be in the output pack.
*/
public void excludeObjects(PackIndex idx) {
if (excludeInPacks == null) {
excludeInPacks = new PackIndex[] { idx };
excludeInPackLast = idx;
} else {
int cnt = excludeInPacks.length;
PackIndex[] newList = new PackIndex[cnt + 1];
System.arraycopy(excludeInPacks, 0, newList, 0, cnt);
newList[cnt] = idx;
excludeInPacks = newList;
}
}
/** /**
* Prepare the list of objects to be written to the pack stream. * Prepare the list of objects to be written to the pack stream.
* <p> * <p>
@ -721,6 +745,9 @@ public class PackWriter {
if (writeMonitor == null) if (writeMonitor == null)
writeMonitor = NullProgressMonitor.INSTANCE; writeMonitor = NullProgressMonitor.INSTANCE;
excludeInPacks = null;
excludeInPackLast = null;
boolean needSearchForReuse = reuseSupport != null && ( boolean needSearchForReuse = reuseSupport != null && (
reuseDeltas reuseDeltas
|| config.isReuseObjects() || config.isReuseObjects()
@ -1459,6 +1486,8 @@ public class PackWriter {
BlockList<RevCommit> commits = new BlockList<RevCommit>(); BlockList<RevCommit> commits = new BlockList<RevCommit>();
RevCommit c; RevCommit c;
while ((c = walker.next()) != null) { while ((c = walker.next()) != null) {
if (exclude(c))
continue;
if (c.has(inCachedPack)) { if (c.has(inCachedPack)) {
CachedPack pack = tipToPack.get(c); CachedPack pack = tipToPack.get(c);
if (includesAllTips(pack, include, walker)) { if (includesAllTips(pack, include, walker)) {
@ -1524,6 +1553,8 @@ public class PackWriter {
while ((o = walker.nextObject()) != null) { while ((o = walker.nextObject()) != null) {
if (o.has(RevFlag.UNINTERESTING)) if (o.has(RevFlag.UNINTERESTING))
continue; continue;
if (exclude(o))
continue;
int pathHash = walker.getPathHashCode(); int pathHash = walker.getPathHashCode();
byte[] pathBuf = walker.getPathBuffer(); byte[] pathBuf = walker.getPathBuffer();
@ -1537,6 +1568,8 @@ public class PackWriter {
while ((o = walker.nextObject()) != null) { while ((o = walker.nextObject()) != null) {
if (o.has(RevFlag.UNINTERESTING)) if (o.has(RevFlag.UNINTERESTING))
continue; continue;
if (exclude(o))
continue;
addObject(o, walker.getPathHashCode()); addObject(o, walker.getPathHashCode());
countingMonitor.update(1); countingMonitor.update(1);
} }
@ -1608,6 +1641,7 @@ public class PackWriter {
*/ */
public void addObject(final RevObject object) public void addObject(final RevObject object)
throws IncorrectObjectTypeException { throws IncorrectObjectTypeException {
if (!exclude(object))
addObject(object, 0); addObject(object, 0);
} }
@ -1622,6 +1656,20 @@ public class PackWriter {
objectsMap.add(otp); objectsMap.add(otp);
} }
private boolean exclude(AnyObjectId objectId) {
if (excludeInPacks == null)
return false;
if (excludeInPackLast.hasObject(objectId))
return true;
for (PackIndex idx : excludeInPacks) {
if (idx.hasObject(objectId)) {
excludeInPackLast = idx;
return true;
}
}
return false;
}
/** /**
* Select an object representation for this writer. * Select an object representation for this writer.
* <p> * <p>

Loading…
Cancel
Save