public class GC
extends java.lang.Object
FileRepository
. Instances of
this class are not thread-safe. Don't use the same instance from multiple
threads.
This class started as a copy of DfsGarbageCollector from Shawn O. Pearce
adapted to FileRepositories.Modifier and Type | Class and Description |
---|---|
static class |
GC.RepoStatistics
A class holding statistical data for a FileRepository regarding how many
objects are stored as loose or packed objects
|
Modifier and Type | Field and Description |
---|---|
private boolean |
automatic
Whether gc should do automatic housekeeping
|
private boolean |
background
Whether to run gc in a background thread
|
private static java.lang.String |
BITMAP_EXT |
private static int |
DEFAULT_AUTOLIMIT |
private static int |
DEFAULT_AUTOPACKLIMIT |
private static java.util.concurrent.ExecutorService |
executor |
private java.util.Date |
expire |
private long |
expireAgeMillis |
private static java.lang.String |
INDEX_EXT |
private java.util.Collection<Ref> |
lastPackedRefs
the refs which existed during the last call to
repack() . |
private long |
lastRepackTime
Holds the starting time of the last repack() execution.
|
private static org.slf4j.Logger |
LOG |
private static java.lang.String |
PACK_EXT |
private java.util.Date |
packExpire |
private long |
packExpireAgeMillis |
private static java.util.regex.Pattern |
PATTERN_LOOSE_OBJECT |
private PackConfig |
pconfig |
private ProgressMonitor |
pm |
private static java.lang.String |
PRUNE_EXPIRE_DEFAULT |
private static java.lang.String |
PRUNE_PACK_EXPIRE_DEFAULT |
private FileRepository |
repo |
Constructor and Description |
---|
GC(FileRepository repo)
Creates a new garbage collector with default values.
|
Modifier and Type | Method and Description |
---|---|
private void |
addRepackAllOption() |
private boolean |
canBeSafelyDeleted(java.nio.file.Path path,
java.time.Instant threshold) |
private void |
checkCancelled() |
private void |
delete(java.nio.file.Path d) |
private void |
deleteDir(java.nio.file.Path dir) |
private void |
deleteEmptyRefsFolders() |
private void |
deleteOldPacks(java.util.Collection<PackFile> oldPacks,
java.util.Collection<PackFile> newPacks)
Delete old pack files.
|
private void |
deleteOrphans()
Deletes orphans
|
private void |
deleteTempPacksIdx() |
private java.util.Collection<PackFile> |
doGc() |
private static boolean |
equals(Ref r1,
Ref r2) |
private java.util.concurrent.ExecutorService |
executor() |
java.util.Collection<PackFile> |
gc()
Runs a garbage collector on a
FileRepository . |
private java.util.Collection<Ref> |
getAllRefs()
Returns a collection of all refs and additional refs.
|
private long |
getExpireDate() |
private int |
getLooseObjectLimit() |
private long |
getPackExpireDate() |
private java.lang.String |
getPruneExpireStr() |
GC.RepoStatistics |
getStatistics()
Returns information about objects and pack files for a FileRepository.
|
private boolean |
isDirectory(java.nio.file.Path p) |
private static boolean |
isHead(Ref ref) |
private static boolean |
isTag(Ref ref) |
private java.util.Set<ObjectId> |
listNonHEADIndexObjects()
Return a list of those objects in the index which differ from whats in
HEAD
|
private java.util.Set<ObjectId> |
listRefLogObjects(Ref ref,
long minTime) |
private void |
loosen(ObjectDirectoryInserter inserter,
ObjectReader reader,
PackFile pack,
java.util.HashSet<ObjectId> existing)
Loosen objects in a pack file which are not also in the newly-created
pack files.
|
private java.io.File |
nameFor(java.lang.String name,
java.lang.String ext) |
private boolean |
needGc() |
void |
packRefs()
Pack ref storage.
|
void |
prune(java.util.Set<ObjectId> objectsToKeep)
Like "git prune" this method tries to prune all loose objects which are
unreferenced.
|
private void |
prunePack(java.lang.String packName)
Delete files associated with a single pack file.
|
void |
prunePacked()
Like "git prune-packed" this method tries to prune all loose objects
which can be found in packs.
|
private void |
prunePreserved()
Delete the preserved directory including all pack files within
|
private void |
removeOldPack(java.io.File packFile,
java.lang.String packName,
PackExt ext,
int deleteOptions)
Deletes old pack file, unless 'preserve-oldpacks' is set, in which case it
moves the pack file to the preserved directory
|
private void |
removeReferenced(java.util.Map<ObjectId,java.io.File> id2File,
ObjectWalk w)
Remove all entries from a map which key is the id of an object referenced
by the given ObjectWalk
|
java.util.Collection<PackFile> |
repack()
Packs all objects which reachable from any of the heads into one pack
file.
|
void |
setAuto(boolean auto)
Set the
gc --auto option. |
(package private) void |
setBackground(boolean background) |
static void |
setExecutor(java.util.concurrent.ExecutorService e)
Set the executor for running auto-gc in the background.
|
void |
setExpire(java.util.Date expire)
During gc() or prune() each unreferenced, loose object which has been
created or modified after or at
expire will not be pruned. |
void |
setExpireAgeMillis(long expireAgeMillis)
During gc() or prune() each unreferenced, loose object which has been
created or modified in the last
expireAgeMillis milliseconds
will not be pruned. |
void |
setPackConfig(PackConfig pconfig)
Set the PackConfig used when (re-)writing packfiles.
|
void |
setPackExpire(java.util.Date packExpire)
During gc() or prune() packfiles which are created or modified after or
at
packExpire will not be deleted. |
void |
setPackExpireAgeMillis(long packExpireAgeMillis)
During gc() or prune() packfiles which are created or modified in the
last
packExpireAgeMillis milliseconds will not be deleted. |
GC |
setProgressMonitor(ProgressMonitor pm)
Set the progress monitor used for garbage collection methods.
|
(package private) boolean |
tooManyLooseObjects()
Quickly estimate number of loose objects, SHA1 is distributed evenly so
counting objects in one directory (bucket 17) is sufficient
|
(package private) boolean |
tooManyPacks() |
private PackFile |
writePack(java.util.Set<? extends ObjectId> want,
java.util.Set<? extends ObjectId> have,
java.util.Set<ObjectId> tags,
java.util.Set<ObjectId> tagTargets,
java.util.List<ObjectIdSet> excludeObjects) |
private static final org.slf4j.Logger LOG
private static final java.lang.String PRUNE_EXPIRE_DEFAULT
private static final java.lang.String PRUNE_PACK_EXPIRE_DEFAULT
private static final java.util.regex.Pattern PATTERN_LOOSE_OBJECT
private static final java.lang.String PACK_EXT
private static final java.lang.String BITMAP_EXT
private static final java.lang.String INDEX_EXT
private static final int DEFAULT_AUTOPACKLIMIT
private static final int DEFAULT_AUTOLIMIT
private static volatile java.util.concurrent.ExecutorService executor
private final FileRepository repo
private ProgressMonitor pm
private long expireAgeMillis
private java.util.Date expire
private long packExpireAgeMillis
private java.util.Date packExpire
private PackConfig pconfig
private java.util.Collection<Ref> lastPackedRefs
repack()
. This is
needed during prune(Set)
where we can optimize by looking at the
difference between the current refs and the refs which existed during
last repack()
.private long lastRepackTime
private boolean automatic
private boolean background
public GC(FileRepository repo)
null
as progress monitor will be used.repo
- the repo to work onpublic static void setExecutor(java.util.concurrent.ExecutorService e)
e
- the executor to be used for running auto-gcpublic java.util.Collection<PackFile> gc() throws java.io.IOException, java.text.ParseException
FileRepository
. It will
setAuto(boolean)
was set to true
gc
will
first check whether any housekeeping is required; if not, it exits
without performing any work.
If setBackground(boolean)
was set to true
collectGarbage
will start the gc in the background, and then
return immediately. In this case, errors will not be reported except in
gc.log.PackFile
's which
are newly createdjava.io.IOException
java.text.ParseException
- If the configuration parameter "gc.pruneexpire" couldn't be
parsedprivate java.util.concurrent.ExecutorService executor()
private java.util.Collection<PackFile> doGc() throws java.io.IOException, java.text.ParseException
java.io.IOException
java.text.ParseException
private void loosen(ObjectDirectoryInserter inserter, ObjectReader reader, PackFile pack, java.util.HashSet<ObjectId> existing) throws java.io.IOException
inserter
- reader
- pack
- existing
- java.io.IOException
private void deleteOldPacks(java.util.Collection<PackFile> oldPacks, java.util.Collection<PackFile> newPacks) throws java.text.ParseException, java.io.IOException
If we're not immediately expiring loose objects, loosen any objects in the old pack files which aren't in the new pack files.
oldPacks
- newPacks
- java.text.ParseException
java.io.IOException
private void removeOldPack(java.io.File packFile, java.lang.String packName, PackExt ext, int deleteOptions) throws java.io.IOException
packFile
- packName
- ext
- deleteOptions
- java.io.IOException
private void prunePreserved()
private void prunePack(java.lang.String packName)
packName
- public void prunePacked() throws java.io.IOException
java.io.IOException
public void prune(java.util.Set<ObjectId> objectsToKeep) throws java.io.IOException, java.text.ParseException
objectsToKeep
- a set of objects which should explicitly not be prunedjava.io.IOException
java.text.ParseException
- If the configuration parameter "gc.pruneexpire" couldn't be
parsedprivate long getExpireDate() throws java.text.ParseException
java.text.ParseException
private java.lang.String getPruneExpireStr()
private long getPackExpireDate() throws java.text.ParseException
java.text.ParseException
private void removeReferenced(java.util.Map<ObjectId,java.io.File> id2File, ObjectWalk w) throws MissingObjectException, IncorrectObjectTypeException, java.io.IOException
id2File
- w
- MissingObjectException
IncorrectObjectTypeException
java.io.IOException
public void packRefs() throws java.io.IOException
java.io.IOException
public java.util.Collection<PackFile> repack() throws java.io.IOException
java.io.IOException
- when during reading of refs, index, packfiles, objects,
reflog-entries or during writing to the packfiles
IOException
occursprivate static boolean isHead(Ref ref)
private static boolean isTag(Ref ref)
private void deleteEmptyRefsFolders() throws java.io.IOException
java.io.IOException
private boolean canBeSafelyDeleted(java.nio.file.Path path, java.time.Instant threshold)
private void deleteDir(java.nio.file.Path dir)
private boolean isDirectory(java.nio.file.Path p)
private void delete(java.nio.file.Path d)
private void deleteOrphans()
A file is considered an orphan if it is either a "bitmap" or an index file, and its corresponding pack file is missing in the list.
private void deleteTempPacksIdx()
private java.util.Set<ObjectId> listRefLogObjects(Ref ref, long minTime) throws java.io.IOException
ref
- the ref which log should be inspectedminTime
- only reflog entries not older then this time are processedObjectId
s contained in the reflogjava.io.IOException
private java.util.Collection<Ref> getAllRefs() throws java.io.IOException
java.io.IOException
private java.util.Set<ObjectId> listNonHEADIndexObjects() throws CorruptObjectException, java.io.IOException
java.io.IOException
CorruptObjectException
NoWorkTreeException
private PackFile writePack(@NonNull java.util.Set<? extends ObjectId> want, @NonNull java.util.Set<? extends ObjectId> have, @NonNull java.util.Set<ObjectId> tags, java.util.Set<ObjectId> tagTargets, java.util.List<ObjectIdSet> excludeObjects) throws java.io.IOException
java.io.IOException
private java.io.File nameFor(java.lang.String name, java.lang.String ext)
private void checkCancelled() throws CancelledException
CancelledException
public GC.RepoStatistics getStatistics() throws java.io.IOException
java.io.IOException
public GC setProgressMonitor(ProgressMonitor pm)
pm
- a ProgressMonitor
object.public void setExpireAgeMillis(long expireAgeMillis)
expireAgeMillis
milliseconds
will not be pruned. Only older objects may be pruned. If set to 0 then
every object is a candidate for pruning.expireAgeMillis
- minimal age of objects to be pruned in milliseconds.public void setPackExpireAgeMillis(long packExpireAgeMillis)
packExpireAgeMillis
milliseconds will not be deleted.
Only older packfiles may be deleted. If set to 0 then every packfile is a
candidate for deletion.packExpireAgeMillis
- minimal age of packfiles to be deleted in milliseconds.public void setPackConfig(@NonNull PackConfig pconfig)
pconfig
- the PackConfig
used when
writing packspublic void setExpire(java.util.Date expire)
expire
will not be pruned.
Only older objects may be pruned. If set to null then every object is a
candidate for pruning.expire
- instant in time which defines object expiration
objects with modification time before this instant are expired
objects with modification time newer or equal to this instant
are not expiredpublic void setPackExpire(java.util.Date packExpire)
packExpire
will not be deleted. Only older packfiles may
be deleted. If set to null then every packfile is a candidate for
deletion.packExpire
- instant in time which defines packfile expirationpublic void setAuto(boolean auto)
gc --auto
option.
With this option, gc checks whether any housekeeping is required; if not,
it exits without performing any work. Some JGit commands run
gc --auto
after performing operations that could create many
loose objects.
Housekeeping is required if there are too many loose objects or too many
packs in the repository. If the number of loose objects exceeds the value
of the gc.auto option JGit GC consolidates all existing packs into a
single pack (equivalent to -A
option), whereas git-core would
combine all loose objects into a single pack using repack -d -l
.
Setting the value of gc.auto
to 0 disables automatic packing of
loose objects.
If the number of packs exceeds the value of gc.autoPackLimit
,
then existing packs (except those marked with a .keep file) are
consolidated into a single pack by using the -A
option of repack.
Setting gc.autoPackLimit
to 0 disables automatic consolidation of
packs.
Like git the following jgit commands run auto gc:
receive.autogc = false
auto
- defines whether gc should do automatic housekeepingvoid setBackground(boolean background)
background
- whether to run the gc in a background thread.private boolean needGc()
private void addRepackAllOption()
boolean tooManyPacks()
true
if number of packs > gc.autopacklimit (default 50)boolean tooManyLooseObjects()
true
if number of loose objects > gc.auto (default 6700)private int getLooseObjectLimit()