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>
This commit is contained in:
parent
c580c56c4d
commit
a1a8c6d77e
|
@ -99,6 +99,7 @@
|
||||||
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 long getObjectCount() throws IOException {
|
||||||
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 void writePack(ProgressMonitor compressMonitor,
|
||||||
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 @@ private void findObjectsToPack(final ProgressMonitor countingMonitor,
|
||||||
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 @@ private void findObjectsToPack(final ProgressMonitor countingMonitor,
|
||||||
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 @@ private void findObjectsToPack(final ProgressMonitor countingMonitor,
|
||||||
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 @@ private static boolean includesAllTips(CachedPack pack, RevFlag include,
|
||||||
*/
|
*/
|
||||||
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 @@ private void addObject(final RevObject object, final int pathHashCode) {
|
||||||
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…
Reference in New Issue