minecraft-source/src/net/minecraft/data/HashCache.java

111 lines
3.9 KiB
Java

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<Path, String> oldCache;
private final Map<Path, String> newCache;
private final Set<Path> 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<Path> walkOutputFiles() throws IOException {
return Files.walk(this.path).filter(path -> !Objects.equals(this.cachePath, path) && !Files.isDirectory(path));
}
static {
LOGGER = LogManager.getLogger();
}
}