@ -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 class PackWriter {
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 @@ public class PackWriter {
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 class PackWriter {
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 class PackWriter {
}
}
reader . release ( ) ;
reader . release ( ) ;
writeMonitor . endTask ( ) ;
endPhase ( writeMonitor ) ;
}
}
/ * *
/ * *
@ -855,6 +889,11 @@ public class PackWriter {
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 @@ public class PackWriter {
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 @@ public class PackWriter {
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 @@ public class PackWriter {
// 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 @@ public class PackWriter {
} 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 class PackWriter {
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 @@ public class PackWriter {
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 @@ public class PackWriter {
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 @@ public class PackWriter {
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 @@ public class PackWriter {
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 class PackWriter {
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 + "]" ;
}
}
}
}