package net.glowstone.io.anvil; /* ** 2011 January 5 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. **/ /* * 2011 February 16 * * This source code is based on the work of Scaevolus (see notice above). * It has been slightly modified by Mojang AB to limit the maximum cache * size (relevant to extremely big worlds on Linux systems with limited * number of file handles). The region files are postfixed with ".mcr" * (Minecraft region file) instead of ".data" to differentiate from the * original McRegion files. * */ /* * Some changes have been made as part of the Glowstone project. */ import net.glowstone.GlowServer; import java.io.File; import java.io.IOException; import java.lang.ref.Reference; import java.lang.ref.SoftReference; import java.util.HashMap; import java.util.Map; /** * A simple cache and wrapper for efficiently accessing multiple RegionFiles * simultaneously. */ public class RegionFileCache { private static final int MAX_CACHE_SIZE = 256; private final Map<File, Reference<RegionFile>> cache = new HashMap<>(); private final String extension; private final File regionDir; public RegionFileCache(File basePath, String extension) { this.extension = extension; regionDir = new File(basePath, "region"); } public RegionFile getRegionFile(int chunkX, int chunkZ) throws IOException { File file = new File(regionDir, "r." + (chunkX >> 5) + "." + (chunkZ >> 5) + extension); Reference<RegionFile> ref = cache.get(file); if (ref != null && ref.get() != null) { return ref.get(); } if (!regionDir.isDirectory() && !regionDir.mkdirs()) { GlowServer.logger.warning("Failed to create directory: " + regionDir); } if (cache.size() >= MAX_CACHE_SIZE) { clear(); } RegionFile reg = new RegionFile(file); cache.put(file, new SoftReference<>(reg)); return reg; } public void clear() throws IOException { for (Reference<RegionFile> ref : cache.values()) { RegionFile value = ref.get(); if (value != null) { value.close(); } } cache.clear(); } }