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.RevTag;
|
||||
import org.eclipse.jgit.revwalk.RevTree;
|
||||
import org.eclipse.jgit.storage.file.PackIndex;
|
||||
import org.eclipse.jgit.storage.file.PackIndexWriter;
|
||||
import org.eclipse.jgit.util.BlockList;
|
||||
import org.eclipse.jgit.util.TemporaryBuffer;
|
||||
|
@ -157,6 +158,10 @@ public class PackWriter {
|
|||
|
||||
private Set<ObjectId> tagTargets = Collections.emptySet();
|
||||
|
||||
private PackIndex[] excludeInPacks;
|
||||
|
||||
private PackIndex excludeInPackLast;
|
||||
|
||||
private Deflater myDeflater;
|
||||
|
||||
private final ObjectReader reader;
|
||||
|
@ -425,6 +430,25 @@ public long getObjectCount() throws IOException {
|
|||
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.
|
||||
* <p>
|
||||
|
@ -721,6 +745,9 @@ public void writePack(ProgressMonitor compressMonitor,
|
|||
if (writeMonitor == null)
|
||||
writeMonitor = NullProgressMonitor.INSTANCE;
|
||||
|
||||
excludeInPacks = null;
|
||||
excludeInPackLast = null;
|
||||
|
||||
boolean needSearchForReuse = reuseSupport != null && (
|
||||
reuseDeltas
|
||||
|| config.isReuseObjects()
|
||||
|
@ -1459,6 +1486,8 @@ private void findObjectsToPack(final ProgressMonitor countingMonitor,
|
|||
BlockList<RevCommit> commits = new BlockList<RevCommit>();
|
||||
RevCommit c;
|
||||
while ((c = walker.next()) != null) {
|
||||
if (exclude(c))
|
||||
continue;
|
||||
if (c.has(inCachedPack)) {
|
||||
CachedPack pack = tipToPack.get(c);
|
||||
if (includesAllTips(pack, include, walker)) {
|
||||
|
@ -1524,6 +1553,8 @@ private void findObjectsToPack(final ProgressMonitor countingMonitor,
|
|||
while ((o = walker.nextObject()) != null) {
|
||||
if (o.has(RevFlag.UNINTERESTING))
|
||||
continue;
|
||||
if (exclude(o))
|
||||
continue;
|
||||
|
||||
int pathHash = walker.getPathHashCode();
|
||||
byte[] pathBuf = walker.getPathBuffer();
|
||||
|
@ -1537,6 +1568,8 @@ private void findObjectsToPack(final ProgressMonitor countingMonitor,
|
|||
while ((o = walker.nextObject()) != null) {
|
||||
if (o.has(RevFlag.UNINTERESTING))
|
||||
continue;
|
||||
if (exclude(o))
|
||||
continue;
|
||||
addObject(o, walker.getPathHashCode());
|
||||
countingMonitor.update(1);
|
||||
}
|
||||
|
@ -1608,7 +1641,8 @@ private static boolean includesAllTips(CachedPack pack, RevFlag include,
|
|||
*/
|
||||
public void addObject(final RevObject object)
|
||||
throws IncorrectObjectTypeException {
|
||||
addObject(object, 0);
|
||||
if (!exclude(object))
|
||||
addObject(object, 0);
|
||||
}
|
||||
|
||||
private void addObject(final RevObject object, final int pathHashCode) {
|
||||
|
@ -1622,6 +1656,20 @@ private void addObject(final RevObject object, final int pathHashCode) {
|
|||
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.
|
||||
* <p>
|
||||
|
|
Loading…
Reference in New Issue