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} packfileCorruptionDetected=Packfile corruption detected: {0}
packfileIsTruncated=Packfile is truncated. packfileIsTruncated=Packfile is truncated.
packingCancelledDuringObjectsWriting=Packing cancelled during objects writing 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 pathIsNotInWorkingDir=Path is not in working dir
peeledLineBeforeRef=Peeled line before ref. peeledLineBeforeRef=Peeled line before ref.
peerDidNotSupplyACompleteObjectGraph=peer did not supply a complete object graph 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 packfileCorruptionDetected;
/***/ public String packfileIsTruncated; /***/ public String packfileIsTruncated;
/***/ public String packingCancelledDuringObjectsWriting; /***/ public String packingCancelledDuringObjectsWriting;
/***/ public String packWriterStatistics;
/***/ public String pathIsNotInWorkingDir; /***/ public String pathIsNotInWorkingDir;
/***/ public String peeledLineBeforeRef; /***/ public String peeledLineBeforeRef;
/***/ public String peerDidNotSupplyACompleteObjectGraph; /***/ 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.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@ -155,6 +156,8 @@ public class PackWriter {
private final PackConfig config; private final PackConfig config;
private final Statistics stats;
private List<ObjectToPack> sortedByName; private List<ObjectToPack> sortedByName;
private byte packcsum[]; private byte packcsum[];
@ -229,6 +232,7 @@ public class PackWriter {
deltaBaseAsOffset = config.isDeltaBaseAsOffset(); deltaBaseAsOffset = config.isDeltaBaseAsOffset();
reuseDeltas = config.isReuseDeltas(); reuseDeltas = config.isReuseDeltas();
stats = new Statistics();
} }
/** /**
@ -498,6 +502,7 @@ public class PackWriter {
packStream, this); packStream, this);
int objCnt = getObjectsNumber(); int objCnt = getObjectsNumber();
stats.totalObjects = objCnt;
writeMonitor.beginTask(JGitText.get().writingObjects, objCnt); writeMonitor.beginTask(JGitText.get().writingObjects, objCnt);
out.writeFileHeader(PACK_VERSION_GENERATED, objCnt); out.writeFileHeader(PACK_VERSION_GENERATED, objCnt);
out.flush(); out.flush();
@ -508,6 +513,15 @@ public class PackWriter {
writeMonitor.endTask(); 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. */ /** Release all resources used by this writer. */
public void release() { public void release() {
reader.release(); reader.release();
@ -846,6 +860,9 @@ public class PackWriter {
reuseSupport.copyObjectAsIs(out, otp); reuseSupport.copyObjectAsIs(out, otp);
out.endObject(); out.endObject();
otp.setCRC(out.getCRC32()); otp.setCRC(out.getCRC32());
stats.reusedObjects++;
if (otp.isDeltaRepresentation())
stats.reusedDeltas++;
return; return;
} catch (StoredObjectRepresentationNotAvailableException gone) { } catch (StoredObjectRepresentationNotAvailableException gone) {
if (otp.getOffset() == out.length()) { if (otp.getOffset() == out.length()) {
@ -940,6 +957,7 @@ public class PackWriter {
DeflaterOutputStream dst = new DeflaterOutputStream(out, deflater); DeflaterOutputStream dst = new DeflaterOutputStream(out, deflater);
delta.writeTo(dst, null); delta.writeTo(dst, null);
dst.finish(); dst.finish();
stats.totalDeltas++;
} }
private TemporaryBuffer.Heap delta(final ObjectToPack otp) private TemporaryBuffer.Heap delta(final ObjectToPack otp)
@ -1167,4 +1185,22 @@ public class PackWriter {
otp.select(next); 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.JGitText;
import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.errors.PackProtocolException; import org.eclipse.jgit.errors.PackProtocolException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.NullProgressMonitor; import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.ProgressMonitor;
@ -614,6 +615,7 @@ public class UploadPack {
ProgressMonitor pm = NullProgressMonitor.INSTANCE; ProgressMonitor pm = NullProgressMonitor.INSTANCE;
OutputStream packOut = rawOut; OutputStream packOut = rawOut;
SideBandOutputStream msgOut = null;
if (sideband) { if (sideband) {
int bufsz = SideBandOutputStream.SMALL_BUF; int bufsz = SideBandOutputStream.SMALL_BUF;
@ -622,9 +624,11 @@ public class UploadPack {
packOut = new SideBandOutputStream(SideBandOutputStream.CH_DATA, packOut = new SideBandOutputStream(SideBandOutputStream.CH_DATA,
bufsz, rawOut); bufsz, rawOut);
if (!options.contains(OPTION_NO_PROGRESS)) if (!options.contains(OPTION_NO_PROGRESS)) {
pm = new SideBandProgressMonitor(new SideBandOutputStream( msgOut = new SideBandOutputStream(
SideBandOutputStream.CH_PROGRESS, bufsz, rawOut)); SideBandOutputStream.CH_PROGRESS, bufsz, rawOut);
pm = new SideBandProgressMonitor(msgOut);
}
} }
PackConfig cfg = packConfig; PackConfig cfg = packConfig;
@ -650,11 +654,19 @@ public class UploadPack {
pw.addObject(t); pw.addObject(t);
} }
} }
pw.writePack(pm, NullProgressMonitor.INSTANCE, packOut); 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 { } finally {
pw.release(); pw.release();
} }
packOut.flush();
if (sideband) if (sideband)
pckOut.end(); pckOut.end();

Loading…
Cancel
Save