X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=getdown%2Fsrc%2Fgetdown%2Fcore%2Fsrc%2Fmain%2Fjava%2Fcom%2Fthreerings%2Fgetdown%2Fcache%2FGarbageCollector.java;fp=getdown%2Fsrc%2Fgetdown%2Fcore%2Fsrc%2Fmain%2Fjava%2Fcom%2Fthreerings%2Fgetdown%2Fcache%2FGarbageCollector.java;h=67ea64575fb00cf403d33b305e9ab98c16cbd696;hb=ca8504cf9d10874dce9f07cf7a9d933853fe0dd0;hp=0000000000000000000000000000000000000000;hpb=775e7bc104584e88dddcea73fbf02c66f5200c16;p=jalview.git diff --git a/getdown/src/getdown/core/src/main/java/com/threerings/getdown/cache/GarbageCollector.java b/getdown/src/getdown/core/src/main/java/com/threerings/getdown/cache/GarbageCollector.java new file mode 100644 index 0000000..67ea645 --- /dev/null +++ b/getdown/src/getdown/core/src/main/java/com/threerings/getdown/cache/GarbageCollector.java @@ -0,0 +1,99 @@ +// +// Getdown - application installer, patcher and launcher +// Copyright (C) 2004-2018 Getdown authors +// https://github.com/threerings/getdown/blob/master/LICENSE + +package com.threerings.getdown.cache; + +import java.io.File; +import com.threerings.getdown.util.FileUtil; + +/** + * Collects elements in the {@link ResourceCache cache} which became unused and deletes them + * afterwards. + */ +public class GarbageCollector +{ + /** + * Collect and delete the garbage in the cache. + */ + public static void collect (File cacheDir, final long retentionPeriodMillis) + { + FileUtil.walkTree(cacheDir, new FileUtil.Visitor() { + @Override public void visit (File file) { + File cachedFile = getCachedFile(file); + File lastAccessedFile = getLastAccessedFile(file); + if (!cachedFile.exists() || !lastAccessedFile.exists()) { + if (cachedFile.exists()) { + FileUtil.deleteHarder(cachedFile); + } else { + FileUtil.deleteHarder(lastAccessedFile); + } + } else if (shouldDelete(lastAccessedFile, retentionPeriodMillis)) { + FileUtil.deleteHarder(lastAccessedFile); + FileUtil.deleteHarder(cachedFile); + } + + File folder = file.getParentFile(); + if (folder != null) { + String[] children = folder.list(); + if (children != null && children.length == 0) { + FileUtil.deleteHarder(folder); + } + } + } + }); + } + + /** + * Collect and delete garbage in the native cache. It tries to find a jar file with a matching + * last modified file, and deletes the entire directory accordingly. + */ + public static void collectNative (File cacheDir, final long retentionPeriodMillis) + { + File[] subdirs = cacheDir.listFiles(); + if (subdirs != null) { + for (File dir : subdirs) { + if (dir.isDirectory()) { + // Get all the native jars in the directory (there should only be one) + for (File file : dir.listFiles()) { + if (!file.getName().endsWith(".jar")) { + continue; + } + File cachedFile = getCachedFile(file); + File lastAccessedFile = getLastAccessedFile(file); + if (!cachedFile.exists() || !lastAccessedFile.exists() || + shouldDelete(lastAccessedFile, retentionPeriodMillis)) { + FileUtil.deleteDirHarder(dir); + } + } + } else { + // @TODO There shouldn't be any loose files in native/ but if there are then + // what? Delete them? file.delete(); + } + } + } + } + + private static boolean shouldDelete (File lastAccessedFile, long retentionMillis) + { + return System.currentTimeMillis() - lastAccessedFile.lastModified() > retentionMillis; + } + + private static File getLastAccessedFile (File file) + { + return isLastAccessedFile(file) ? file : new File( + file.getParentFile(), file.getName() + ResourceCache.LAST_ACCESSED_FILE_SUFFIX); + } + + private static boolean isLastAccessedFile (File file) + { + return file.getName().endsWith(ResourceCache.LAST_ACCESSED_FILE_SUFFIX); + } + + private static File getCachedFile (File file) + { + return !isLastAccessedFile(file) ? file : new File( + file.getParentFile(), file.getName().substring(0, file.getName().lastIndexOf("."))); + } +}