Merge branch 'master' into stable-4.3
* master: Add config parameter gc.prunePackExpire for packfile expiration In TestRepository, use a consistent clock Change-Id: I7ac568e650fbd191e48a8f1a4068af72deb242e8 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
This commit is contained in:
commit
f56b9001fc
|
@ -112,23 +112,18 @@
|
||||||
* type of Repository the test data is stored on.
|
* type of Repository the test data is stored on.
|
||||||
*/
|
*/
|
||||||
public class TestRepository<R extends Repository> {
|
public class TestRepository<R extends Repository> {
|
||||||
private static final PersonIdent defaultAuthor;
|
|
||||||
|
|
||||||
private static final PersonIdent defaultCommitter;
|
public static final String AUTHOR = "J. Author";
|
||||||
|
|
||||||
static {
|
public static final String AUTHOR_EMAIL = "jauthor@example.com";
|
||||||
final MockSystemReader m = new MockSystemReader();
|
|
||||||
final long now = m.getCurrentTime();
|
|
||||||
final int tz = m.getTimezone(now);
|
|
||||||
|
|
||||||
final String an = "J. Author";
|
public static final String COMMITTER = "J. Committer";
|
||||||
final String ae = "jauthor@example.com";
|
|
||||||
defaultAuthor = new PersonIdent(an, ae, now, tz);
|
|
||||||
|
|
||||||
final String cn = "J. Committer";
|
public static final String COMMITTER_EMAIL = "jcommitter@example.com";
|
||||||
final String ce = "jcommitter@example.com";
|
|
||||||
defaultCommitter = new PersonIdent(cn, ce, now, tz);
|
private final PersonIdent defaultAuthor;
|
||||||
}
|
|
||||||
|
private final PersonIdent defaultCommitter;
|
||||||
|
|
||||||
private final R db;
|
private final R db;
|
||||||
|
|
||||||
|
@ -184,6 +179,10 @@ public TestRepository(R db, RevWalk rw, MockSystemReader reader)
|
||||||
this.pool = rw;
|
this.pool = rw;
|
||||||
this.inserter = db.newObjectInserter();
|
this.inserter = db.newObjectInserter();
|
||||||
this.mockSystemReader = reader;
|
this.mockSystemReader = reader;
|
||||||
|
long now = mockSystemReader.getCurrentTime();
|
||||||
|
int tz = mockSystemReader.getTimezone(now);
|
||||||
|
defaultAuthor = new PersonIdent(AUTHOR, AUTHOR_EMAIL, now, tz);
|
||||||
|
defaultCommitter = new PersonIdent(COMMITTER, COMMITTER_EMAIL, now, tz);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return the repository this helper class operates against. */
|
/** @return the repository this helper class operates against. */
|
||||||
|
|
|
@ -213,9 +213,20 @@ public void testDonePruneTooYoungPacks() throws Exception {
|
||||||
assertEquals(9, stats.numberOfPackedObjects);
|
assertEquals(9, stats.numberOfPackedObjects);
|
||||||
assertEquals(2, stats.numberOfPackFiles);
|
assertEquals(2, stats.numberOfPackFiles);
|
||||||
|
|
||||||
|
// repack again but now without a grace period for loose objects. Since
|
||||||
|
// we don't have loose objects anymore this shouldn't change anything
|
||||||
|
gc.setExpireAgeMillis(0);
|
||||||
|
gc.gc();
|
||||||
|
stats = gc.getStatistics();
|
||||||
|
assertEquals(0, stats.numberOfLooseObjects);
|
||||||
|
// if objects exist in multiple packFiles then they are counted multiple
|
||||||
|
// times
|
||||||
|
assertEquals(9, stats.numberOfPackedObjects);
|
||||||
|
assertEquals(2, stats.numberOfPackFiles);
|
||||||
|
|
||||||
// repack again but now without a grace period for packfiles. We should
|
// repack again but now without a grace period for packfiles. We should
|
||||||
// end up with one packfile
|
// end up with one packfile
|
||||||
gc.setExpireAgeMillis(0);
|
gc.setPackExpireAgeMillis(0);
|
||||||
gc.gc();
|
gc.gc();
|
||||||
stats = gc.getStatistics();
|
stats = gc.getStatistics();
|
||||||
assertEquals(0, stats.numberOfLooseObjects);
|
assertEquals(0, stats.numberOfLooseObjects);
|
||||||
|
|
|
@ -95,7 +95,8 @@ public void testBitmapSpansNoMerges() throws Exception {
|
||||||
}
|
}
|
||||||
currentCommits = nextCommitCount;
|
currentCommits = nextCommitCount;
|
||||||
|
|
||||||
gc.setExpireAgeMillis(0); // immediately delete old packs
|
gc.setPackExpireAgeMillis(0); // immediately delete old packs
|
||||||
|
gc.setExpireAgeMillis(0);
|
||||||
gc.gc();
|
gc.gc();
|
||||||
assertEquals(currentCommits * 3, // commit/tree/object
|
assertEquals(currentCommits * 3, // commit/tree/object
|
||||||
gc.getStatistics().numberOfPackedObjects);
|
gc.getStatistics().numberOfPackedObjects);
|
||||||
|
@ -158,7 +159,8 @@ public void testBitmapSpansWithMerges() throws Exception {
|
||||||
}
|
}
|
||||||
currentCommits = nextCommitCount;
|
currentCommits = nextCommitCount;
|
||||||
|
|
||||||
gc.setExpireAgeMillis(0); // immediately delete old packs
|
gc.setPackExpireAgeMillis(0); // immediately delete old packs
|
||||||
|
gc.setExpireAgeMillis(0);
|
||||||
gc.gc();
|
gc.gc();
|
||||||
assertEquals(currentCommits + " commits: ", expectedBitmapCount,
|
assertEquals(currentCommits + " commits: ", expectedBitmapCount,
|
||||||
gc.getStatistics().numberOfBitmaps);
|
gc.getStatistics().numberOfBitmaps);
|
||||||
|
@ -198,7 +200,8 @@ public void testBitmapsForExcessiveBranches() throws Exception {
|
||||||
final int commitsForShallowBranches = 100;
|
final int commitsForShallowBranches = 100;
|
||||||
|
|
||||||
// Excessive branch history pruning, one old branch.
|
// Excessive branch history pruning, one old branch.
|
||||||
gc.setExpireAgeMillis(0); // immediately delete old packs
|
gc.setPackExpireAgeMillis(0); // immediately delete old packs
|
||||||
|
gc.setExpireAgeMillis(0);
|
||||||
gc.gc();
|
gc.gc();
|
||||||
assertEquals(
|
assertEquals(
|
||||||
commitsForSparseBranch + commitsForFullBranch
|
commitsForSparseBranch + commitsForFullBranch
|
||||||
|
|
|
@ -111,6 +111,8 @@
|
||||||
public class GC {
|
public class GC {
|
||||||
private static final String PRUNE_EXPIRE_DEFAULT = "2.weeks.ago"; //$NON-NLS-1$
|
private static final String PRUNE_EXPIRE_DEFAULT = "2.weeks.ago"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
private static final String PRUNE_PACK_EXPIRE_DEFAULT = "1.hour.ago"; //$NON-NLS-1$
|
||||||
|
|
||||||
private final FileRepository repo;
|
private final FileRepository repo;
|
||||||
|
|
||||||
private ProgressMonitor pm;
|
private ProgressMonitor pm;
|
||||||
|
@ -119,6 +121,10 @@ public class GC {
|
||||||
|
|
||||||
private Date expire;
|
private Date expire;
|
||||||
|
|
||||||
|
private long packExpireAgeMillis = -1;
|
||||||
|
|
||||||
|
private Date packExpire;
|
||||||
|
|
||||||
private PackConfig pconfig = null;
|
private PackConfig pconfig = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -186,7 +192,7 @@ public Collection<PackFile> gc() throws IOException, ParseException {
|
||||||
*/
|
*/
|
||||||
private void deleteOldPacks(Collection<PackFile> oldPacks,
|
private void deleteOldPacks(Collection<PackFile> oldPacks,
|
||||||
Collection<PackFile> newPacks) throws ParseException {
|
Collection<PackFile> newPacks) throws ParseException {
|
||||||
long expireDate = getExpireDate();
|
long packExpireDate = getPackExpireDate();
|
||||||
oldPackLoop: for (PackFile oldPack : oldPacks) {
|
oldPackLoop: for (PackFile oldPack : oldPacks) {
|
||||||
String oldName = oldPack.getPackName();
|
String oldName = oldPack.getPackName();
|
||||||
// check whether an old pack file is also among the list of new
|
// check whether an old pack file is also among the list of new
|
||||||
|
@ -196,7 +202,7 @@ private void deleteOldPacks(Collection<PackFile> oldPacks,
|
||||||
continue oldPackLoop;
|
continue oldPackLoop;
|
||||||
|
|
||||||
if (!oldPack.shouldBeKept()
|
if (!oldPack.shouldBeKept()
|
||||||
&& oldPack.getPackFile().lastModified() < expireDate) {
|
&& oldPack.getPackFile().lastModified() < packExpireDate) {
|
||||||
oldPack.close();
|
oldPack.close();
|
||||||
prunePack(oldName);
|
prunePack(oldName);
|
||||||
}
|
}
|
||||||
|
@ -449,6 +455,26 @@ private long getExpireDate() throws ParseException {
|
||||||
return expireDate;
|
return expireDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private long getPackExpireDate() throws ParseException {
|
||||||
|
long packExpireDate = Long.MAX_VALUE;
|
||||||
|
|
||||||
|
if (packExpire == null && packExpireAgeMillis == -1) {
|
||||||
|
String prunePackExpireStr = repo.getConfig().getString(
|
||||||
|
ConfigConstants.CONFIG_GC_SECTION, null,
|
||||||
|
ConfigConstants.CONFIG_KEY_PRUNEPACKEXPIRE);
|
||||||
|
if (prunePackExpireStr == null)
|
||||||
|
prunePackExpireStr = PRUNE_PACK_EXPIRE_DEFAULT;
|
||||||
|
packExpire = GitDateParser.parse(prunePackExpireStr, null,
|
||||||
|
SystemReader.getInstance().getLocale());
|
||||||
|
packExpireAgeMillis = -1;
|
||||||
|
}
|
||||||
|
if (packExpire != null)
|
||||||
|
packExpireDate = packExpire.getTime();
|
||||||
|
if (packExpireAgeMillis != -1)
|
||||||
|
packExpireDate = System.currentTimeMillis() - packExpireAgeMillis;
|
||||||
|
return packExpireDate;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove all entries from a map which key is the id of an object referenced
|
* Remove all entries from a map which key is the id of an object referenced
|
||||||
* by the given ObjectWalk
|
* by the given ObjectWalk
|
||||||
|
@ -982,6 +1008,20 @@ public void setExpireAgeMillis(long expireAgeMillis) {
|
||||||
expire = null;
|
expire = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* During gc() or prune() packfiles which are created or modified in the
|
||||||
|
* last <code>packExpireAgeMillis</code> milliseconds will not be deleted.
|
||||||
|
* Only older packfiles may be deleted. If set to 0 then every packfile is a
|
||||||
|
* candidate for deletion.
|
||||||
|
*
|
||||||
|
* @param packExpireAgeMillis
|
||||||
|
* minimal age of packfiles to be deleted in milliseconds.
|
||||||
|
*/
|
||||||
|
public void setPackExpireAgeMillis(long packExpireAgeMillis) {
|
||||||
|
this.packExpireAgeMillis = packExpireAgeMillis;
|
||||||
|
expire = null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the PackConfig used when (re-)writing packfiles. This allows to
|
* Set the PackConfig used when (re-)writing packfiles. This allows to
|
||||||
* influence how packs are written and to implement something similar to
|
* influence how packs are written and to implement something similar to
|
||||||
|
@ -1011,4 +1051,18 @@ public void setExpire(Date expire) {
|
||||||
this.expire = expire;
|
this.expire = expire;
|
||||||
expireAgeMillis = -1;
|
expireAgeMillis = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* During gc() or prune() packfiles which are created or modified after or
|
||||||
|
* at <code>packExpire</code> will not be deleted. Only older packfiles may
|
||||||
|
* be deleted. If set to null then every packfile is a candidate for
|
||||||
|
* deletion.
|
||||||
|
*
|
||||||
|
* @param packExpire
|
||||||
|
* instant in time which defines packfile expiration
|
||||||
|
*/
|
||||||
|
public void setPackExpire(Date packExpire) {
|
||||||
|
this.packExpire = packExpire;
|
||||||
|
packExpireAgeMillis = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,6 +247,12 @@ public class ConfigConstants {
|
||||||
/** The "pruneexpire" key */
|
/** The "pruneexpire" key */
|
||||||
public static final String CONFIG_KEY_PRUNEEXPIRE = "pruneexpire";
|
public static final String CONFIG_KEY_PRUNEEXPIRE = "pruneexpire";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The "prunepackexpire" key
|
||||||
|
* @since 4.3
|
||||||
|
*/
|
||||||
|
public static final String CONFIG_KEY_PRUNEPACKEXPIRE = "prunepackexpire";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The "aggressiveDepth" key
|
* The "aggressiveDepth" key
|
||||||
* @since 3.6
|
* @since 3.6
|
||||||
|
|
Loading…
Reference in New Issue