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}
|
||||
illegalArgumentNotA=Not {0}
|
||||
illegalCombinationOfArguments=The combination of arguments {0} and {1} is not allowed
|
||||
illegalPackingPhase=Illegal packing phase {0}
|
||||
illegalStateExists=exists {0}
|
||||
improperlyPaddedBase64Input=Improperly padded Base64 input.
|
||||
inMemoryBufferLimitExceeded=In-memory buffer limit exceeded
|
||||
|
|
|
@ -275,6 +275,7 @@ public static JGitText get() {
|
|||
/***/ public String hunkHeaderDoesNotMatchBodyLineCountOf;
|
||||
/***/ public String illegalArgumentNotA;
|
||||
/***/ public String illegalCombinationOfArguments;
|
||||
/***/ public String illegalPackingPhase;
|
||||
/***/ public String illegalStateExists;
|
||||
/***/ public String improperlyPaddedBase64Input;
|
||||
/***/ public String inMemoryBufferLimitExceeded;
|
||||
|
|
|
@ -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 PackWriter(final PackConfig config, final ObjectReader reader) {
|
|||
reuseDeltas = config.isReuseDeltas();
|
||||
reuseValidate = true; // be paranoid by default
|
||||
stats = new Statistics();
|
||||
state = new MutableState();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -744,6 +747,37 @@ private List<ObjectToPack> sortByName() {
|
|||
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 void writePack(ProgressMonitor compressMonitor,
|
|||
|
||||
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 void writePack(ProgressMonitor compressMonitor,
|
|||
}
|
||||
|
||||
reader.release();
|
||||
writeMonitor.endTask();
|
||||
endPhase(writeMonitor);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -855,6 +889,11 @@ public Statistics getStatistics() {
|
|||
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 @@ private void searchForReuse(ProgressMonitor monitor) throws IOException {
|
|||
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 @@ private void searchForReuse(ProgressMonitor monitor) throws IOException {
|
|||
searchForReuse(monitor, objectsLists[Constants.OBJ_TAG]);
|
||||
}
|
||||
|
||||
monitor.endTask();
|
||||
endPhase(monitor);
|
||||
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.
|
||||
//
|
||||
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 @@ else if (sz <= DeltaIndex.BLKSZ)
|
|||
} 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 int compare(ObjectToPack a, ObjectToPack b) {
|
|||
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 @@ private void findObjectsToPack(final ProgressMonitor countingMonitor,
|
|||
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 @@ private void findObjectsToPack(final ProgressMonitor countingMonitor,
|
|||
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 @@ private void findObjectsToPack(final ProgressMonitor countingMonitor,
|
|||
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 @@ private void findObjectsToPack(final ProgressMonitor countingMonitor,
|
|||
|
||||
for (CachedPack pack : cachedPacks)
|
||||
countingMonitor.update((int) pack.getObjectCount());
|
||||
countingMonitor.endTask();
|
||||
endPhase(countingMonitor);
|
||||
stats.timeCounting = System.currentTimeMillis() - countingStart;
|
||||
}
|
||||
|
||||
|
@ -2099,4 +2137,58 @@ public String getMessage() {
|
|||
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