minecraft-src/net/minecraft/server/packs/DownloadCacheCleaner.java
2025-07-04 03:15:13 +03:00

111 lines
3.7 KiB
Java

package net.minecraft.server.packs;
import com.mojang.logging.LogUtils;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.slf4j.Logger;
public class DownloadCacheCleaner {
private static final Logger LOGGER = LogUtils.getLogger();
public static void vacuumCacheDir(Path path, int maxEntries) {
try {
List<DownloadCacheCleaner.PathAndTime> list = listFilesWithModificationTimes(path);
int i = list.size() - maxEntries;
if (i <= 0) {
return;
}
list.sort(DownloadCacheCleaner.PathAndTime.NEWEST_FIRST);
List<DownloadCacheCleaner.PathAndPriority> list2 = prioritizeFilesInDirs(list);
Collections.reverse(list2);
list2.sort(DownloadCacheCleaner.PathAndPriority.HIGHEST_PRIORITY_FIRST);
Set<Path> set = new HashSet();
for (int j = 0; j < i; j++) {
DownloadCacheCleaner.PathAndPriority pathAndPriority = (DownloadCacheCleaner.PathAndPriority)list2.get(j);
Path path2 = pathAndPriority.path;
try {
Files.delete(path2);
if (pathAndPriority.removalPriority == 0) {
set.add(path2.getParent());
}
} catch (IOException var12) {
LOGGER.warn("Failed to delete cache file {}", path2, var12);
}
}
set.remove(path);
for (Path path3 : set) {
try {
Files.delete(path3);
} catch (DirectoryNotEmptyException var10) {
} catch (IOException var11) {
LOGGER.warn("Failed to delete empty(?) cache directory {}", path3, var11);
}
}
} catch (UncheckedIOException | IOException var13) {
LOGGER.error("Failed to vacuum cache dir {}", path, var13);
}
}
private static List<DownloadCacheCleaner.PathAndTime> listFilesWithModificationTimes(Path path) throws IOException {
try {
final List<DownloadCacheCleaner.PathAndTime> list = new ArrayList();
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) {
if (attributes.isRegularFile() && !file.getParent().equals(path)) {
FileTime fileTime = attributes.lastModifiedTime();
list.add(new DownloadCacheCleaner.PathAndTime(file, fileTime));
}
return FileVisitResult.CONTINUE;
}
});
return list;
} catch (NoSuchFileException var2) {
return List.of();
}
}
private static List<DownloadCacheCleaner.PathAndPriority> prioritizeFilesInDirs(List<DownloadCacheCleaner.PathAndTime> paths) {
List<DownloadCacheCleaner.PathAndPriority> list = new ArrayList();
Object2IntOpenHashMap<Path> object2IntOpenHashMap = new Object2IntOpenHashMap<>();
for (DownloadCacheCleaner.PathAndTime pathAndTime : paths) {
int i = object2IntOpenHashMap.addTo(pathAndTime.path.getParent(), 1);
list.add(new DownloadCacheCleaner.PathAndPriority(pathAndTime.path, i));
}
return list;
}
record PathAndPriority(Path path, int removalPriority) {
public static final Comparator<DownloadCacheCleaner.PathAndPriority> HIGHEST_PRIORITY_FIRST = Comparator.comparing(
DownloadCacheCleaner.PathAndPriority::removalPriority
)
.reversed();
}
record PathAndTime(Path path, FileTime modifiedTime) {
public static final Comparator<DownloadCacheCleaner.PathAndTime> NEWEST_FIRST = Comparator.comparing(DownloadCacheCleaner.PathAndTime::modifiedTime)
.reversed();
}
}