Browse Source

Merge "Pack bitmaps: improve readability"

stable-4.2
Jonathan Nieder 9 years ago committed by Gerrit Code Review @ Eclipse.org
parent
commit
f6b9cd38ca
  1. 68
      org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java

68
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java

@ -181,8 +181,14 @@ class PackWriterBitmapPreparer {
BitmapBuilder bitmap = entry.getBuilder(); BitmapBuilder bitmap = entry.getBuilder();
int cardinality = bitmap.cardinality(); int cardinality = bitmap.cardinality();
List<List<BitmapCommit>> running = new ArrayList< // Within this branch, keep ordered lists of commits representing
List<BitmapCommit>>(); // chains in its history, where each chain is a "sub-branch".
// Ordering commits by these chains makes for fewer differences
// between consecutive selected commits, which in turn provides
// better compression/on the run-length encoding of the XORs between
// them.
List<List<BitmapCommit>> chains =
new ArrayList<List<BitmapCommit>>();
// Mark the current branch as inactive if its tip commit isn't // Mark the current branch as inactive if its tip commit isn't
// recent and there are an excessive number of branches, to // recent and there are an excessive number of branches, to
@ -195,7 +201,8 @@ class PackWriterBitmapPreparer {
} }
// Insert bitmaps at the offsets suggested by the // Insert bitmaps at the offsets suggested by the
// nextSelectionDistance() heuristic. // nextSelectionDistance() heuristic. Only reuse bitmaps created
// for more distant commits.
int index = -1; int index = -1;
int nextIn = nextSpan(cardinality); int nextIn = nextSpan(cardinality);
int nextFlg = nextIn == distantCommitSpan int nextFlg = nextIn == distantCommitSpan
@ -241,7 +248,8 @@ class PackWriterBitmapPreparer {
} }
} }
// This commit is selected, calculate the next one. // This commit is selected.
// Calculate where to look for the next one.
int flags = nextFlg; int flags = nextFlg;
nextIn = nextSpan(distanceFromTip); nextIn = nextSpan(distanceFromTip);
nextFlg = nextIn == distantCommitSpan nextFlg = nextIn == distantCommitSpan
@ -250,43 +258,48 @@ class PackWriterBitmapPreparer {
BitmapBuilder fullBitmap = commitBitmapIndex.newBitmapBuilder(); BitmapBuilder fullBitmap = commitBitmapIndex.newBitmapBuilder();
rw.reset(); rw.reset();
rw.markStart(c); rw.markStart(c);
for (AnyObjectId objectId : selectionHelper.reusedCommits) for (AnyObjectId objectId : selectionHelper.reusedCommits) {
rw.markUninteresting(rw.parseCommit(objectId)); rw.markUninteresting(rw.parseCommit(objectId));
}
rw.setRevFilter( rw.setRevFilter(
PackWriterBitmapWalker.newRevFilter(null, fullBitmap)); PackWriterBitmapWalker.newRevFilter(null, fullBitmap));
while (rw.next() != null) { while (rw.next() != null) {
// Work is done in the RevFilter. // The RevFilter adds the reachable commits from this
// selected commit to fullBitmap.
} }
List<List<BitmapCommit>> matches = new ArrayList< // Sort the commits by independent chains in its history,
// yielding better compression when building bitmaps.
List<List<BitmapCommit>> candidateChain = new ArrayList<
List<BitmapCommit>>(); List<BitmapCommit>>();
for (List<BitmapCommit> list : running) { for (List<BitmapCommit> chain : chains) {
BitmapCommit last = list.get(list.size() - 1); BitmapCommit mostRecentCommit = chain.get(chain.size() - 1);
if (fullBitmap.contains(last)) { if (fullBitmap.contains(mostRecentCommit)) {
matches.add(list); candidateChain.add(chain);
} }
} }
List<BitmapCommit> match; List<BitmapCommit> longestAncestorChain;
if (matches.isEmpty()) { if (candidateChain.isEmpty()) {
match = new ArrayList<BitmapCommit>(); longestAncestorChain = new ArrayList<BitmapCommit>();
running.add(match); chains.add(longestAncestorChain);
} else { } else {
match = matches.get(0); longestAncestorChain = candidateChain.get(0);
// Append to longest // Append to longest
for (List<BitmapCommit> list : matches) { for (List<BitmapCommit> chain : candidateChain) {
if (list.size() > match.size()) { if (chain.size() > longestAncestorChain.size()) {
match = list; longestAncestorChain = chain;
} }
} }
} }
match.add(new BitmapCommit(c, !match.isEmpty(), flags)); longestAncestorChain.add(new BitmapCommit(
c, !longestAncestorChain.isEmpty(), flags));
writeBitmaps.addBitmap(c, fullBitmap, 0); writeBitmaps.addBitmap(c, fullBitmap, 0);
} }
for (List<BitmapCommit> list : running) { for (List<BitmapCommit> chain : chains) {
selections.addAll(list); selections.addAll(chain);
} }
} }
writeBitmaps.clearBitmaps(); // Remove the temporary commit bitmaps. writeBitmaps.clearBitmaps(); // Remove the temporary commit bitmaps.
@ -329,6 +342,7 @@ class PackWriterBitmapPreparer {
BitmapBuilder reuse = commitBitmapIndex.newBitmapBuilder(); BitmapBuilder reuse = commitBitmapIndex.newBitmapBuilder();
List<BitmapCommit> reuseCommits = new ArrayList<BitmapCommit>(); List<BitmapCommit> reuseCommits = new ArrayList<BitmapCommit>();
for (PackBitmapIndexRemapper.Entry entry : bitmapRemapper) { for (PackBitmapIndexRemapper.Entry entry : bitmapRemapper) {
// More recent commits did not have the reuse flag set, so skip them
if ((entry.getFlags() & FLAG_REUSE) != FLAG_REUSE) { if ((entry.getFlags() & FLAG_REUSE) != FLAG_REUSE) {
continue; continue;
} }
@ -346,8 +360,8 @@ class PackWriterBitmapPreparer {
} }
} }
// Do a RevWalk by commit time descending. Keep track of all the paths // Add branch tips that are not represented in old bitmap indices. Set
// from the wants. // up the RevWalk to walk the new commits not in the old packs.
List<BitmapBuilderEntry> tipCommitBitmaps = new ArrayList<BitmapBuilderEntry>( List<BitmapBuilderEntry> tipCommitBitmaps = new ArrayList<BitmapBuilderEntry>(
want.size()); want.size());
Set<RevCommit> peeledWant = new HashSet<RevCommit>(want.size()); Set<RevCommit> peeledWant = new HashSet<RevCommit>(want.size());
@ -366,6 +380,8 @@ class PackWriterBitmapPreparer {
} }
// Create a list of commits in reverse order (older to newer). // Create a list of commits in reverse order (older to newer).
// For each branch that contains the commit, mark its parents as being
// in the bitmap.
RevCommit[] commits = new RevCommit[expectedCommitCount]; RevCommit[] commits = new RevCommit[expectedCommitCount];
int pos = commits.length; int pos = commits.length;
RevCommit rc; RevCommit rc;
@ -480,7 +496,6 @@ class PackWriterBitmapPreparer {
*/ */
private static final class BitmapBuilderEntry { private static final class BitmapBuilderEntry {
private final RevCommit commit; private final RevCommit commit;
private final BitmapBuilder builder; private final BitmapBuilder builder;
BitmapBuilderEntry(RevCommit commit, BitmapBuilder builder) { BitmapBuilderEntry(RevCommit commit, BitmapBuilder builder) {
@ -509,7 +524,6 @@ class PackWriterBitmapPreparer {
*/ */
private static final class CommitSelectionHelper implements Iterable<RevCommit> { private static final class CommitSelectionHelper implements Iterable<RevCommit> {
final Set<? extends ObjectId> peeledWants; final Set<? extends ObjectId> peeledWants;
final List<BitmapBuilderEntry> tipCommitBitmaps; final List<BitmapBuilderEntry> tipCommitBitmaps;
final Iterable<BitmapCommit> reusedCommits; final Iterable<BitmapCommit> reusedCommits;
final RevCommit[] commitsByOldest; final RevCommit[] commitsByOldest;
@ -527,6 +541,8 @@ class PackWriterBitmapPreparer {
} }
public Iterator<RevCommit> iterator() { public Iterator<RevCommit> iterator() {
// Member variables referenced by this iterator will have synthetic
// accessors generated for them if they are made private.
return new Iterator<RevCommit>() { return new Iterator<RevCommit>() {
int pos = commitStartPos; int pos = commitStartPos;

Loading…
Cancel
Save