package net.minecraft.data; import org.apache.logging.log4j.LogManager; import java.nio.file.LinkOption; import java.nio.file.FileVisitOption; import java.util.stream.Stream; import java.util.Objects; import javax.annotation.Nullable; import java.io.Writer; import java.util.Collection; import java.util.stream.Collector; import java.util.stream.Collectors; import java.util.List; import java.io.IOException; import org.apache.commons.io.IOUtils; import com.google.common.base.Charsets; import java.nio.file.OpenOption; import java.nio.file.Files; import java.nio.file.attribute.FileAttribute; import com.google.common.collect.Sets; import com.google.common.collect.Maps; import java.util.Set; import java.util.Map; import java.nio.file.Path; import org.apache.logging.log4j.Logger; public class HashCache { private static final Logger LOGGER; private final Path path; private final Path cachePath; private int hits; private final Map oldCache; private final Map newCache; private final Set keep; public HashCache(final Path path, final String string) throws IOException { this.oldCache = Maps.newHashMap(); this.newCache = Maps.newHashMap(); this.keep = Sets.newHashSet(); this.path = path; final Path path2 = path.resolve(".cache"); Files.createDirectories(path2, new FileAttribute[0]); this.cachePath = path2.resolve(string); final String s; this.walkOutputFiles().forEach(path -> s = this.oldCache.put(path, "")); if (Files.isReadable(this.cachePath)) { final int integer4; IOUtils.readLines(Files.newInputStream(this.cachePath), Charsets.UTF_8).forEach(string -> { integer4 = string.indexOf(32); this.oldCache.put(path.resolve(string.substring(integer4 + 1)), string.substring(0, integer4)); }); } } public void purgeStaleAndWrite() throws IOException { this.removeStale(); Writer writer2; try { writer2 = Files.newBufferedWriter(this.cachePath); } catch (IOException iOException3) { HashCache.LOGGER.warn("Unable write cachefile {}: {}", this.cachePath, iOException3.toString()); return; } IOUtils.writeLines((Collection)this.newCache.entrySet().stream().map(entry -> entry.getValue() + ' ' + this.path.relativize((Path)entry.getKey())).collect(Collectors.toList()), System.lineSeparator(), writer2); writer2.close(); HashCache.LOGGER.debug("Caching: cache hits: {}, created: {} removed: {}", this.hits, (this.newCache.size() - this.hits), this.oldCache.size()); } @Nullable public String getHash(final Path path) { return this.oldCache.get(path); } public void putNew(final Path path, final String string) { this.newCache.put(path, string); if (Objects.equals(this.oldCache.remove(path), string)) { ++this.hits; } } public boolean had(final Path path) { return this.oldCache.containsKey(path); } public void keep(final Path path) { this.keep.add(path); } private void removeStale() throws IOException { this.walkOutputFiles().forEach(path -> { if (this.had(path) && !this.keep.contains(path)) { try { Files.delete(path); } catch (IOException iOException3) { HashCache.LOGGER.debug("Unable to delete: {} ({})", path, iOException3.toString()); } } }); } private Stream walkOutputFiles() throws IOException { return Files.walk(this.path).filter(path -> !Objects.equals(this.cachePath, path) && !Files.isDirectory(path)); } static { LOGGER = LogManager.getLogger(); } }