summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java58
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java15
2 files changed, 47 insertions, 26 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java
index 62206c69c9..93f891864a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java
@@ -44,7 +44,7 @@
package org.eclipse.jgit.internal.storage.file;
import java.text.MessageFormat;
-import java.util.Arrays;
+import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
@@ -73,7 +73,7 @@ public class PackBitmapIndexBuilder extends BasePackBitmapIndex {
private final EWAHCompressedBitmap trees;
private final EWAHCompressedBitmap blobs;
private final EWAHCompressedBitmap tags;
- private final ObjectToPack[] byOffset;
+ private final BlockList<PositionEntry> byOffset;
private final BlockList<StoredBitmap>
byAddOrder = new BlockList<StoredBitmap>();
private final ObjectIdOwnerMap<PositionEntry>
@@ -83,20 +83,25 @@ public class PackBitmapIndexBuilder extends BasePackBitmapIndex {
* Creates a PackBitmapIndex used for building the contents of an index
* file.
*
- * @param byName
- * objects sorted by name.
+ * @param objects
+ * objects sorted by name. The list must be initially sorted by
+ * ObjectId (name); it will be resorted in place.
*/
- public PackBitmapIndexBuilder(List<ObjectToPack> byName) {
+ public PackBitmapIndexBuilder(List<ObjectToPack> objects) {
super(new ObjectIdOwnerMap<StoredBitmap>());
- byOffset = sortByOffset(byName);
+ byOffset = new BlockList<>(objects.size());
+ sortByOffsetAndIndex(byOffset, positionEntries, objects);
- int sizeInWords = Math.max(byOffset.length / 64, 4);
+ // 64 objects fit in a single long word (64 bits).
+ // On average a repository is 30% commits, 30% trees, 30% blobs.
+ // Initialize bitmap capacity for worst case to minimize growing.
+ int sizeInWords = Math.max(4, byOffset.size() / 64 / 3);
commits = new EWAHCompressedBitmap(sizeInWords);
trees = new EWAHCompressedBitmap(sizeInWords);
blobs = new EWAHCompressedBitmap(sizeInWords);
tags = new EWAHCompressedBitmap(sizeInWords);
- for (int i = 0; i < byOffset.length; i++) {
- int type = byOffset[i].getType();
+ for (int i = 0; i < objects.size(); i++) {
+ int type = objects.get(i).getType();
switch (type) {
case Constants.OBJ_COMMIT:
commits.set(i);
@@ -121,20 +126,33 @@ public class PackBitmapIndexBuilder extends BasePackBitmapIndex {
tags.trim();
}
- private ObjectToPack[] sortByOffset(List<ObjectToPack> entries) {
- ObjectToPack[] result = new ObjectToPack[entries.size()];
- for (int i = 0; i < result.length; i++) {
- result[i] = entries.get(i);
- positionEntries.add(new PositionEntry(result[i], i));
+ private static void sortByOffsetAndIndex(BlockList<PositionEntry> byOffset,
+ ObjectIdOwnerMap<PositionEntry> positionEntries,
+ List<ObjectToPack> entries) {
+ for (int i = 0; i < entries.size(); i++) {
+ positionEntries.add(new PositionEntry(entries.get(i), i));
}
- Arrays.sort(result, new Comparator<ObjectToPack>() {
+ Collections.sort(entries, new Comparator<ObjectToPack>() {
public int compare(ObjectToPack a, ObjectToPack b) {
return Long.signum(a.getOffset() - b.getOffset());
}
});
- for (int i = 0; i < result.length; i++)
- positionEntries.get(result[i]).offsetPosition = i;
- return result;
+ for (int i = 0; i < entries.size(); i++) {
+ PositionEntry e = positionEntries.get(entries.get(i));
+ e.offsetPosition = i;
+ byOffset.add(e);
+ }
+ }
+
+ /** @return set of objects included in the pack. */
+ public ObjectIdOwnerMap<ObjectIdOwnerMap.Entry> getObjectSet() {
+ ObjectIdOwnerMap<ObjectIdOwnerMap.Entry> r = new ObjectIdOwnerMap<>();
+ for (PositionEntry e : byOffset) {
+ r.add(new ObjectIdOwnerMap.Entry(e) {
+ // A new entry that copies the ObjectId
+ });
+ }
+ return r;
}
/**
@@ -204,7 +222,7 @@ public class PackBitmapIndexBuilder extends BasePackBitmapIndex {
@Override
public ObjectId getObject(int position) throws IllegalArgumentException {
- ObjectId objectId = byOffset[position];
+ ObjectId objectId = byOffset.get(position);
if (objectId == null)
throw new IllegalArgumentException();
return objectId;
@@ -248,7 +266,7 @@ public class PackBitmapIndexBuilder extends BasePackBitmapIndex {
@Override
public int getObjectCount() {
- return byOffset.length;
+ return byOffset.size();
}
/** @return an iterator over the xor compressed entries. */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java
index a88502c2f0..d9fa393c7e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java
@@ -608,12 +608,12 @@ public class PackWriter implements AutoCloseable {
/**
* Returns the object ids in the pack file that was created by this writer.
- *
+ * <p>
* This method can only be invoked after
* {@link #writePack(ProgressMonitor, ProgressMonitor, OutputStream)} has
* been invoked and completed successfully.
*
- * @return number of objects in pack.
+ * @return set of objects in pack.
* @throws IOException
* a cached pack cannot supply its object ids.
*/
@@ -623,17 +623,20 @@ public class PackWriter implements AutoCloseable {
throw new IOException(
JGitText.get().cachedPacksPreventsListingObjects);
- ObjectIdOwnerMap<ObjectIdOwnerMap.Entry> objs = new ObjectIdOwnerMap<
- ObjectIdOwnerMap.Entry>();
+ if (writeBitmaps != null) {
+ return writeBitmaps.getObjectSet();
+ }
+
+ ObjectIdOwnerMap<ObjectIdOwnerMap.Entry> r = new ObjectIdOwnerMap<>();
for (BlockList<ObjectToPack> objList : objectsLists) {
if (objList != null) {
for (ObjectToPack otp : objList)
- objs.add(new ObjectIdOwnerMap.Entry(otp) {
+ r.add(new ObjectIdOwnerMap.Entry(otp) {
// A new entry that copies the ObjectId
});
}
}
- return objs;
+ return r;
}
/**