|
|
@@ -174,6 +174,8 @@ public class PackWriter { |
|
|
|
|
|
|
|
private final Statistics stats; |
|
|
|
|
|
|
|
private final MutableState state; |
|
|
|
|
|
|
|
private Statistics.ObjectType typeStats; |
|
|
|
|
|
|
|
private List<ObjectToPack> sortedByName; |
|
|
@@ -266,6 +268,7 @@ public class PackWriter { |
|
|
|
reuseDeltas = config.isReuseDeltas(); |
|
|
|
reuseValidate = true; // be paranoid by default |
|
|
|
stats = new Statistics(); |
|
|
|
state = new MutableState(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@@ -744,6 +747,37 @@ public class PackWriter { |
|
|
|
return sortedByName; |
|
|
|
} |
|
|
|
|
|
|
|
private void beginPhase(PackingPhase phase, ProgressMonitor monitor, |
|
|
|
int cnt) { |
|
|
|
state.phase = phase; |
|
|
|
String task; |
|
|
|
switch (phase) { |
|
|
|
case COUNTING: |
|
|
|
task = JGitText.get().countingObjects; |
|
|
|
break; |
|
|
|
case GETTING_SIZES: |
|
|
|
task = JGitText.get().searchForSizes; |
|
|
|
break; |
|
|
|
case FINDING_SOURCES: |
|
|
|
task = JGitText.get().searchForReuse; |
|
|
|
break; |
|
|
|
case COMPRESSING: |
|
|
|
task = JGitText.get().compressingObjects; |
|
|
|
break; |
|
|
|
case WRITING: |
|
|
|
task = JGitText.get().writingObjects; |
|
|
|
break; |
|
|
|
default: |
|
|
|
throw new IllegalArgumentException( |
|
|
|
MessageFormat.format(JGitText.get().illegalPackingPhase, phase)); |
|
|
|
} |
|
|
|
monitor.beginTask(task, cnt); |
|
|
|
} |
|
|
|
|
|
|
|
private void endPhase(ProgressMonitor monitor) { |
|
|
|
monitor.endTask(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Write the prepared pack to the supplied stream. |
|
|
|
* <p> |
|
|
@@ -803,7 +837,7 @@ public class PackWriter { |
|
|
|
|
|
|
|
long objCnt = getObjectCount(); |
|
|
|
stats.totalObjects = objCnt; |
|
|
|
writeMonitor.beginTask(JGitText.get().writingObjects, (int) objCnt); |
|
|
|
beginPhase(PackingPhase.WRITING, writeMonitor, (int) objCnt); |
|
|
|
long writeStart = System.currentTimeMillis(); |
|
|
|
|
|
|
|
out.writeFileHeader(PACK_VERSION_GENERATED, objCnt); |
|
|
@@ -843,7 +877,7 @@ public class PackWriter { |
|
|
|
} |
|
|
|
|
|
|
|
reader.release(); |
|
|
|
writeMonitor.endTask(); |
|
|
|
endPhase(writeMonitor); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@@ -855,6 +889,11 @@ public class PackWriter { |
|
|
|
return stats; |
|
|
|
} |
|
|
|
|
|
|
|
/** @return snapshot of the current state of this PackWriter. */ |
|
|
|
public State getState() { |
|
|
|
return state.snapshot(); |
|
|
|
} |
|
|
|
|
|
|
|
/** Release all resources used by this writer. */ |
|
|
|
public void release() { |
|
|
|
reader.release(); |
|
|
@@ -872,7 +911,7 @@ public class PackWriter { |
|
|
|
cnt += objectsLists[Constants.OBJ_TAG].size(); |
|
|
|
|
|
|
|
long start = System.currentTimeMillis(); |
|
|
|
monitor.beginTask(JGitText.get().searchForReuse, cnt); |
|
|
|
beginPhase(PackingPhase.FINDING_SOURCES, monitor, cnt); |
|
|
|
|
|
|
|
if (cnt <= 4096) { |
|
|
|
// For small object counts, do everything as one list. |
|
|
@@ -897,7 +936,7 @@ public class PackWriter { |
|
|
|
searchForReuse(monitor, objectsLists[Constants.OBJ_TAG]); |
|
|
|
} |
|
|
|
|
|
|
|
monitor.endTask(); |
|
|
|
endPhase(monitor); |
|
|
|
stats.timeSearchingForReuse = System.currentTimeMillis() - start; |
|
|
|
} |
|
|
|
|
|
|
@@ -944,7 +983,7 @@ public class PackWriter { |
|
|
|
// abort with an exception if we actually had to have it. |
|
|
|
// |
|
|
|
final long sizingStart = System.currentTimeMillis(); |
|
|
|
monitor.beginTask(JGitText.get().searchForSizes, cnt); |
|
|
|
beginPhase(PackingPhase.GETTING_SIZES, monitor, cnt); |
|
|
|
AsyncObjectSizeQueue<ObjectToPack> sizeQueue = reader.getObjectSize( |
|
|
|
Arrays.<ObjectToPack> asList(list).subList(0, cnt), false); |
|
|
|
try { |
|
|
@@ -989,7 +1028,7 @@ public class PackWriter { |
|
|
|
} finally { |
|
|
|
sizeQueue.release(); |
|
|
|
} |
|
|
|
monitor.endTask(); |
|
|
|
endPhase(monitor); |
|
|
|
stats.timeSearchingForSizes = System.currentTimeMillis() - sizingStart; |
|
|
|
|
|
|
|
// Sort the objects by path hash so like files are near each other, |
|
|
@@ -1035,9 +1074,9 @@ public class PackWriter { |
|
|
|
return; |
|
|
|
|
|
|
|
final long searchStart = System.currentTimeMillis(); |
|
|
|
monitor.beginTask(JGitText.get().compressingObjects, nonEdgeCnt); |
|
|
|
beginPhase(PackingPhase.COMPRESSING, monitor, nonEdgeCnt); |
|
|
|
searchForDeltas(monitor, list, cnt); |
|
|
|
monitor.endTask(); |
|
|
|
endPhase(monitor); |
|
|
|
stats.deltaSearchNonEdgeObjects = nonEdgeCnt; |
|
|
|
stats.timeCompressing = System.currentTimeMillis() - searchStart; |
|
|
|
|
|
|
@@ -1400,8 +1439,7 @@ public class PackWriter { |
|
|
|
throws MissingObjectException, IOException, |
|
|
|
IncorrectObjectTypeException { |
|
|
|
final long countingStart = System.currentTimeMillis(); |
|
|
|
countingMonitor.beginTask(JGitText.get().countingObjects, |
|
|
|
ProgressMonitor.UNKNOWN); |
|
|
|
beginPhase(PackingPhase.COUNTING, countingMonitor, ProgressMonitor.UNKNOWN); |
|
|
|
|
|
|
|
if (have == null) |
|
|
|
have = Collections.emptySet(); |
|
|
@@ -1447,7 +1485,7 @@ public class PackWriter { |
|
|
|
cachedPacks.addAll(shortCircuit); |
|
|
|
for (CachedPack pack : shortCircuit) |
|
|
|
countingMonitor.update((int) pack.getObjectCount()); |
|
|
|
countingMonitor.endTask(); |
|
|
|
endPhase(countingMonitor); |
|
|
|
stats.timeCounting = System.currentTimeMillis() - countingStart; |
|
|
|
return; |
|
|
|
} |
|
|
@@ -1537,8 +1575,8 @@ public class PackWriter { |
|
|
|
wantObjs, haveObjs, pack); |
|
|
|
commits = new BlockList<RevCommit>(); |
|
|
|
|
|
|
|
countingMonitor.endTask(); |
|
|
|
countingMonitor.beginTask(JGitText.get().countingObjects, |
|
|
|
endPhase(countingMonitor); |
|
|
|
beginPhase(PackingPhase.COUNTING, countingMonitor, |
|
|
|
ProgressMonitor.UNKNOWN); |
|
|
|
continue; |
|
|
|
} |
|
|
@@ -1625,7 +1663,7 @@ public class PackWriter { |
|
|
|
|
|
|
|
for (CachedPack pack : cachedPacks) |
|
|
|
countingMonitor.update((int) pack.getObjectCount()); |
|
|
|
countingMonitor.endTask(); |
|
|
|
endPhase(countingMonitor); |
|
|
|
stats.timeCounting = System.currentTimeMillis() - countingStart; |
|
|
|
} |
|
|
|
|
|
|
@@ -2099,4 +2137,58 @@ public class PackWriter { |
|
|
|
reusedObjects, reusedDeltas); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private class MutableState { |
|
|
|
private volatile PackingPhase phase; |
|
|
|
|
|
|
|
MutableState() { |
|
|
|
phase = PackingPhase.COUNTING; |
|
|
|
} |
|
|
|
|
|
|
|
State snapshot() { |
|
|
|
return new State(phase); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** Possible states that a PackWriter can be in. */ |
|
|
|
public static enum PackingPhase { |
|
|
|
/** Counting objects phase. */ |
|
|
|
COUNTING, |
|
|
|
|
|
|
|
/** Getting sizes phase. */ |
|
|
|
GETTING_SIZES, |
|
|
|
|
|
|
|
/** Finding sources phase. */ |
|
|
|
FINDING_SOURCES, |
|
|
|
|
|
|
|
/** Compressing objects phase. */ |
|
|
|
COMPRESSING, |
|
|
|
|
|
|
|
/** Writing objects phase. */ |
|
|
|
WRITING; |
|
|
|
} |
|
|
|
|
|
|
|
/** Summary of the current state of a PackWriter. */ |
|
|
|
public class State { |
|
|
|
private final PackingPhase phase; |
|
|
|
|
|
|
|
State(PackingPhase phase) { |
|
|
|
this.phase = phase; |
|
|
|
} |
|
|
|
|
|
|
|
/** @return the PackConfig used to build the writer. */ |
|
|
|
public PackConfig getConfig() { |
|
|
|
return config; |
|
|
|
} |
|
|
|
|
|
|
|
/** @return the current phase of the writer. */ |
|
|
|
public PackingPhase getPhase() { |
|
|
|
return phase; |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public String toString() { |
|
|
|
return "PackWriter.State[" + phase + "]"; |
|
|
|
} |
|
|
|
} |
|
|
|
} |