111 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			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();
 | |
| 	}
 | |
| }
 |