summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java286
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java40
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLogger.java75
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLoggerChain.java96
4 files changed, 497 insertions, 0 deletions
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 e31f2412c0..19b6b080da 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
@@ -2057,6 +2057,292 @@ public class PackWriter implements AutoCloseable {
return true;
}
+ /**
+ * Summary of how PackWriter created the pack.
+ *
+ * @deprecated Use {@link PackStatistics} instead.
+ */
+ @Deprecated
+ public static class Statistics {
+ /** Statistics about a single class of object. */
+ public static class ObjectType {
+ // All requests are forwarded to this object.
+ private PackStatistics.ObjectType objectType;
+
+ /**
+ * Wraps an
+ * {@link org.eclipse.jgit.storage.pack.PackStatistics.ObjectType}
+ * instance to maintain backwards compatibility with existing API.
+ *
+ * @param type
+ * the wrapped instance
+ */
+ public ObjectType(PackStatistics.ObjectType type) {
+ objectType = type;
+ }
+
+ /**
+ * @return total number of objects output. This total includes the
+ * value of {@link #getDeltas()}.
+ */
+ public long getObjects() {
+ return objectType.getObjects();
+ }
+
+ /**
+ * @return total number of deltas output. This may be lower than the
+ * actual number of deltas if a cached pack was reused.
+ */
+ public long getDeltas() {
+ return objectType.getDeltas();
+ }
+
+ /**
+ * @return number of objects whose existing representation was
+ * reused in the output. This count includes
+ * {@link #getReusedDeltas()}.
+ */
+ public long getReusedObjects() {
+ return objectType.getReusedObjects();
+ }
+
+ /**
+ * @return number of deltas whose existing representation was reused
+ * in the output, as their base object was also output or
+ * was assumed present for a thin pack. This may be lower
+ * than the actual number of reused deltas if a cached pack
+ * was reused.
+ */
+ public long getReusedDeltas() {
+ return objectType.getReusedDeltas();
+ }
+
+ /**
+ * @return total number of bytes written. This size includes the
+ * object headers as well as the compressed data. This size
+ * also includes all of {@link #getDeltaBytes()}.
+ */
+ public long getBytes() {
+ return objectType.getBytes();
+ }
+
+ /**
+ * @return number of delta bytes written. This size includes the
+ * object headers for the delta objects.
+ */
+ public long getDeltaBytes() {
+ return objectType.getDeltaBytes();
+ }
+ }
+
+ // All requests are forwarded to this object.
+ private PackStatistics statistics;
+
+ /**
+ * Wraps a {@link PackStatistics} object to maintain backwards
+ * compatibility with existing API.
+ *
+ * @param stats
+ * the wrapped PackStatitics object
+ */
+ public Statistics(PackStatistics stats) {
+ statistics = stats;
+ }
+
+ /**
+ * @return unmodifiable collection of objects to be included in the
+ * pack. May be null if the pack was hand-crafted in a unit
+ * test.
+ */
+ public Set<ObjectId> getInterestingObjects() {
+ return statistics.getInterestingObjects();
+ }
+
+ /**
+ * @return unmodifiable collection of objects that should be excluded
+ * from the pack, as the peer that will receive the pack already
+ * has these objects.
+ */
+ public Set<ObjectId> getUninterestingObjects() {
+ return statistics.getUninterestingObjects();
+ }
+
+ /**
+ * @return unmodifiable collection of the cached packs that were reused
+ * in the output, if any were selected for reuse.
+ */
+ public Collection<CachedPack> getReusedPacks() {
+ return statistics.getReusedPacks();
+ }
+
+ /**
+ * @return number of objects in the output pack that went through the
+ * delta search process in order to find a potential delta base.
+ */
+ public int getDeltaSearchNonEdgeObjects() {
+ return statistics.getDeltaSearchNonEdgeObjects();
+ }
+
+ /**
+ * @return number of objects in the output pack that went through delta
+ * base search and found a suitable base. This is a subset of
+ * {@link #getDeltaSearchNonEdgeObjects()}.
+ */
+ public int getDeltasFound() {
+ return statistics.getDeltasFound();
+ }
+
+ /**
+ * @return total number of objects output. This total includes the value
+ * of {@link #getTotalDeltas()}.
+ */
+ public long getTotalObjects() {
+ return statistics.getTotalObjects();
+ }
+
+ /**
+ * @return the count of objects that needed to be discovered through an
+ * object walk because they were not found in bitmap indices.
+ * Returns -1 if no bitmap indices were found.
+ *
+ * @since 4.0
+ */
+ public long getBitmapIndexMisses() {
+ return statistics.getBitmapIndexMisses();
+ }
+
+ /**
+ * @return total number of deltas output. This may be lower than the
+ * actual number of deltas if a cached pack was reused.
+ */
+ public long getTotalDeltas() {
+ return statistics.getTotalDeltas();
+ }
+
+ /**
+ * @return number of objects whose existing representation was reused in
+ * the output. This count includes {@link #getReusedDeltas()}.
+ */
+ public long getReusedObjects() {
+ return statistics.getReusedObjects();
+ }
+
+ /**
+ * @return number of deltas whose existing representation was reused in
+ * the output, as their base object was also output or was
+ * assumed present for a thin pack. This may be lower than the
+ * actual number of reused deltas if a cached pack was reused.
+ */
+ public long getReusedDeltas() {
+ return statistics.getReusedDeltas();
+ }
+
+ /**
+ * @return total number of bytes written. This size includes the pack
+ * header, trailer, thin pack, and reused cached pack(s).
+ */
+ public long getTotalBytes() {
+ return statistics.getTotalBytes();
+ }
+
+ /**
+ * @return size of the thin pack in bytes, if a thin pack was generated.
+ * A thin pack is created when the client already has objects
+ * and some deltas are created against those objects, or if a
+ * cached pack is being used and some deltas will reference
+ * objects in the cached pack. This size does not include the
+ * pack header or trailer.
+ */
+ public long getThinPackBytes() {
+ return statistics.getThinPackBytes();
+ }
+
+ /**
+ * @param typeCode
+ * object type code, e.g. OBJ_COMMIT or OBJ_TREE.
+ * @return information about this type of object in the pack.
+ */
+ public ObjectType byObjectType(int typeCode) {
+ return new ObjectType(statistics.byObjectType(typeCode));
+ }
+
+ /** @return true if the resulting pack file was a shallow pack. */
+ public boolean isShallow() {
+ return statistics.isShallow();
+ }
+
+ /** @return depth (in commits) the pack includes if shallow. */
+ public int getDepth() {
+ return statistics.getDepth();
+ }
+
+ /**
+ * @return time in milliseconds spent enumerating the objects that need
+ * to be included in the output. This time includes any restarts
+ * that occur when a cached pack is selected for reuse.
+ */
+ public long getTimeCounting() {
+ return statistics.getTimeCounting();
+ }
+
+ /**
+ * @return time in milliseconds spent matching existing representations
+ * against objects that will be transmitted, or that the client
+ * can be assumed to already have.
+ */
+ public long getTimeSearchingForReuse() {
+ return statistics.getTimeSearchingForReuse();
+ }
+
+ /**
+ * @return time in milliseconds spent finding the sizes of all objects
+ * that will enter the delta compression search window. The
+ * sizes need to be known to better match similar objects
+ * together and improve delta compression ratios.
+ */
+ public long getTimeSearchingForSizes() {
+ return statistics.getTimeSearchingForSizes();
+ }
+
+ /**
+ * @return time in milliseconds spent on delta compression. This is
+ * observed wall-clock time and does not accurately track CPU
+ * time used when multiple threads were used to perform the
+ * delta compression.
+ */
+ public long getTimeCompressing() {
+ return statistics.getTimeCompressing();
+ }
+
+ /**
+ * @return time in milliseconds spent writing the pack output, from
+ * start of header until end of trailer. The transfer speed can
+ * be approximated by dividing {@link #getTotalBytes()} by this
+ * value.
+ */
+ public long getTimeWriting() {
+ return statistics.getTimeWriting();
+ }
+
+ /** @return total time spent processing this pack. */
+ public long getTimeTotal() {
+ return statistics.getTimeTotal();
+ }
+
+ /**
+ * @return get the average output speed in terms of bytes-per-second.
+ * {@code getTotalBytes() / (getTimeWriting() / 1000.0)}.
+ */
+ public double getTransferRate() {
+ return statistics.getTransferRate();
+ }
+
+ /** @return formatted message string for display to clients. */
+ public String getMessage() {
+ return statistics.getMessage();
+ }
+ }
+
private class MutableState {
/** Estimated size of a single ObjectToPack instance. */
// Assume 64-bit pointers, since this is just an estimate.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
index f9ab56d950..101057fb4f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
@@ -312,6 +312,8 @@ public class UploadPack {
private PackStatistics statistics;
+ private UploadPackLogger logger = UploadPackLogger.NULL;
+
/**
* Create a new pack upload for an open repository.
*
@@ -584,6 +586,28 @@ public class UploadPack {
}
/**
+ * @return the configured logger.
+ *
+ * @deprecated Use {@link #getPreUploadHook()}.
+ */
+ @Deprecated
+ public UploadPackLogger getLogger() {
+ return logger;
+ }
+
+ /**
+ * Set the logger.
+ *
+ * @param logger
+ * the logger instance. If null, no logging occurs.
+ * @deprecated Use {@link #setPreUploadHook(PreUploadHook)}.
+ */
+ @Deprecated
+ public void setLogger(UploadPackLogger logger) {
+ this.logger = logger;
+ }
+
+ /**
* Check whether the client expects a side-band stream.
*
* @return true if the client has advertised a side-band capability, false
@@ -659,6 +683,21 @@ public class UploadPack {
* @return statistics about pack output, if a pack was sent. Null if no pack
* was sent, such as during the negotation phase of a smart HTTP
* connection, or if the client was already up-to-date.
+ * @since 3.0
+ * @deprecated Use {@link #getStatistics()}.
+ */
+ @Deprecated
+ public PackWriter.Statistics getPackStatistics() {
+ return statistics == null ? null
+ : new PackWriter.Statistics(statistics);
+ }
+
+ /**
+ * Get the PackWriter's statistics if a pack was sent to the client.
+ *
+ * @return statistics about pack output, if a pack was sent. Null if no pack
+ * was sent, such as during the negotation phase of a smart HTTP
+ * connection, or if the client was already up-to-date.
* @since 4.1
*/
public PackStatistics getStatistics() {
@@ -1508,6 +1547,7 @@ public class UploadPack {
statistics = pw.getStatistics();
if (statistics != null) {
postUploadHook.onPostUpload(statistics);
+ logger.onPackStatistics(new PackWriter.Statistics(statistics));
}
pw.close();
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLogger.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLogger.java
new file mode 100644
index 0000000000..85ebecc450
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLogger.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011, Google Inc.
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.eclipse.jgit.transport;
+
+import org.eclipse.jgit.internal.storage.pack.PackWriter;
+
+/**
+ * Logs activity that occurred within {@link UploadPack}.
+ * <p>
+ * Implementors of the interface are responsible for associating the current
+ * thread to a particular connection, if they need to also include connection
+ * information. One method is to use a {@link java.lang.ThreadLocal} to remember
+ * the connection information before invoking UploadPack.
+ *
+ * @deprecated use {@link PostUploadHook} instead
+ */
+@Deprecated
+public interface UploadPackLogger {
+ /** A simple no-op logger. */
+ public static final UploadPackLogger NULL = new UploadPackLogger() {
+ public void onPackStatistics(PackWriter.Statistics stats) {
+ // Do nothing.
+ }
+ };
+
+ /**
+ * Notice to the logger after a pack has been sent.
+ *
+ * @param stats
+ * the statistics after sending a pack to the client.
+ * @since 3.0
+ */
+ public void onPackStatistics(PackWriter.Statistics stats);
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLoggerChain.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLoggerChain.java
new file mode 100644
index 0000000000..4ea0319d9c
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLoggerChain.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2011, Google Inc.
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.eclipse.jgit.transport;
+
+import java.util.List;
+
+import org.eclipse.jgit.internal.storage.pack.PackWriter;
+
+/**
+ * UploadPackLogger that delegates to a list of other loggers.
+ * <p>
+ * loggers are run in the order passed to the constructor.
+ *
+ * @deprecated Use {@link PostUploadHookChain} instead.
+ */
+@Deprecated
+public class UploadPackLoggerChain implements UploadPackLogger {
+ private final UploadPackLogger[] loggers;
+ private final int count;
+
+ /**
+ * Create a new logger chaining the given loggers together.
+ *
+ * @param loggers
+ * loggers to execute, in order.
+ * @return a new logger chain of the given loggers.
+ */
+ public static UploadPackLogger newChain(
+ List<? extends UploadPackLogger> loggers) {
+ UploadPackLogger[] newLoggers = new UploadPackLogger[loggers.size()];
+ int i = 0;
+ for (UploadPackLogger logger : loggers)
+ if (logger != UploadPackLogger.NULL)
+ newLoggers[i++] = logger;
+ if (i == 0)
+ return UploadPackLogger.NULL;
+ else if (i == 1)
+ return newLoggers[0];
+ else
+ return new UploadPackLoggerChain(newLoggers, i);
+ }
+
+ /**
+ * @since 3.0
+ */
+ public void onPackStatistics(PackWriter.Statistics stats) {
+ for (int i = 0; i < count; i++)
+ loggers[i].onPackStatistics(stats);
+ }
+
+ private UploadPackLoggerChain(UploadPackLogger[] loggers, int count) {
+ this.loggers = loggers;
+ this.count = count;
+ }
+}