Browse Source

Add negotiation statistics to PackStatistics

Add fetch statistics for the counts of advertised refs, wants and haves.
Also add the duration in milliseconds for the negotiation phase. For
non-bidirectional transports like HTTP, this is the time for the final
round that sends the pack back to the user.

Change-Id: I1af7ffd3cb7b62182340682e2a243691ea24ec2e
Signed-off-by: Terry Parker <tparker@google.com>
stable-4.11
Terry Parker 7 years ago
parent
commit
302596cc67
  1. 22
      org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java
  2. 72
      org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackStatistics.java
  3. 29
      org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java

22
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java

@ -81,6 +81,7 @@ import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.LargeObjectException;
@ -355,6 +356,24 @@ public class PackWriter implements AutoCloseable {
* reader to read from the repository with.
*/
public PackWriter(final PackConfig config, final ObjectReader reader) {
this(config, reader, null);
}
/**
* Create writer with a specified configuration.
* <p>
* Objects for packing are specified in {@link #preparePack(Iterator)} or
* {@link #preparePack(ProgressMonitor, Set, Set)}.
*
* @param config
* configuration for the pack writer.
* @param reader
* reader to read from the repository with.
* @param statsAccumulator
* accumulator for statics
*/
public PackWriter(PackConfig config, final ObjectReader reader,
@Nullable PackStatistics.Accumulator statsAccumulator) {
this.config = config;
this.reader = reader;
if (reader instanceof ObjectReuseAsIs)
@ -365,7 +384,8 @@ public class PackWriter implements AutoCloseable {
deltaBaseAsOffset = config.isDeltaBaseAsOffset();
reuseDeltas = config.isReuseDeltas();
reuseValidate = true; // be paranoid by default
stats = new PackStatistics.Accumulator();
stats = statsAccumulator != null ? statsAccumulator
: new PackStatistics.Accumulator();
state = new MutableState();
selfRef = new WeakReference<>(this);
instances.put(selfRef, Boolean.TRUE);

72
org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackStatistics.java

@ -166,6 +166,36 @@ public class PackStatistics {
* POJO for accumulating the statistics.
*/
public static class Accumulator {
/**
* The count of references in the ref advertisement.
*
* @since 4.11
*/
public long advertised;
/**
* The count of client wants.
*
* @since 4.11
*/
public long wants;
/**
* The count of client haves.
*
* @since 4.11
*/
public long haves;
/**
* Time in ms spent in the negotiation phase. For non-bidirectional
* transports (e.g., HTTP), this is only for the final request that
* sends back the pack file.
*
* @since 4.11
*/
public long timeNegotiating;
/** The set of objects to be included in the pack. */
public Set<ObjectId> interestingObjects;
@ -270,6 +300,48 @@ public class PackStatistics {
statistics = accumulator;
}
/**
* Get the count of references in the ref advertisement.
*
* @return count of refs in the ref advertisement.
* @since 4.11
*/
public long getAdvertised() {
return statistics.advertised;
}
/**
* Get the count of client wants.
*
* @return count of client wants.
* @since 4.11
*/
public long getWants() {
return statistics.wants;
}
/**
* Get the count of client haves.
*
* @return count of client haves.
* @since 4.11
*/
public long getHaves() {
return statistics.haves;
}
/**
* Time in ms spent in the negotiation phase. For non-bidirectional
* transports (e.g., HTTP), this is only for the final request that sends
* back the pack file.
*
* @return time for ref advertisement in ms.
* @since 4.11
*/
public long getTimeNegotiating() {
return statistics.timeNegotiating;
}
/**
* Get unmodifiable collection of objects to be included in the pack.
*

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

@ -773,6 +773,7 @@ public class UploadPack {
boolean sendPack = false;
// If it's a non-bidi request, we need to read the entire request before
// writing a response. Buffer the response until then.
PackStatistics.Accumulator accumulator = new PackStatistics.Accumulator();
try {
if (biDirectionalPipe)
sendAdvertisedRefs(new PacketLineOutRefAdvertiser(pckOut));
@ -781,12 +782,15 @@ public class UploadPack {
else
advertised = refIdSet(getAdvertisedOrDefaultRefs().values());
long negotiateStart = System.currentTimeMillis();
accumulator.advertised = advertised.size();
recvWants();
if (wantIds.isEmpty()) {
preUploadHook.onBeginNegotiateRound(this, wantIds, 0);
preUploadHook.onEndNegotiateRound(this, wantIds, 0, 0, false);
return;
}
accumulator.wants = wantIds.size();
if (options.contains(OPTION_MULTI_ACK_DETAILED)) {
multiAck = MultiAck.DETAILED;
@ -802,7 +806,10 @@ public class UploadPack {
processShallow();
if (!clientShallowCommits.isEmpty())
walk.assumeShallow(clientShallowCommits);
sendPack = negotiate();
sendPack = negotiate(accumulator);
accumulator.timeNegotiating += System.currentTimeMillis()
- negotiateStart;
if (sendPack && !biDirectionalPipe) {
// Ensure the request was fully consumed. Any remaining input must
// be a protocol error. If we aren't at EOF the implementation is broken.
@ -849,7 +856,7 @@ public class UploadPack {
}
if (sendPack)
sendPack();
sendPack(accumulator);
}
private static Set<ObjectId> refIdSet(Collection<Ref> refs) {
@ -1093,7 +1100,8 @@ public class UploadPack {
return UserAgent.getAgent(options, userAgent);
}
private boolean negotiate() throws IOException {
private boolean negotiate(PackStatistics.Accumulator accumulator)
throws IOException {
okToGiveUp = Boolean.FALSE;
ObjectId last = ObjectId.zeroId();
@ -1127,7 +1135,7 @@ public class UploadPack {
} else if (line.startsWith("have ") && line.length() == 45) { //$NON-NLS-1$
peerHas.add(ObjectId.fromString(line.substring(5)));
accumulator.haves++;
} else if (line.equals("done")) { //$NON-NLS-1$
last = processHaveLines(peerHas, last);
@ -1485,12 +1493,13 @@ public class UploadPack {
return false;
}
private void sendPack() throws IOException {
private void sendPack(PackStatistics.Accumulator accumulator)
throws IOException {
final boolean sideband = options.contains(OPTION_SIDE_BAND)
|| options.contains(OPTION_SIDE_BAND_64K);
if (sideband) {
try {
sendPack(true);
sendPack(true, accumulator);
} catch (ServiceMayNotContinueException noPack) {
// This was already reported on (below).
throw noPack;
@ -1511,7 +1520,7 @@ public class UploadPack {
throw err;
}
} else {
sendPack(false);
sendPack(false, accumulator);
}
}
@ -1532,7 +1541,8 @@ public class UploadPack {
}
@SuppressWarnings("deprecation")
private void sendPack(final boolean sideband) throws IOException {
private void sendPack(final boolean sideband,
PackStatistics.Accumulator accumulator) throws IOException {
ProgressMonitor pm = NullProgressMonitor.INSTANCE;
OutputStream packOut = rawOut;
@ -1573,7 +1583,8 @@ public class UploadPack {
PackConfig cfg = packConfig;
if (cfg == null)
cfg = new PackConfig(db);
final PackWriter pw = new PackWriter(cfg, walk.getObjectReader());
final PackWriter pw = new PackWriter(cfg, walk.getObjectReader(),
accumulator);
try {
pw.setIndexDisabled(true);
pw.setUseCachedPacks(true);

Loading…
Cancel
Save