From c21286dbc301361ca45007596b8530437586c7d0 Mon Sep 17 00:00:00 2001 From: Glitchfinder Date: Mon, 5 Nov 2012 19:28:00 -0800 Subject: [PATCH] Offloading chunk conversion. SHould alleviate lag. --- .../BlockStoreConversionZDirectory.java | 2 +- .../blockmeta/chunkmeta/HashChunkManager.java | 95 ++++--------------- .../chunkstore/mcMMOSimpleRegionFile.java | 24 ++--- 3 files changed, 34 insertions(+), 87 deletions(-) diff --git a/src/main/java/com/gmail/nossr50/runnables/blockstoreconversion/BlockStoreConversionZDirectory.java b/src/main/java/com/gmail/nossr50/runnables/blockstoreconversion/BlockStoreConversionZDirectory.java index 5b7bcfa01..543cc9e33 100755 --- a/src/main/java/com/gmail/nossr50/runnables/blockstoreconversion/BlockStoreConversionZDirectory.java +++ b/src/main/java/com/gmail/nossr50/runnables/blockstoreconversion/BlockStoreConversionZDirectory.java @@ -15,7 +15,7 @@ import com.gmail.nossr50.util.blockmeta.HashChunkletManager; import com.gmail.nossr50.util.blockmeta.chunkmeta.HashChunkManager; public class BlockStoreConversionZDirectory implements Runnable { - private int taskID, cx, cz, x, y, z, y2, xPos, zPos, cxPos, czPos; + public int taskID, cx, cz, x, y, z, y2, xPos, zPos, cxPos, czPos; private String cxs, czs, chunkletName, chunkName; private org.bukkit.World world; private BukkitScheduler scheduler; diff --git a/src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/HashChunkManager.java b/src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/HashChunkManager.java index 3faef4be7..6a7fd5418 100755 --- a/src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/HashChunkManager.java +++ b/src/main/java/com/gmail/nossr50/util/blockmeta/chunkmeta/HashChunkManager.java @@ -7,6 +7,7 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.lang.Integer; +import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.UUID; @@ -17,6 +18,7 @@ import org.bukkit.block.Block; import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.runnables.ChunkletUnloader; +import com.gmail.nossr50.runnables.blockstoreconversion.BlockStoreConversionZDirectory; import com.gmail.nossr50.util.blockmeta.ChunkletStore; import com.gmail.nossr50.util.blockmeta.PrimitiveChunkletStore; import com.gmail.nossr50.util.blockmeta.PrimitiveExChunkletStore; @@ -27,6 +29,7 @@ import org.getspout.spoutapi.chunkstore.mcMMOSimpleRegionFile; public class HashChunkManager implements ChunkManager { private HashMap> regionFiles = new HashMap>(); public HashMap store = new HashMap(); + public ArrayList converters = new ArrayList(); @Override public void closeAll() { @@ -377,88 +380,32 @@ public class HashChunkManager implements ChunkManager { public void cleanUp() {} public void convertChunk(File dataDir, int cx, int cz, World world) { - HashChunkletManager manager = new HashChunkletManager(); - manager.loadChunk(cx, cz, world); - - for(int y = 0; y < (world.getMaxHeight() / 64); y++) { - String chunkletName = world.getName() + "," + cx + "," + cz + "," + y; - ChunkletStore tempChunklet = manager.store.get(chunkletName); - PrimitiveChunkletStore primitiveChunklet = null; - PrimitiveExChunkletStore primitiveExChunklet = null; - if(tempChunklet instanceof PrimitiveChunkletStore) - primitiveChunklet = (PrimitiveChunkletStore) tempChunklet; - else if(tempChunklet instanceof PrimitiveExChunkletStore) - primitiveExChunklet = (PrimitiveExChunkletStore) tempChunklet; - if(tempChunklet == null) { - continue; - } else { - String chunkName = world.getName() + "," + cx + "," + cz; - PrimitiveChunkStore cChunk = (PrimitiveChunkStore) store.get(chunkName); - - if(cChunk != null) { - int xPos = cx * 16; - int zPos = cz * 16; - - for(int x = 0; x < 16; x++) { - for(int z = 0; z < 16; z++) { - int cxPos = xPos + x; - int czPos = zPos + z; - - for(int y2 = (64 * y); y2 < (64 * y + 64); y2++) { - if(!manager.isTrue(cxPos, y2, czPos, world)) - continue; - - setTrue(cxPos, y2, czPos, world); - } - } - } - continue; - } - - setTrue(cx * 16, 0, cz * 16, world); - setFalse(cx * 16, 0, cz * 16, world); - cChunk = (PrimitiveChunkStore) store.get(chunkName); - - for(int x = 0; x < 16; x++) { - for(int z = 0; z < 16; z++) { - boolean[] oldArray; - if(primitiveChunklet != null) - oldArray = primitiveChunklet.store[x][z]; - if(primitiveExChunklet != null) - oldArray = primitiveExChunklet.store[x][z]; - else - return; - boolean[] newArray = cChunk.store[x][z]; - if(oldArray.length < 64) - return; - else if(newArray.length < ((y * 64) + 64)) - return; - System.arraycopy(oldArray, 0, newArray, (y * 64), 64); - } - } - } - } - - manager.unloadChunk(cx, cz, world); - unloadChunk(cx, cz, world); - + if(!dataDir.exists()) return; File cxDir = new File(dataDir, "" + cx); if(!cxDir.exists()) return; File czDir = new File(cxDir, "" + cz); if(!czDir.exists()) return; - for(File yFile : czDir.listFiles()) { - if(!yFile.exists()) + boolean conversionSet = false; + + for(BlockStoreConversionZDirectory converter : this.converters) { + if(converter == null) continue; - yFile.delete(); + if(converter.taskID >= 0) + continue; + + if(conversionSet) + converters.remove(converter); + + converter.start(world, cxDir, czDir); + conversionSet = true; } - if(czDir.listFiles().length <= 0) - czDir.delete(); - if(cxDir.listFiles().length <= 0) - cxDir.delete(); - if(dataDir.listFiles().length <= 0) - dataDir.delete(); + if(!conversionSet) { + BlockStoreConversionZDirectory converter = new BlockStoreConversionZDirectory(); + converter.start(world, cxDir, czDir); + converters.add(converter); + } } } diff --git a/src/main/java/org/getspout/spoutapi/chunkstore/mcMMOSimpleRegionFile.java b/src/main/java/org/getspout/spoutapi/chunkstore/mcMMOSimpleRegionFile.java index 8acd53434..1e3354479 100755 --- a/src/main/java/org/getspout/spoutapi/chunkstore/mcMMOSimpleRegionFile.java +++ b/src/main/java/org/getspout/spoutapi/chunkstore/mcMMOSimpleRegionFile.java @@ -102,7 +102,7 @@ public class mcMMOSimpleRegionFile { } } - public final RandomAccessFile getFile() { + public synchronized final RandomAccessFile getFile() { lastAccessTime = System.currentTimeMillis(); if (file == null) { try { @@ -150,7 +150,7 @@ public class mcMMOSimpleRegionFile { return file; } - public boolean testCloseTimeout() { + public synchronized boolean testCloseTimeout() { /*if (System.currentTimeMillis() - TIMEOUT_TIME > lastAccessTime) { close(); return true; @@ -158,12 +158,12 @@ public class mcMMOSimpleRegionFile { return false; } - public DataOutputStream getOutputStream(int x, int z) { + public synchronized DataOutputStream getOutputStream(int x, int z) { int index = getChunkIndex(x, z); return new DataOutputStream(new DeflaterOutputStream(new mcMMOSimpleChunkBuffer(this, index))); } - public DataInputStream getInputStream(int x, int z) throws IOException { + public synchronized DataInputStream getInputStream(int x, int z) throws IOException { int index = getChunkIndex(x, z); int actualLength = dataActualLength[index]; if (actualLength == 0) { @@ -176,7 +176,7 @@ public class mcMMOSimpleRegionFile { return new DataInputStream(new InflaterInputStream(new ByteArrayInputStream(data))); } - void write(int index, byte[] buffer, int size) throws IOException { + synchronized void write(int index, byte[] buffer, int size) throws IOException { int oldStart = setInUse(index, false); int start = findSpace(oldStart, size); getFile().seek(start << segmentSize); @@ -188,7 +188,7 @@ public class mcMMOSimpleRegionFile { saveFAT(); } - public void close() { + public synchronized void close() { try { if (file != null) { file.seek(4096 * 2); @@ -200,7 +200,7 @@ public class mcMMOSimpleRegionFile { } } - private int setInUse(int index, boolean used) { + private synchronized int setInUse(int index, boolean used) { if (dataActualLength[index] == 0) { return dataStart[index]; } @@ -225,7 +225,7 @@ public class mcMMOSimpleRegionFile { return dataStart[index]; } - private void extendFile() throws IOException { + private synchronized void extendFile() throws IOException { long extend = (-getFile().length()) & segmentMask; getFile().seek(getFile().length()); @@ -235,7 +235,7 @@ public class mcMMOSimpleRegionFile { } } - private int findSpace(int oldStart, int size) { + private synchronized int findSpace(int oldStart, int size) { int segments = sizeToSegments(size); boolean oldFree = true; @@ -268,7 +268,7 @@ public class mcMMOSimpleRegionFile { return start; } - private int sizeToSegments(int size) { + private synchronized int sizeToSegments(int size) { if (size <= 0) { return 1; } else { @@ -276,7 +276,7 @@ public class mcMMOSimpleRegionFile { } } - private Integer getChunkIndex(int x, int z) { + private synchronized Integer getChunkIndex(int x, int z) { if (rx != (x >> 5) || rz != (z >> 5)) { throw new RuntimeException(x + ", " + z + " not in region " + rx + ", " + rz); } @@ -287,7 +287,7 @@ public class mcMMOSimpleRegionFile { return (x << 5) + z; } - private void saveFAT() throws IOException { + private synchronized void saveFAT() throws IOException { getFile().seek(0); for (int i = 0; i < 1024; i++) { getFile().writeInt(dataStart[i]);