summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Frade <ifrade@google.com>2021-12-28 14:23:40 -0800
committerIvan Frade <ifrade@google.com>2023-02-24 12:56:33 -0800
commitca2c57b2ec5400db9c9446056b001a83adc5ccd8 (patch)
tree02b4e038982d02ce8a100d047f363ce2ebe79468
parentcfacc43b522cd2f93b0addbb3d6479750d0b73c9 (diff)
downloadjgit-ca2c57b2ec5400db9c9446056b001a83adc5ccd8.tar.gz
jgit-ca2c57b2ec5400db9c9446056b001a83adc5ccd8.zip
PackWriter: offer to write an object-size index for the pack
PackWriter callers tell the writer what do the want to include in the pack and invoke #writePack(). Afterwards, they can invoke #writeIndex() to write the corresponding pack index. Mirror this for the object-size index, adding a #writeObjectSizeIndex() method. Change-Id: Ic319975c72c239cd6488303f7d4cced797e6fe00
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java37
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java45
2 files changed, 82 insertions, 0 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java
index 3fe8f52fba..2a403c7699 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java
@@ -505,6 +505,43 @@ public class PackWriterTest extends SampleDataRepositoryTestCase {
}
@Test
+ public void testWriteObjectSizeIndex_noDeltas() throws Exception {
+ config.setMinBytesForObjSizeIndex(0);
+ HashSet<ObjectId> interesting = new HashSet<>();
+ interesting.add(ObjectId
+ .fromString("82c6b885ff600be425b4ea96dee75dca255b69e7"));
+
+ NullProgressMonitor m1 = NullProgressMonitor.INSTANCE;
+ writer = new PackWriter(config, db.newObjectReader());
+ writer.setUseBitmaps(false);
+ writer.setThin(false);
+ writer.setIgnoreMissingUninteresting(false);
+ writer.preparePack(m1, interesting, NONE);
+ writer.writePack(m1, m1, os);
+
+ PackIndex idx;
+ try (ByteArrayOutputStream is = new ByteArrayOutputStream()) {
+ writer.writeIndex(is);
+ idx = PackIndex.read(new ByteArrayInputStream(is.toByteArray()));
+ }
+
+ PackObjectSizeIndex objSizeIdx;
+ try (ByteArrayOutputStream objSizeStream = new ByteArrayOutputStream()) {
+ writer.writeObjectSizeIndex(objSizeStream);
+ objSizeIdx = PackObjectSizeIndexLoader.load(
+ new ByteArrayInputStream(objSizeStream.toByteArray()));
+ }
+ writer.close();
+
+ ObjectId knownBlob1 = ObjectId
+ .fromString("5b6e7c66c276e7610d4a73c70ec1a1f7c1003259");
+ ObjectId knownBlob2 = ObjectId
+ .fromString("6ff87c4664981e4397625791c8ea3bbb5f2279a3");
+ assertEquals(18009, objSizeIdx.getSize(idx.findPosition(knownBlob1)));
+ assertEquals(18787, objSizeIdx.getSize(idx.findPosition(knownBlob2)));
+ }
+
+ @Test
public void testExclude() throws Exception {
// TestRepository closes repo
FileRepository repo = createBareRepository();
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 d42d348a1c..bad572459a 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
@@ -61,6 +61,7 @@ import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.internal.storage.file.PackBitmapIndexBuilder;
import org.eclipse.jgit.internal.storage.file.PackBitmapIndexWriterV1;
import org.eclipse.jgit.internal.storage.file.PackIndexWriter;
+import org.eclipse.jgit.internal.storage.file.PackObjectSizeIndexWriter;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.AsyncObjectSizeQueue;
import org.eclipse.jgit.lib.BatchingProgressMonitor;
@@ -1092,6 +1093,50 @@ public class PackWriter implements AutoCloseable {
}
/**
+ * Create an object size index file for the contents of the pack file just
+ * written.
+ * <p>
+ * Called after
+ * {@link #writePack(ProgressMonitor, ProgressMonitor, OutputStream)} that
+ * populates the list of objects to pack and before
+ * {@link #writeBitmapIndex(OutputStream)} that destroys it.
+ * <p>
+ * Writing this index is only required for local pack storage. Packs sent on
+ * the network do not need to create an object size index.
+ *
+ * @param objIdxStream
+ * output for the object size index data. Caller is responsible
+ * for closing this stream.
+ * @throws IOException
+ * errors while writing
+ */
+ public void writeObjectSizeIndex(OutputStream objIdxStream)
+ throws IOException {
+ if (config.getMinBytesForObjSizeIndex() < 0) {
+ return;
+ }
+
+ long writeStart = System.currentTimeMillis();
+ // We only need to populate the size of blobs
+ AsyncObjectSizeQueue<ObjectToPack> sizeQueue = reader
+ .getObjectSize(objectsLists[OBJ_BLOB], /* reportMissing= */false);
+ try {
+ while (sizeQueue.next()) {
+ ObjectToPack otp = sizeQueue.getCurrent();
+ long sz = sizeQueue.getSize();
+ otp.setFullSize(sz);
+ }
+ } finally {
+ sizeQueue.release();
+ }
+ PackObjectSizeIndexWriter iw = PackObjectSizeIndexWriter.createWriter(
+ objIdxStream, config.getMinBytesForObjSizeIndex());
+ // All indexed objects because their positions must match primary index order
+ iw.write(sortByName());
+ stats.timeWriting += System.currentTimeMillis() - writeStart;
+ }
+
+ /**
* Create a bitmap index file to match the pack file just written.
* <p>
* Called after {@link #prepareBitmapIndex(ProgressMonitor)}.