Make PackWriterBitmapWriter class public and move it to a more central location, in preparation for its use by another class (in a subsequent commit). One of its inner static classes, AddUnseenToBitmapFilter, previously package-private, is also used directly in its former package. Therefore, AddUnseenToBitmapFilter and its sibling class have been moved to an internal package instead. Change-Id: I740bc4bfc4e4e3c857d1ee7d25fe45e90cd22a75 Signed-off-by: Jonathan Tan <jonathantanmy@google.com>tags/v4.10.0.201712302008-r
@@ -0,0 +1,105 @@ | |||
/* | |||
* Copyright (C) 2017, Google Inc. | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Distribution License v1.0 which | |||
* accompanies this distribution, is reproduced below, and is | |||
* available at http://www.eclipse.org/org/documents/edl-v10.php | |||
* | |||
* All rights reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or | |||
* without modification, are permitted provided that the following | |||
* conditions are met: | |||
* | |||
* - Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* | |||
* - Redistributions in binary form must reproduce the above | |||
* copyright notice, this list of conditions and the following | |||
* disclaimer in the documentation and/or other materials provided | |||
* with the distribution. | |||
* | |||
* - Neither the name of the Eclipse Foundation, Inc. nor the | |||
* names of its contributors may be used to endorse or promote | |||
* products derived from this software without specific prior | |||
* written permission. | |||
* | |||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
*/ | |||
package org.eclipse.jgit.internal.revwalk; | |||
import org.eclipse.jgit.lib.BitmapIndex.Bitmap; | |||
import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder; | |||
import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.revwalk.filter.RevFilter; | |||
import org.eclipse.jgit.revwalk.RevWalk; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
import org.eclipse.jgit.revwalk.RevFlag; | |||
/** | |||
* A RevFilter that adds the visited commits to {@code bitmap} as a side | |||
* effect. | |||
* <p> | |||
* When the walk hits a commit that is part of {@code bitmap}'s | |||
* BitmapIndex, that entire bitmap is ORed into {@code bitmap} and the | |||
* commit and its parents are marked as SEEN so that the walk does not | |||
* have to visit its ancestors. This ensures the walk is very short if | |||
* there is good bitmap coverage. | |||
*/ | |||
public class AddToBitmapFilter extends RevFilter { | |||
private final BitmapBuilder bitmap; | |||
/** | |||
* Create a filter that adds visited commits to the given bitmap. | |||
* | |||
* @param bitmap bitmap to write visited commits to | |||
*/ | |||
public AddToBitmapFilter(BitmapBuilder bitmap) { | |||
this.bitmap = bitmap; | |||
} | |||
@Override | |||
public final boolean include(RevWalk walker, RevCommit cmit) { | |||
Bitmap visitedBitmap; | |||
if (bitmap.contains(cmit)) { | |||
// already included | |||
} else if ((visitedBitmap = bitmap.getBitmapIndex() | |||
.getBitmap(cmit)) != null) { | |||
bitmap.or(visitedBitmap); | |||
} else { | |||
bitmap.addObject(cmit, Constants.OBJ_COMMIT); | |||
return true; | |||
} | |||
for (RevCommit p : cmit.getParents()) { | |||
p.add(RevFlag.SEEN); | |||
} | |||
return false; | |||
} | |||
@Override | |||
public final RevFilter clone() { | |||
throw new UnsupportedOperationException(); | |||
} | |||
@Override | |||
public final boolean requiresCommitBody() { | |||
return false; | |||
} | |||
} |
@@ -0,0 +1,113 @@ | |||
/* | |||
* Copyright (C) 2017, Google Inc. | |||
* and other copyright owners as documented in the project's IP log. | |||
* | |||
* This program and the accompanying materials are made available | |||
* under the terms of the Eclipse Distribution License v1.0 which | |||
* accompanies this distribution, is reproduced below, and is | |||
* available at http://www.eclipse.org/org/documents/edl-v10.php | |||
* | |||
* All rights reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or | |||
* without modification, are permitted provided that the following | |||
* conditions are met: | |||
* | |||
* - Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* | |||
* - Redistributions in binary form must reproduce the above | |||
* copyright notice, this list of conditions and the following | |||
* disclaimer in the documentation and/or other materials provided | |||
* with the distribution. | |||
* | |||
* - Neither the name of the Eclipse Foundation, Inc. nor the | |||
* names of its contributors may be used to endorse or promote | |||
* products derived from this software without specific prior | |||
* written permission. | |||
* | |||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | |||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | |||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
*/ | |||
package org.eclipse.jgit.internal.revwalk; | |||
import org.eclipse.jgit.lib.BitmapIndex.Bitmap; | |||
import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder; | |||
import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.revwalk.filter.RevFilter; | |||
import org.eclipse.jgit.revwalk.RevWalk; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
import org.eclipse.jgit.revwalk.RevFlag; | |||
/** | |||
* A RevFilter that adds the visited commits to {@code bitmap} as a side | |||
* effect. | |||
* <p> | |||
* When the walk hits a commit that is part of {@code bitmap}'s | |||
* BitmapIndex, that entire bitmap is ORed into {@code bitmap} and the | |||
* commit and its parents are marked as SEEN so that the walk does not | |||
* have to visit its ancestors. This ensures the walk is very short if | |||
* there is good bitmap coverage. | |||
* <p> | |||
* Commits named in {@code seen} are considered already seen. If one is | |||
* encountered, that commit and its parents will be marked with the SEEN | |||
* flag to prevent the walk from visiting its ancestors. | |||
*/ | |||
public class AddUnseenToBitmapFilter extends RevFilter { | |||
private final BitmapBuilder seen; | |||
private final BitmapBuilder bitmap; | |||
/** | |||
* Create a filter that adds visited commits to the given bitmap, but does not walk | |||
* through the objects in {@code seen}. | |||
* | |||
* @param seen objects that are already seen | |||
* @param bitmap bitmap to write visited commits to | |||
*/ | |||
public AddUnseenToBitmapFilter(BitmapBuilder seen, BitmapBuilder bitmap) { | |||
this.seen = seen; | |||
this.bitmap = bitmap; | |||
} | |||
@Override | |||
public final boolean include(RevWalk walker, RevCommit cmit) { | |||
Bitmap visitedBitmap; | |||
if (seen.contains(cmit) || bitmap.contains(cmit)) { | |||
// already seen or included | |||
} else if ((visitedBitmap = bitmap.getBitmapIndex() | |||
.getBitmap(cmit)) != null) { | |||
bitmap.or(visitedBitmap); | |||
} else { | |||
bitmap.addObject(cmit, Constants.OBJ_COMMIT); | |||
return true; | |||
} | |||
for (RevCommit p : cmit.getParents()) { | |||
p.add(RevFlag.SEEN); | |||
} | |||
return false; | |||
} | |||
@Override | |||
public final RevFilter clone() { | |||
throw new UnsupportedOperationException(); | |||
} | |||
@Override | |||
public final boolean requiresCommitBody() { | |||
return false; | |||
} | |||
} |
@@ -107,6 +107,7 @@ import org.eclipse.jgit.lib.ProgressMonitor; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.lib.ThreadSafeProgressMonitor; | |||
import org.eclipse.jgit.revwalk.AsyncRevObjectQueue; | |||
import org.eclipse.jgit.revwalk.BitmapWalker; | |||
import org.eclipse.jgit.revwalk.DepthWalk; | |||
import org.eclipse.jgit.revwalk.ObjectWalk; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
@@ -1714,7 +1715,7 @@ public class PackWriter implements AutoCloseable { | |||
if (!shallowPack && useBitmaps) { | |||
BitmapIndex bitmapIndex = reader.getBitmapIndex(); | |||
if (bitmapIndex != null) { | |||
PackWriterBitmapWalker bitmapWalker = new PackWriterBitmapWalker( | |||
BitmapWalker bitmapWalker = new BitmapWalker( | |||
walker, bitmapIndex, countingMonitor); | |||
findObjectsToPackUsingBitmaps(bitmapWalker, want, have); | |||
endPhase(countingMonitor); | |||
@@ -1917,7 +1918,7 @@ public class PackWriter implements AutoCloseable { | |||
} | |||
private void findObjectsToPackUsingBitmaps( | |||
PackWriterBitmapWalker bitmapWalker, Set<? extends ObjectId> want, | |||
BitmapWalker bitmapWalker, Set<? extends ObjectId> want, | |||
Set<? extends ObjectId> have) | |||
throws MissingObjectException, IncorrectObjectTypeException, | |||
IOException { | |||
@@ -2123,7 +2124,7 @@ public class PackWriter implements AutoCloseable { | |||
beginPhase(PackingPhase.BUILDING_BITMAPS, pm, selectedCommits.size()); | |||
PackWriterBitmapWalker walker = bitmapPreparer.newBitmapWalker(); | |||
BitmapWalker walker = bitmapPreparer.newBitmapWalker(); | |||
AnyObjectId last = null; | |||
for (PackWriterBitmapPreparer.BitmapCommit cmit : selectedCommits) { | |||
if (!cmit.isReuseWalker()) { |
@@ -59,18 +59,19 @@ import java.util.Set; | |||
import org.eclipse.jgit.errors.IncorrectObjectTypeException; | |||
import org.eclipse.jgit.errors.MissingObjectException; | |||
import org.eclipse.jgit.internal.JGitText; | |||
import org.eclipse.jgit.internal.revwalk.AddUnseenToBitmapFilter; | |||
import org.eclipse.jgit.internal.storage.file.BitmapIndexImpl; | |||
import org.eclipse.jgit.internal.storage.file.BitmapIndexImpl.CompressedBitmap; | |||
import org.eclipse.jgit.internal.storage.file.PackBitmapIndex; | |||
import org.eclipse.jgit.internal.storage.file.PackBitmapIndexBuilder; | |||
import org.eclipse.jgit.internal.storage.file.PackBitmapIndexRemapper; | |||
import org.eclipse.jgit.internal.storage.pack.PackWriterBitmapWalker.AddUnseenToBitmapFilter; | |||
import org.eclipse.jgit.lib.AnyObjectId; | |||
import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder; | |||
import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.lib.ObjectId; | |||
import org.eclipse.jgit.lib.ObjectReader; | |||
import org.eclipse.jgit.lib.ProgressMonitor; | |||
import org.eclipse.jgit.revwalk.BitmapWalker; | |||
import org.eclipse.jgit.revwalk.ObjectWalk; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
import org.eclipse.jgit.revwalk.RevObject; | |||
@@ -508,8 +509,8 @@ class PackWriterBitmapPreparer { | |||
return Math.max(next, recentCommitSpan); | |||
} | |||
PackWriterBitmapWalker newBitmapWalker() { | |||
return new PackWriterBitmapWalker( | |||
BitmapWalker newBitmapWalker() { | |||
return new BitmapWalker( | |||
new ObjectWalk(reader), bitmapIndex, null); | |||
} | |||
@@ -41,29 +41,28 @@ | |||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
*/ | |||
package org.eclipse.jgit.internal.storage.pack; | |||
package org.eclipse.jgit.revwalk; | |||
import java.io.IOException; | |||
import java.util.Arrays; | |||
import org.eclipse.jgit.errors.IncorrectObjectTypeException; | |||
import org.eclipse.jgit.errors.MissingObjectException; | |||
import org.eclipse.jgit.lib.BitmapIndex; | |||
import org.eclipse.jgit.internal.revwalk.AddToBitmapFilter; | |||
import org.eclipse.jgit.internal.revwalk.AddUnseenToBitmapFilter; | |||
import org.eclipse.jgit.lib.BitmapIndex.Bitmap; | |||
import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder; | |||
import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.lib.BitmapIndex; | |||
import org.eclipse.jgit.lib.NullProgressMonitor; | |||
import org.eclipse.jgit.lib.ObjectId; | |||
import org.eclipse.jgit.lib.ProgressMonitor; | |||
import org.eclipse.jgit.revwalk.ObjectWalk; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
import org.eclipse.jgit.revwalk.RevFlag; | |||
import org.eclipse.jgit.revwalk.RevObject; | |||
import org.eclipse.jgit.revwalk.RevWalk; | |||
import org.eclipse.jgit.revwalk.filter.RevFilter; | |||
/** Helper class for PackWriter to do ObjectWalks with pack index bitmaps. */ | |||
final class PackWriterBitmapWalker { | |||
/** | |||
* Helper class to do ObjectWalks with pack index bitmaps. | |||
* | |||
* @since 4.10 | |||
*/ | |||
public final class BitmapWalker { | |||
private final ObjectWalk walker; | |||
@@ -73,18 +72,52 @@ final class PackWriterBitmapWalker { | |||
private long countOfBitmapIndexMisses; | |||
PackWriterBitmapWalker( | |||
/** | |||
* Create a BitmapWalker. | |||
* | |||
* @param walker walker to use when traversing the object graph. | |||
* @param bitmapIndex index to obtain bitmaps from. | |||
* @param pm progress monitor to report progress on. | |||
*/ | |||
public BitmapWalker( | |||
ObjectWalk walker, BitmapIndex bitmapIndex, ProgressMonitor pm) { | |||
this.walker = walker; | |||
this.bitmapIndex = bitmapIndex; | |||
this.pm = (pm == null) ? NullProgressMonitor.INSTANCE : pm; | |||
} | |||
long getCountOfBitmapIndexMisses() { | |||
/** | |||
* Return the number of objects that had to be walked because they were not covered by a | |||
* bitmap. | |||
* | |||
* @return the number of objects that had to be walked because they were not covered by a | |||
* bitmap. | |||
*/ | |||
public long getCountOfBitmapIndexMisses() { | |||
return countOfBitmapIndexMisses; | |||
} | |||
BitmapBuilder findObjects(Iterable<? extends ObjectId> start, BitmapBuilder seen, | |||
/** | |||
* Return, as a bitmap, the objects reachable from the objects in start. | |||
* | |||
* @param start the objects to start the object traversal from. | |||
* @param seen the objects to skip if encountered during traversal. | |||
* @param ignoreMissing true to ignore missing objects, false otherwise. | |||
* @return as a bitmap, the objects reachable from the objects in start. | |||
* @throws MissingObjectException | |||
* the object supplied is not available from the object | |||
* database. This usually indicates the supplied object is | |||
* invalid, but the reference was constructed during an earlier | |||
* invocation to {@link RevWalk#lookupAny(AnyObjectId, int)}. | |||
* @throws IncorrectObjectTypeException | |||
* the object was not parsed yet and it was discovered during | |||
* parsing that it is not actually the type of the instance | |||
* passed in. This usually indicates the caller used the wrong | |||
* type in a {@link RevWalk#lookupAny(AnyObjectId, int)} call. | |||
* @throws IOException | |||
* a pack file or loose object could not be read. | |||
*/ | |||
public BitmapBuilder findObjects(Iterable<? extends ObjectId> start, BitmapBuilder seen, | |||
boolean ignoreMissing) | |||
throws MissingObjectException, IncorrectObjectTypeException, | |||
IOException { | |||
@@ -191,106 +224,4 @@ final class PackWriterBitmapWalker { | |||
return bitmapResult; | |||
} | |||
/** | |||
* A RevFilter that adds the visited commits to {@code bitmap} as a side | |||
* effect. | |||
* <p> | |||
* When the walk hits a commit that is part of {@code bitmap}'s | |||
* BitmapIndex, that entire bitmap is ORed into {@code bitmap} and the | |||
* commit and its parents are marked as SEEN so that the walk does not | |||
* have to visit its ancestors. This ensures the walk is very short if | |||
* there is good bitmap coverage. | |||
*/ | |||
static class AddToBitmapFilter extends RevFilter { | |||
private final BitmapBuilder bitmap; | |||
AddToBitmapFilter(BitmapBuilder bitmap) { | |||
this.bitmap = bitmap; | |||
} | |||
@Override | |||
public final boolean include(RevWalk walker, RevCommit cmit) { | |||
Bitmap visitedBitmap; | |||
if (bitmap.contains(cmit)) { | |||
// already included | |||
} else if ((visitedBitmap = bitmap.getBitmapIndex() | |||
.getBitmap(cmit)) != null) { | |||
bitmap.or(visitedBitmap); | |||
} else { | |||
bitmap.addObject(cmit, Constants.OBJ_COMMIT); | |||
return true; | |||
} | |||
for (RevCommit p : cmit.getParents()) { | |||
p.add(RevFlag.SEEN); | |||
} | |||
return false; | |||
} | |||
@Override | |||
public final RevFilter clone() { | |||
throw new UnsupportedOperationException(); | |||
} | |||
@Override | |||
public final boolean requiresCommitBody() { | |||
return false; | |||
} | |||
} | |||
/** | |||
* A RevFilter that adds the visited commits to {@code bitmap} as a side | |||
* effect. | |||
* <p> | |||
* When the walk hits a commit that is part of {@code bitmap}'s | |||
* BitmapIndex, that entire bitmap is ORed into {@code bitmap} and the | |||
* commit and its parents are marked as SEEN so that the walk does not | |||
* have to visit its ancestors. This ensures the walk is very short if | |||
* there is good bitmap coverage. | |||
* <p> | |||
* Commits named in {@code seen} are considered already seen. If one is | |||
* encountered, that commit and its parents will be marked with the SEEN | |||
* flag to prevent the walk from visiting its ancestors. | |||
*/ | |||
static class AddUnseenToBitmapFilter extends RevFilter { | |||
private final BitmapBuilder seen; | |||
private final BitmapBuilder bitmap; | |||
AddUnseenToBitmapFilter(BitmapBuilder seen, BitmapBuilder bitmapResult) { | |||
this.seen = seen; | |||
this.bitmap = bitmapResult; | |||
} | |||
@Override | |||
public final boolean include(RevWalk walker, RevCommit cmit) { | |||
Bitmap visitedBitmap; | |||
if (seen.contains(cmit) || bitmap.contains(cmit)) { | |||
// already seen or included | |||
} else if ((visitedBitmap = bitmap.getBitmapIndex() | |||
.getBitmap(cmit)) != null) { | |||
bitmap.or(visitedBitmap); | |||
} else { | |||
bitmap.addObject(cmit, Constants.OBJ_COMMIT); | |||
return true; | |||
} | |||
for (RevCommit p : cmit.getParents()) { | |||
p.add(RevFlag.SEEN); | |||
} | |||
return false; | |||
} | |||
@Override | |||
public final RevFilter clone() { | |||
throw new UnsupportedOperationException(); | |||
} | |||
@Override | |||
public final boolean requiresCommitBody() { | |||
return false; | |||
} | |||
} | |||
} |