]> source.dussan.org Git - jgit.git/commitdiff
PackWriter: Display totals after sending objects 87/2387/2
authorShawn O. Pearce <spearce@spearce.org>
Mon, 31 Jan 2011 16:58:23 +0000 (08:58 -0800)
committerShawn O. Pearce <spearce@spearce.org>
Thu, 3 Feb 2011 01:17:57 +0000 (17:17 -0800)
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>
org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties
org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java
org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java
org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java

index 9b1cb0c919994c9669836b6b638b86269743e66d..bc4603eeb96a043953b85f90c20fd134cc021f3b 100644 (file)
@@ -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
index bd63a42db55426e4f68ee64c61369a5905d98909..2834bd2549278b3dc855690f20aa37d8f1b7f5b7 100644 (file)
@@ -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;
index 3f6a091fcbee778332e17a28dae9b56f883c0cc2..320fa3b008c0cae895976e57cb94fdcc6d28e736 100644 (file)
@@ -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);
+               }
+       }
 }
index 1082cc06e18ff0a48de8591d8c49d50c929962d1..d8edfa0df326fe19f354662c7d09380fbaa1e1b1 100644 (file)
@@ -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();