Browse Source

PackWriter: Display totals after sending objects

CGit pack-objects displays a totals line after the pack data
was fully written.  This can be useful to understand some of
the decisions made by the packer, and has been a great tool
for helping to debug some of that code.

Track some of the basic values, and send it to the client when
packing is done:

  remote: Counting objects: 1826776, done
  remote: Finding sources: 100% (55121/55121)
  remote: Getting sizes: 100% (25654/25654)
  remote: Compressing objects: 100% (11434/11434)
  remote: Total 1861830 (delta 3926), reused 1854705 (delta 38306)
  Receiving objects: 100% (1861830/1861830), 386.03 MiB | 30.32 MiB/s, done.

Change-Id: If3b039017a984ed5d5ae80940ce32bda93652df5
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
stable-0.11
Shawn O. Pearce 14 years ago
parent
commit
71f168fcd7
  1. 1
      org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties
  2. 1
      org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java
  3. 36
      org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java
  4. 20
      org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java

1
org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties

@ -329,6 +329,7 @@ packetSizeMustBeAtMost=packet size {0} must be <= {1}
packfileCorruptionDetected=Packfile corruption detected: {0}
packfileIsTruncated=Packfile is truncated.
packingCancelledDuringObjectsWriting=Packing cancelled during objects writing
packWriterStatistics=Total {0,number,#0} (delta {1,number,#0}), reused {2,number,#0} (delta {3,number,#0})
pathIsNotInWorkingDir=Path is not in working dir
peeledLineBeforeRef=Peeled line before ref.
peerDidNotSupplyACompleteObjectGraph=peer did not supply a complete object graph

1
org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java

@ -389,6 +389,7 @@ public class JGitText extends TranslationBundle {
/***/ public String packfileCorruptionDetected;
/***/ public String packfileIsTruncated;
/***/ public String packingCancelledDuringObjectsWriting;
/***/ public String packWriterStatistics;
/***/ public String pathIsNotInWorkingDir;
/***/ public String peeledLineBeforeRef;
/***/ public String peerDidNotSupplyACompleteObjectGraph;

36
org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java

@ -50,6 +50,7 @@ import static org.eclipse.jgit.storage.pack.StoredObjectRepresentation.PACK_WHOL
import java.io.IOException;
import java.io.OutputStream;
import java.security.MessageDigest;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@ -155,6 +156,8 @@ public class PackWriter {
private final PackConfig config;
private final Statistics stats;
private List<ObjectToPack> sortedByName;
private byte packcsum[];
@ -229,6 +232,7 @@ public class PackWriter {
deltaBaseAsOffset = config.isDeltaBaseAsOffset();
reuseDeltas = config.isReuseDeltas();
stats = new Statistics();
}
/**
@ -498,6 +502,7 @@ public class PackWriter {
packStream, this);
int objCnt = getObjectsNumber();
stats.totalObjects = objCnt;
writeMonitor.beginTask(JGitText.get().writingObjects, objCnt);
out.writeFileHeader(PACK_VERSION_GENERATED, objCnt);
out.flush();
@ -508,6 +513,15 @@ public class PackWriter {
writeMonitor.endTask();
}
/**
* @return description of what this PackWriter did in order to create the
* final pack stream. The object is only available to callers after
* {@link #writePack(ProgressMonitor, ProgressMonitor, OutputStream)}
*/
public Statistics getStatistics() {
return stats;
}
/** Release all resources used by this writer. */
public void release() {
reader.release();
@ -846,6 +860,9 @@ public class PackWriter {
reuseSupport.copyObjectAsIs(out, otp);
out.endObject();
otp.setCRC(out.getCRC32());
stats.reusedObjects++;
if (otp.isDeltaRepresentation())
stats.reusedDeltas++;
return;
} catch (StoredObjectRepresentationNotAvailableException gone) {
if (otp.getOffset() == out.length()) {
@ -940,6 +957,7 @@ public class PackWriter {
DeflaterOutputStream dst = new DeflaterOutputStream(out, deflater);
delta.writeTo(dst, null);
dst.finish();
stats.totalDeltas++;
}
private TemporaryBuffer.Heap delta(final ObjectToPack otp)
@ -1167,4 +1185,22 @@ public class PackWriter {
otp.select(next);
}
/** Summary of how PackWriter created the pack. */
public static class Statistics {
long totalObjects;
long totalDeltas;
long reusedObjects;
long reusedDeltas;
/** @return formatted message string for display to clients. */
public String getMessage() {
return MessageFormat.format(JGitText.get().packWriterStatistics, //
totalObjects, totalDeltas, //
reusedObjects, reusedDeltas);
}
}
}

20
org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java

@ -57,6 +57,7 @@ import java.util.Set;
import org.eclipse.jgit.JGitText;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.errors.PackProtocolException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ProgressMonitor;
@ -614,6 +615,7 @@ public class UploadPack {
ProgressMonitor pm = NullProgressMonitor.INSTANCE;
OutputStream packOut = rawOut;
SideBandOutputStream msgOut = null;
if (sideband) {
int bufsz = SideBandOutputStream.SMALL_BUF;
@ -622,9 +624,11 @@ public class UploadPack {
packOut = new SideBandOutputStream(SideBandOutputStream.CH_DATA,
bufsz, rawOut);
if (!options.contains(OPTION_NO_PROGRESS))
pm = new SideBandProgressMonitor(new SideBandOutputStream(
SideBandOutputStream.CH_PROGRESS, bufsz, rawOut));
if (!options.contains(OPTION_NO_PROGRESS)) {
msgOut = new SideBandOutputStream(
SideBandOutputStream.CH_PROGRESS, bufsz, rawOut);
pm = new SideBandProgressMonitor(msgOut);
}
}
PackConfig cfg = packConfig;
@ -650,11 +654,19 @@ public class UploadPack {
pw.addObject(t);
}
}
pw.writePack(pm, NullProgressMonitor.INSTANCE, packOut);
packOut.flush();
if (msgOut != null) {
String msg = pw.getStatistics().getMessage() + '\n';
msgOut.write(Constants.encode(msg));
msgOut.flush();
}
} finally {
pw.release();
}
packOut.flush();
if (sideband)
pckOut.end();

Loading…
Cancel
Save