Add an object encapsulating the state of a PackWriter
Exposes essentially the same state machine to the programmer as is exposed to the client via a ProgressMonitor, using a wrapper around beginTask()/endTask(). Change-Id: Ic3622b4acea65d2b9b3551c668806981fa7293e3
This commit is contained in:
parent
e7ec5e1473
commit
16b8ebf2d1
|
@ -215,6 +215,7 @@ hunkDisconnectedFromFile=Hunk disconnected from file
|
||||||
hunkHeaderDoesNotMatchBodyLineCountOf=Hunk header {0} does not match body line count of {1}
|
hunkHeaderDoesNotMatchBodyLineCountOf=Hunk header {0} does not match body line count of {1}
|
||||||
illegalArgumentNotA=Not {0}
|
illegalArgumentNotA=Not {0}
|
||||||
illegalCombinationOfArguments=The combination of arguments {0} and {1} is not allowed
|
illegalCombinationOfArguments=The combination of arguments {0} and {1} is not allowed
|
||||||
|
illegalPackingPhase=Illegal packing phase {0}
|
||||||
illegalStateExists=exists {0}
|
illegalStateExists=exists {0}
|
||||||
improperlyPaddedBase64Input=Improperly padded Base64 input.
|
improperlyPaddedBase64Input=Improperly padded Base64 input.
|
||||||
inMemoryBufferLimitExceeded=In-memory buffer limit exceeded
|
inMemoryBufferLimitExceeded=In-memory buffer limit exceeded
|
||||||
|
|
|
@ -275,6 +275,7 @@ public static JGitText get() {
|
||||||
/***/ public String hunkHeaderDoesNotMatchBodyLineCountOf;
|
/***/ public String hunkHeaderDoesNotMatchBodyLineCountOf;
|
||||||
/***/ public String illegalArgumentNotA;
|
/***/ public String illegalArgumentNotA;
|
||||||
/***/ public String illegalCombinationOfArguments;
|
/***/ public String illegalCombinationOfArguments;
|
||||||
|
/***/ public String illegalPackingPhase;
|
||||||
/***/ public String illegalStateExists;
|
/***/ public String illegalStateExists;
|
||||||
/***/ public String improperlyPaddedBase64Input;
|
/***/ public String improperlyPaddedBase64Input;
|
||||||
/***/ public String inMemoryBufferLimitExceeded;
|
/***/ public String inMemoryBufferLimitExceeded;
|
||||||
|
|
|
@ -174,6 +174,8 @@ public class PackWriter {
|
||||||
|
|
||||||
private final Statistics stats;
|
private final Statistics stats;
|
||||||
|
|
||||||
|
private final MutableState state;
|
||||||
|
|
||||||
private Statistics.ObjectType typeStats;
|
private Statistics.ObjectType typeStats;
|
||||||
|
|
||||||
private List<ObjectToPack> sortedByName;
|
private List<ObjectToPack> sortedByName;
|
||||||
|
@ -266,6 +268,7 @@ public PackWriter(final PackConfig config, final ObjectReader reader) {
|
||||||
reuseDeltas = config.isReuseDeltas();
|
reuseDeltas = config.isReuseDeltas();
|
||||||
reuseValidate = true; // be paranoid by default
|
reuseValidate = true; // be paranoid by default
|
||||||
stats = new Statistics();
|
stats = new Statistics();
|
||||||
|
state = new MutableState();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -744,6 +747,37 @@ private List<ObjectToPack> sortByName() {
|
||||||
return sortedByName;
|
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.
|
* Write the prepared pack to the supplied stream.
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -803,7 +837,7 @@ public void writePack(ProgressMonitor compressMonitor,
|
||||||
|
|
||||||
long objCnt = getObjectCount();
|
long objCnt = getObjectCount();
|
||||||
stats.totalObjects = objCnt;
|
stats.totalObjects = objCnt;
|
||||||
writeMonitor.beginTask(JGitText.get().writingObjects, (int) objCnt);
|
beginPhase(PackingPhase.WRITING, writeMonitor, (int) objCnt);
|
||||||
long writeStart = System.currentTimeMillis();
|
long writeStart = System.currentTimeMillis();
|
||||||
|
|
||||||
out.writeFileHeader(PACK_VERSION_GENERATED, objCnt);
|
out.writeFileHeader(PACK_VERSION_GENERATED, objCnt);
|
||||||
|
@ -843,7 +877,7 @@ public void writePack(ProgressMonitor compressMonitor,
|
||||||
}
|
}
|
||||||
|
|
||||||
reader.release();
|
reader.release();
|
||||||
writeMonitor.endTask();
|
endPhase(writeMonitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -855,6 +889,11 @@ public Statistics getStatistics() {
|
||||||
return stats;
|
return stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return snapshot of the current state of this PackWriter. */
|
||||||
|
public State getState() {
|
||||||
|
return state.snapshot();
|
||||||
|
}
|
||||||
|
|
||||||
/** Release all resources used by this writer. */
|
/** Release all resources used by this writer. */
|
||||||
public void release() {
|
public void release() {
|
||||||
reader.release();
|
reader.release();
|
||||||
|
@ -872,7 +911,7 @@ private void searchForReuse(ProgressMonitor monitor) throws IOException {
|
||||||
cnt += objectsLists[Constants.OBJ_TAG].size();
|
cnt += objectsLists[Constants.OBJ_TAG].size();
|
||||||
|
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
monitor.beginTask(JGitText.get().searchForReuse, cnt);
|
beginPhase(PackingPhase.FINDING_SOURCES, monitor, cnt);
|
||||||
|
|
||||||
if (cnt <= 4096) {
|
if (cnt <= 4096) {
|
||||||
// For small object counts, do everything as one list.
|
// For small object counts, do everything as one list.
|
||||||
|
@ -897,7 +936,7 @@ private void searchForReuse(ProgressMonitor monitor) throws IOException {
|
||||||
searchForReuse(monitor, objectsLists[Constants.OBJ_TAG]);
|
searchForReuse(monitor, objectsLists[Constants.OBJ_TAG]);
|
||||||
}
|
}
|
||||||
|
|
||||||
monitor.endTask();
|
endPhase(monitor);
|
||||||
stats.timeSearchingForReuse = System.currentTimeMillis() - start;
|
stats.timeSearchingForReuse = System.currentTimeMillis() - start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -944,7 +983,7 @@ private void searchForDeltas(ProgressMonitor monitor)
|
||||||
// abort with an exception if we actually had to have it.
|
// abort with an exception if we actually had to have it.
|
||||||
//
|
//
|
||||||
final long sizingStart = System.currentTimeMillis();
|
final long sizingStart = System.currentTimeMillis();
|
||||||
monitor.beginTask(JGitText.get().searchForSizes, cnt);
|
beginPhase(PackingPhase.GETTING_SIZES, monitor, cnt);
|
||||||
AsyncObjectSizeQueue<ObjectToPack> sizeQueue = reader.getObjectSize(
|
AsyncObjectSizeQueue<ObjectToPack> sizeQueue = reader.getObjectSize(
|
||||||
Arrays.<ObjectToPack> asList(list).subList(0, cnt), false);
|
Arrays.<ObjectToPack> asList(list).subList(0, cnt), false);
|
||||||
try {
|
try {
|
||||||
|
@ -989,7 +1028,7 @@ else if (sz <= DeltaIndex.BLKSZ)
|
||||||
} finally {
|
} finally {
|
||||||
sizeQueue.release();
|
sizeQueue.release();
|
||||||
}
|
}
|
||||||
monitor.endTask();
|
endPhase(monitor);
|
||||||
stats.timeSearchingForSizes = System.currentTimeMillis() - sizingStart;
|
stats.timeSearchingForSizes = System.currentTimeMillis() - sizingStart;
|
||||||
|
|
||||||
// Sort the objects by path hash so like files are near each other,
|
// Sort the objects by path hash so like files are near each other,
|
||||||
|
@ -1035,9 +1074,9 @@ public int compare(ObjectToPack a, ObjectToPack b) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
final long searchStart = System.currentTimeMillis();
|
final long searchStart = System.currentTimeMillis();
|
||||||
monitor.beginTask(JGitText.get().compressingObjects, nonEdgeCnt);
|
beginPhase(PackingPhase.COMPRESSING, monitor, nonEdgeCnt);
|
||||||
searchForDeltas(monitor, list, cnt);
|
searchForDeltas(monitor, list, cnt);
|
||||||
monitor.endTask();
|
endPhase(monitor);
|
||||||
stats.deltaSearchNonEdgeObjects = nonEdgeCnt;
|
stats.deltaSearchNonEdgeObjects = nonEdgeCnt;
|
||||||
stats.timeCompressing = System.currentTimeMillis() - searchStart;
|
stats.timeCompressing = System.currentTimeMillis() - searchStart;
|
||||||
|
|
||||||
|
@ -1400,8 +1439,7 @@ private void findObjectsToPack(final ProgressMonitor countingMonitor,
|
||||||
throws MissingObjectException, IOException,
|
throws MissingObjectException, IOException,
|
||||||
IncorrectObjectTypeException {
|
IncorrectObjectTypeException {
|
||||||
final long countingStart = System.currentTimeMillis();
|
final long countingStart = System.currentTimeMillis();
|
||||||
countingMonitor.beginTask(JGitText.get().countingObjects,
|
beginPhase(PackingPhase.COUNTING, countingMonitor, ProgressMonitor.UNKNOWN);
|
||||||
ProgressMonitor.UNKNOWN);
|
|
||||||
|
|
||||||
if (have == null)
|
if (have == null)
|
||||||
have = Collections.emptySet();
|
have = Collections.emptySet();
|
||||||
|
@ -1447,7 +1485,7 @@ private void findObjectsToPack(final ProgressMonitor countingMonitor,
|
||||||
cachedPacks.addAll(shortCircuit);
|
cachedPacks.addAll(shortCircuit);
|
||||||
for (CachedPack pack : shortCircuit)
|
for (CachedPack pack : shortCircuit)
|
||||||
countingMonitor.update((int) pack.getObjectCount());
|
countingMonitor.update((int) pack.getObjectCount());
|
||||||
countingMonitor.endTask();
|
endPhase(countingMonitor);
|
||||||
stats.timeCounting = System.currentTimeMillis() - countingStart;
|
stats.timeCounting = System.currentTimeMillis() - countingStart;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1537,8 +1575,8 @@ private void findObjectsToPack(final ProgressMonitor countingMonitor,
|
||||||
wantObjs, haveObjs, pack);
|
wantObjs, haveObjs, pack);
|
||||||
commits = new BlockList<RevCommit>();
|
commits = new BlockList<RevCommit>();
|
||||||
|
|
||||||
countingMonitor.endTask();
|
endPhase(countingMonitor);
|
||||||
countingMonitor.beginTask(JGitText.get().countingObjects,
|
beginPhase(PackingPhase.COUNTING, countingMonitor,
|
||||||
ProgressMonitor.UNKNOWN);
|
ProgressMonitor.UNKNOWN);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1625,7 +1663,7 @@ private void findObjectsToPack(final ProgressMonitor countingMonitor,
|
||||||
|
|
||||||
for (CachedPack pack : cachedPacks)
|
for (CachedPack pack : cachedPacks)
|
||||||
countingMonitor.update((int) pack.getObjectCount());
|
countingMonitor.update((int) pack.getObjectCount());
|
||||||
countingMonitor.endTask();
|
endPhase(countingMonitor);
|
||||||
stats.timeCounting = System.currentTimeMillis() - countingStart;
|
stats.timeCounting = System.currentTimeMillis() - countingStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2099,4 +2137,58 @@ public String getMessage() {
|
||||||
reusedObjects, reusedDeltas);
|
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 + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue