DownloadCacheCleaner.java

net.minecraft.server.packs.DownloadCacheCleaner

信息

  • 全限定名:net.minecraft.server.packs.DownloadCacheCleaner
  • 类型:public class
  • 包:net.minecraft.server.packs
  • 源码路径:src/main/java/net/minecraft/server/packs/DownloadCacheCleaner.java
  • 起始行号:L23
  • 职责:

    TODO

字段/常量

  • LOGGER
    • 类型: Logger
    • 修饰符: private static final
    • 源码定位: L24
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.server.packs.DownloadCacheCleaner.PathAndPriority

    • 类型: record
    • 修饰符: private
    • 源码定位: L100
    • 说明:

      TODO

  • net.minecraft.server.packs.DownloadCacheCleaner.PathAndTime

    • 类型: record
    • 修饰符: private
    • 源码定位: L107
    • 说明:

      TODO

构造器

方法

下面的方法块按源码顺序生成。

public static void vacuumCacheDir(Path cacheDir, int maxFiles) @ L26

  • 方法名:vacuumCacheDir
  • 源码定位:L26
  • 返回类型:void
  • 修饰符:public static

参数:

  • cacheDir: Path
  • maxFiles: int

说明:

TODO

private static List<DownloadCacheCleaner.PathAndTime> listFilesWithModificationTimes(Path cacheDir) @ L69

  • 方法名:listFilesWithModificationTimes
  • 源码定位:L69
  • 返回类型:List<DownloadCacheCleaner.PathAndTime>
  • 修饰符:private static

参数:

  • cacheDir: Path

说明:

TODO

private static List<DownloadCacheCleaner.PathAndPriority> prioritizeFilesInDirs(List<DownloadCacheCleaner.PathAndTime> filesAndDates) @ L88

  • 方法名:prioritizeFilesInDirs
  • 源码定位:L88
  • 返回类型:List<DownloadCacheCleaner.PathAndPriority>
  • 修饰符:private static

参数:

  • filesAndDates: List<DownloadCacheCleaner.PathAndTime>

说明:

TODO

代码

public class DownloadCacheCleaner {
    private static final Logger LOGGER = LogUtils.getLogger();
 
    public static void vacuumCacheDir(Path cacheDir, int maxFiles) {
        try {
            List<DownloadCacheCleaner.PathAndTime> filesAndDates = listFilesWithModificationTimes(cacheDir);
            int toRemove = filesAndDates.size() - maxFiles;
            if (toRemove <= 0) {
                return;
            }
 
            filesAndDates.sort(DownloadCacheCleaner.PathAndTime.NEWEST_FIRST);
            List<DownloadCacheCleaner.PathAndPriority> filesWithDirOrder = prioritizeFilesInDirs(filesAndDates);
            Collections.reverse(filesWithDirOrder);
            filesWithDirOrder.sort(DownloadCacheCleaner.PathAndPriority.HIGHEST_PRIORITY_FIRST);
            Set<Path> emptyDirectoryCandidates = new HashSet<>();
 
            for (int i = 0; i < toRemove; i++) {
                DownloadCacheCleaner.PathAndPriority entry = filesWithDirOrder.get(i);
                Path pathToRemove = entry.path;
 
                try {
                    Files.delete(pathToRemove);
                    if (entry.removalPriority == 0) {
                        emptyDirectoryCandidates.add(pathToRemove.getParent());
                    }
                } catch (IOException var12) {
                    LOGGER.warn("Failed to delete cache file {}", pathToRemove, var12);
                }
            }
 
            emptyDirectoryCandidates.remove(cacheDir);
 
            for (Path dir : emptyDirectoryCandidates) {
                try {
                    Files.delete(dir);
                } catch (DirectoryNotEmptyException var10) {
                } catch (IOException var11) {
                    LOGGER.warn("Failed to delete empty(?) cache directory {}", dir, var11);
                }
            }
        } catch (UncheckedIOException | IOException var13) {
            LOGGER.error("Failed to vacuum cache dir {}", cacheDir, var13);
        }
    }
 
    private static List<DownloadCacheCleaner.PathAndTime> listFilesWithModificationTimes(Path cacheDir) throws IOException {
        try {
            final List<DownloadCacheCleaner.PathAndTime> unsortedFiles = new ArrayList<>();
            Files.walkFileTree(cacheDir, new SimpleFileVisitor<Path>() {
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
                    if (attrs.isRegularFile() && !file.getParent().equals(cacheDir)) {
                        FileTime fileTime = attrs.lastModifiedTime();
                        unsortedFiles.add(new DownloadCacheCleaner.PathAndTime(file, fileTime));
                    }
 
                    return FileVisitResult.CONTINUE;
                }
            });
            return unsortedFiles;
        } catch (NoSuchFileException var2) {
            return List.of();
        }
    }
 
    private static List<DownloadCacheCleaner.PathAndPriority> prioritizeFilesInDirs(List<DownloadCacheCleaner.PathAndTime> filesAndDates) {
        List<DownloadCacheCleaner.PathAndPriority> result = new ArrayList<>();
        Object2IntOpenHashMap<Path> parentCounts = new Object2IntOpenHashMap<>();
 
        for (DownloadCacheCleaner.PathAndTime entry : filesAndDates) {
            int removalPriority = parentCounts.addTo(entry.path.getParent(), 1);
            result.add(new DownloadCacheCleaner.PathAndPriority(entry.path, removalPriority));
        }
 
        return result;
    }
 
    private record PathAndPriority(Path path, int removalPriority) {
        public static final Comparator<DownloadCacheCleaner.PathAndPriority> HIGHEST_PRIORITY_FIRST = Comparator.comparing(
                DownloadCacheCleaner.PathAndPriority::removalPriority
            )
            .reversed();
    }
 
    private record PathAndTime(Path path, FileTime modifiedTime) {
        public static final Comparator<DownloadCacheCleaner.PathAndTime> NEWEST_FIRST = Comparator.comparing(DownloadCacheCleaner.PathAndTime::modifiedTime)
            .reversed();
    }
}

引用的其他类