2 // Getdown - application installer, patcher and launcher
3 // Copyright (C) 2004-2018 Getdown authors
4 // https://github.com/threerings/getdown/blob/master/LICENSE
6 package com.threerings.getdown.cache;
9 import com.threerings.getdown.util.FileUtil;
12 * Collects elements in the {@link ResourceCache cache} which became unused and deletes them
15 public class GarbageCollector
18 * Collect and delete the garbage in the cache.
20 public static void collect (File cacheDir, final long retentionPeriodMillis)
22 FileUtil.walkTree(cacheDir, new FileUtil.Visitor() {
23 @Override public void visit (File file) {
24 File cachedFile = getCachedFile(file);
25 File lastAccessedFile = getLastAccessedFile(file);
26 if (!cachedFile.exists() || !lastAccessedFile.exists()) {
27 if (cachedFile.exists()) {
28 FileUtil.deleteHarder(cachedFile);
30 FileUtil.deleteHarder(lastAccessedFile);
32 } else if (shouldDelete(lastAccessedFile, retentionPeriodMillis)) {
33 FileUtil.deleteHarder(lastAccessedFile);
34 FileUtil.deleteHarder(cachedFile);
37 File folder = file.getParentFile();
39 String[] children = folder.list();
40 if (children != null && children.length == 0) {
41 FileUtil.deleteHarder(folder);
49 * Collect and delete garbage in the native cache. It tries to find a jar file with a matching
50 * last modified file, and deletes the entire directory accordingly.
52 public static void collectNative (File cacheDir, final long retentionPeriodMillis)
54 File[] subdirs = cacheDir.listFiles();
55 if (subdirs != null) {
56 for (File dir : subdirs) {
57 if (dir.isDirectory()) {
58 // Get all the native jars in the directory (there should only be one)
59 for (File file : dir.listFiles()) {
60 if (!file.getName().endsWith(".jar")) {
63 File cachedFile = getCachedFile(file);
64 File lastAccessedFile = getLastAccessedFile(file);
65 if (!cachedFile.exists() || !lastAccessedFile.exists() ||
66 shouldDelete(lastAccessedFile, retentionPeriodMillis)) {
67 FileUtil.deleteDirHarder(dir);
71 // @TODO There shouldn't be any loose files in native/ but if there are then
72 // what? Delete them? file.delete();
78 private static boolean shouldDelete (File lastAccessedFile, long retentionMillis)
80 return System.currentTimeMillis() - lastAccessedFile.lastModified() > retentionMillis;
83 private static File getLastAccessedFile (File file)
85 return isLastAccessedFile(file) ? file : new File(
86 file.getParentFile(), file.getName() + ResourceCache.LAST_ACCESSED_FILE_SUFFIX);
89 private static boolean isLastAccessedFile (File file)
91 return file.getName().endsWith(ResourceCache.LAST_ACCESSED_FILE_SUFFIX);
94 private static File getCachedFile (File file)
96 return !isLastAccessedFile(file) ? file : new File(
97 file.getParentFile(), file.getName().substring(0, file.getName().lastIndexOf(".")));