summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit/src
diff options
context:
space:
mode:
authorShawn Pearce <spearce@spearce.org>2013-04-16 09:25:29 -0700
committerGerrit Code Review @ Eclipse.org <gerrit@eclipse.org>2013-04-17 14:43:01 -0400
commit5d8a9f6f3f43ac43c6b1c48cdfad55e545171ea3 (patch)
treead702d27a394719a8aef3995abce7c2d340a0a0f /org.eclipse.jgit/src
parent21e4aa2b9eaf392825e52ada6034cc3044c69c67 (diff)
downloadjgit-5d8a9f6f3f43ac43c6b1c48cdfad55e545171ea3.tar.gz
jgit-5d8a9f6f3f43ac43c6b1c48cdfad55e545171ea3.zip
Rescale "Compressing objects" progress meter by size
Instead of counting objects processed, count number of bytes added into the window. This should rescale the progress meter so that 30% complete means 30% of the total uncompressed content size has been inflated and fed into the window. In theory the progress meter should be more accurate about its percentage complete/remaining fraction than with objects. When counting objects small objects move the progress meter more rapidly than large objects, but demand a smaller amount of work than large objects being compressed. Change-Id: Id2848c16a2148b5ca51e0ca1e29c5be97eefeb48
Diffstat (limited to 'org.eclipse.jgit/src')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java16
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaWindow.java13
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java45
3 files changed, 58 insertions, 16 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java
index ca2fff6882..c4b01949d1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java
@@ -57,6 +57,8 @@ import org.eclipse.jgit.lib.ThreadSafeProgressMonitor;
import org.eclipse.jgit.storage.pack.PackConfig;
final class DeltaTask implements Callable<Object> {
+ static final long MAX_METER = 9 << 20;
+
static final class Block {
private static final int MIN_TOP_PATH = 50 << 20;
@@ -71,6 +73,7 @@ final class DeltaTask implements Callable<Object> {
final int endIndex;
private long totalWeight;
+ private long bytesPerUnit;
Block(int threads, PackConfig config, ObjectReader reader,
DeltaCache dc, ThreadSafeProgressMonitor pm,
@@ -86,6 +89,13 @@ final class DeltaTask implements Callable<Object> {
this.endIndex = end;
}
+ int cost() {
+ int d = (int) (totalWeight / bytesPerUnit);
+ if (totalWeight % bytesPerUnit != 0)
+ d++;
+ return d;
+ }
+
synchronized DeltaWindow stealWork(DeltaTask forThread) {
for (;;) {
DeltaTask maxTask = null;
@@ -200,6 +210,10 @@ final class DeltaTask implements Callable<Object> {
return a.slice.beginIndex - b.slice.beginIndex;
}
});
+
+ bytesPerUnit = 1;
+ while (MAX_METER <= (totalWeight / bytesPerUnit))
+ bytesPerUnit <<= 10;
return topPaths;
}
}
@@ -282,7 +296,7 @@ final class DeltaTask implements Callable<Object> {
DeltaWindow initWindow(Slice s) {
DeltaWindow w = new DeltaWindow(block.config, block.dc,
- or, block.pm,
+ or, block.pm, block.bytesPerUnit,
block.list, s.beginIndex, s.endIndex);
synchronized (this) {
dw = w;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaWindow.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaWindow.java
index cc7fac8007..19d06a23f8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaWindow.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaWindow.java
@@ -64,6 +64,8 @@ final class DeltaWindow {
private final DeltaCache deltaCache;
private final ObjectReader reader;
private final ProgressMonitor monitor;
+ private final long bytesPerUnit;
+ private long bytesProcessed;
/** Maximum number of bytes to admit to the window at once. */
private final long maxMemory;
@@ -92,12 +94,13 @@ final class DeltaWindow {
private Deflater deflater;
DeltaWindow(PackConfig pc, DeltaCache dc, ObjectReader or,
- ProgressMonitor pm,
+ ProgressMonitor pm, long bpu,
ObjectToPack[] in, int beginIndex, int endIndex) {
config = pc;
deltaCache = dc;
reader = or;
monitor = pm;
+ bytesPerUnit = bpu;
toSearch = in;
cur = beginIndex;
end = endIndex;
@@ -162,12 +165,14 @@ final class DeltaWindow {
// We don't actually want to make a delta for
// them, just need to push them into the window
// so they can be read by other objects.
- //
keepInWindow();
} else {
// Search for a delta for the current window slot.
- //
- monitor.update(1);
+ if (bytesPerUnit <= (bytesProcessed += next.getWeight())) {
+ int d = (int) (bytesProcessed / bytesPerUnit);
+ monitor.update(d);
+ bytesProcessed -= d * bytesPerUnit;
+ }
searchInWindow();
}
}
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 a3ef27c217..a7122592f3 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
@@ -1286,9 +1286,7 @@ public class PackWriter {
return;
final long searchStart = System.currentTimeMillis();
- beginPhase(PackingPhase.COMPRESSING, monitor, nonEdgeCnt);
searchForDeltas(monitor, list, cnt);
- endPhase(monitor);
stats.deltaSearchNonEdgeObjects = nonEdgeCnt;
stats.timeCompressing = System.currentTimeMillis() - searchStart;
@@ -1327,25 +1325,49 @@ public class PackWriter {
int threads = config.getThreads();
if (threads == 0)
threads = Runtime.getRuntime().availableProcessors();
+ if (threads <= 1 || cnt <= config.getDeltaSearchWindowSize())
+ singleThreadDeltaSearch(monitor, list, cnt);
+ else
+ parallelDeltaSearch(monitor, list, cnt, threads);
+ }
- if (threads <= 1 || cnt <= 2 * config.getDeltaSearchWindowSize()) {
- new DeltaWindow(config, new DeltaCache(config), reader, monitor,
- list, 0, cnt).search();
- return;
+ private void singleThreadDeltaSearch(ProgressMonitor monitor,
+ ObjectToPack[] list, int cnt) throws IOException {
+ long totalWeight = 0;
+ for (int i = 0; i < cnt; i++) {
+ ObjectToPack o = list[i];
+ if (!o.isEdge() && !o.doNotAttemptDelta())
+ totalWeight += o.getWeight();
}
- final DeltaCache dc = new ThreadSafeDeltaCache(config);
- final ThreadSafeProgressMonitor pm = new ThreadSafeProgressMonitor(monitor);
+ long bytesPerUnit = 1;
+ while (DeltaTask.MAX_METER <= (totalWeight / bytesPerUnit))
+ bytesPerUnit <<= 10;
+ int cost = (int) (totalWeight / bytesPerUnit);
+ if (totalWeight % bytesPerUnit != 0)
+ cost++;
+ beginPhase(PackingPhase.COMPRESSING, monitor, cost);
+ new DeltaWindow(config, new DeltaCache(config), reader,
+ monitor, bytesPerUnit,
+ list, 0, cnt).search();
+ endPhase(monitor);
+ }
+
+ private void parallelDeltaSearch(ProgressMonitor monitor,
+ ObjectToPack[] list, int cnt, int threads) throws IOException {
+ DeltaCache dc = new ThreadSafeDeltaCache(config);
+ ThreadSafeProgressMonitor pm = new ThreadSafeProgressMonitor(monitor);
DeltaTask.Block taskBlock = new DeltaTask.Block(threads, config,
reader, dc, pm,
list, 0, cnt);
taskBlock.partitionTasks();
+ beginPhase(PackingPhase.COMPRESSING, monitor, taskBlock.cost());
pm.startWorkers(taskBlock.tasks.size());
- final Executor executor = config.getExecutor();
- final List<Throwable> errors = Collections
- .synchronizedList(new ArrayList<Throwable>());
+ Executor executor = config.getExecutor();
+ final List<Throwable> errors =
+ Collections.synchronizedList(new ArrayList<Throwable>(threads));
if (executor instanceof ExecutorService) {
// Caller supplied us a service, use it directly.
runTasks((ExecutorService) executor, pm, taskBlock, errors);
@@ -1409,6 +1431,7 @@ public class PackWriter {
fail.initCause(err);
throw fail;
}
+ endPhase(monitor);
}
private static void runTasks(ExecutorService pool,