From d5d6f7e860f20e969d1b39b3b33f9293b3decf97 Mon Sep 17 00:00:00 2001 From: Glitchfinder Date: Sun, 13 Jan 2013 20:02:11 -0800 Subject: [PATCH] Reducing CPU usage as a result of unloading chunks. --- .../nossr50/datatypes/InactiveChunk.java | 17 ++++++++ .../nossr50/runnables/ChunkletUnloader.java | 42 ++++++++++++------- 2 files changed, 44 insertions(+), 15 deletions(-) create mode 100755 src/main/java/com/gmail/nossr50/datatypes/InactiveChunk.java diff --git a/src/main/java/com/gmail/nossr50/datatypes/InactiveChunk.java b/src/main/java/com/gmail/nossr50/datatypes/InactiveChunk.java new file mode 100755 index 000000000..d58a4d332 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/datatypes/InactiveChunk.java @@ -0,0 +1,17 @@ +package com.gmail.nossr50.datatypes; + +import org.bukkit.Chunk; + +public class InactiveChunk { + public Chunk chunk; + public int inactiveTime = 0; + + public InactiveChunk(Chunk chunk, int inactiveTime) { + this.chunk = chunk; + this.inactiveTime = inactiveTime; + } + + public InactiveChunk(Chunk chunk) { + this(chunk, 0); + } +} \ No newline at end of file diff --git a/src/main/java/com/gmail/nossr50/runnables/ChunkletUnloader.java b/src/main/java/com/gmail/nossr50/runnables/ChunkletUnloader.java index 44340fb30..609b2d1bb 100644 --- a/src/main/java/com/gmail/nossr50/runnables/ChunkletUnloader.java +++ b/src/main/java/com/gmail/nossr50/runnables/ChunkletUnloader.java @@ -8,23 +8,24 @@ import java.util.Map.Entry; import org.bukkit.Chunk; import org.bukkit.World; +import com.gmail.nossr50.datatypes.InactiveChunk; import com.gmail.nossr50.mcMMO; public class ChunkletUnloader implements Runnable { - private static Map unloadedChunks = new HashMap(); + private static Map unloadedChunks = new HashMap(); private static int minimumInactiveTime = 60; //Should be a multiple of RUN_INTERVAL for best performance public static final int RUN_INTERVAL = 20; public static void addToList(Chunk chunk) { - //Unfortunately we can't use Map.contains() because Chunks are always new objects - //This method isn't efficient enough for me - for (Chunk otherChunk : unloadedChunks.keySet()) { - if (chunk.getX() == otherChunk.getX() && chunk.getZ() == otherChunk.getZ()) { - return; - } - } + if (chunk == null || chunk.getWorld() == null) + return; - unloadedChunks.put(chunk, 0); + String key = chunk.getWorld().getName() + "," + chunk.getX() + "," + chunk.getZ(); + + if (unloadedChunks.containsKey(key)) + return; + + unloadedChunks.put(key, new InactiveChunk(chunk)); } public static void addToList(int cx, int cz, World world) { @@ -33,24 +34,35 @@ public class ChunkletUnloader implements Runnable { @Override public void run() { - for (Iterator> unloadedChunkIterator = unloadedChunks.entrySet().iterator() ; unloadedChunkIterator.hasNext() ; ) { - Entry entry = unloadedChunkIterator.next(); - Chunk chunk = entry.getKey(); + for (Iterator> unloadedChunkIterator = unloadedChunks.entrySet().iterator() ; unloadedChunkIterator.hasNext() ; ) { + Entry entry = unloadedChunkIterator.next(); + + if (entry.getKey() == null || entry.getValue() == null) { + unloadedChunkIterator.remove(); + continue; + } + + if (entry.getValue().chunk == null) { + unloadedChunkIterator.remove(); + continue; + } + + Chunk chunk = entry.getValue().chunk; if (!chunk.isLoaded()) { - int inactiveTime = entry.getValue() + RUN_INTERVAL; + int inactiveTime = entry.getValue().inactiveTime + RUN_INTERVAL; //Chunklets are unloaded only if their chunk has been unloaded for minimumInactiveTime if (inactiveTime >= minimumInactiveTime) { if (mcMMO.placeStore == null) - continue; + return; mcMMO.placeStore.unloadChunk(chunk.getX(), chunk.getZ(), chunk.getWorld()); unloadedChunkIterator.remove(); continue; } - unloadedChunks.put(entry.getKey(), inactiveTime); + entry.getValue().inactiveTime = inactiveTime; } else { //Just remove the entry if the chunk has been reloaded.