From 0357b228883484a715f3a67db8c0602f287cdfc1 Mon Sep 17 00:00:00 2001 From: Ross Allan Date: Sun, 20 Jan 2013 21:13:40 +0000 Subject: [PATCH] Implement chunk garbage collection Signed-off-by: Ross Allan --- .../minecraft/ChunkGarbageCollector.java | 44 +++++++++++++++++++ .../patched/PatchChunkProviderServer.java | 14 +++++- .../patched/PatchMinecraftServer.java | 4 ++ .../util/StringFillers/ChatStringFiller.java | 1 - .../tickthreading/util/TableFormatter.java | 6 ++- 5 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 src/common/me/nallar/tickthreading/minecraft/ChunkGarbageCollector.java diff --git a/src/common/me/nallar/tickthreading/minecraft/ChunkGarbageCollector.java b/src/common/me/nallar/tickthreading/minecraft/ChunkGarbageCollector.java new file mode 100644 index 00000000..2a33d1bd --- /dev/null +++ b/src/common/me/nallar/tickthreading/minecraft/ChunkGarbageCollector.java @@ -0,0 +1,44 @@ +package me.nallar.tickthreading.minecraft; + +import java.util.HashSet; +import java.util.Set; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.profiler.Profiler; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.ChunkCoordIntPair; +import net.minecraft.world.WorldServer; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.gen.ChunkProviderServer; + +public class ChunkGarbageCollector { + public static Profiler profiler = MinecraftServer.getServer().theProfiler; + + public static void garbageCollect(WorldServer worldServer) { + profiler.startSection("chunkGC"); + int viewDistance = MinecraftServer.getServer().getConfigurationManager().getViewDistance(); + ChunkProviderServer chunkProvider = worldServer.theChunkProviderServer; + Set chunksToUnload = new HashSet(); + for (Chunk chunk : chunkProvider.getLoadedChunks()) { + chunksToUnload.add(ChunkCoordIntPair.chunkXZ2Int(chunk.xPosition, chunk.zPosition)); + } + + for (Object player_ : worldServer.playerEntities) { + EntityPlayerMP player = (EntityPlayerMP) player_; + int cX = (int) player.managedPosX >> 4; + int cZ = (int) player.managedPosZ >> 4; + int minX = cX - viewDistance; + int maxX = cX + viewDistance; + int minZ = cZ - viewDistance; + int maxZ = cZ + viewDistance; + for (int x = minX; x <= maxX; x++) { + for (int z = minZ; z <= maxZ; z++) { + chunksToUnload.remove(ChunkCoordIntPair.chunkXZ2Int(x, z)); + } + } + } + + chunkProvider.getChunksToUnloadSet().addAll(chunksToUnload); + profiler.endSection(); + } +} diff --git a/src/common/me/nallar/tickthreading/minecraft/patched/PatchChunkProviderServer.java b/src/common/me/nallar/tickthreading/minecraft/patched/PatchChunkProviderServer.java index 8fc664f6..f6c22bbc 100644 --- a/src/common/me/nallar/tickthreading/minecraft/patched/PatchChunkProviderServer.java +++ b/src/common/me/nallar/tickthreading/minecraft/patched/PatchChunkProviderServer.java @@ -2,6 +2,7 @@ import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -9,6 +10,7 @@ import com.google.common.collect.Sets; import me.nallar.tickthreading.minecraft.TickThreading; +import me.nallar.tickthreading.patcher.Declare; import net.minecraft.crash.CrashReport; import net.minecraft.crash.CrashReportCategory; import net.minecraft.util.ChunkCoordinates; @@ -69,7 +71,7 @@ public boolean unload100OldestChunks() { this.chunksToUnloadSet.remove(ChunkCoordIntPair.chunkXZ2Int(forced.chunkXPos, forced.chunkZPos)); } - for (int var1 = 0; var1 < 100 && !this.chunksToUnloadSet.isEmpty(); ++var1) { + for (int var1 = 0; var1 < 200 && !this.chunksToUnloadSet.isEmpty(); ++var1) { Long var2 = this.chunksToUnloadSet.iterator().next(); Chunk var3 = (Chunk) this.loadedChunkHashMap.getValueByKey(var2); var3.onChunkUnload(); @@ -192,6 +194,16 @@ public boolean saveChunks(boolean par1, IProgressUpdate par2IProgressUpdate) { return true; } + @Declare + public List getLoadedChunks() { + return loadedChunks; + } + + @Declare + public Set getChunksToUnloadSet() { + return chunksToUnloadSet; + } + public Object getLock(int x, int z) { long hash = hash(x, z); Object lock = chunkLoadLocks.get(hash); diff --git a/src/common/me/nallar/tickthreading/minecraft/patched/PatchMinecraftServer.java b/src/common/me/nallar/tickthreading/minecraft/patched/PatchMinecraftServer.java index 3f38241b..346c20d7 100644 --- a/src/common/me/nallar/tickthreading/minecraft/patched/PatchMinecraftServer.java +++ b/src/common/me/nallar/tickthreading/minecraft/patched/PatchMinecraftServer.java @@ -9,6 +9,7 @@ import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.relauncher.Side; import me.nallar.tickthreading.Log; +import me.nallar.tickthreading.minecraft.ChunkGarbageCollector; import me.nallar.tickthreading.minecraft.ThreadManager; import me.nallar.tickthreading.minecraft.TickThreading; import me.nallar.tickthreading.patcher.Declare; @@ -258,6 +259,9 @@ public void doWorldTick() { this.theProfiler.startSection("tracker"); var4.getEntityTracker().updateTrackedEntities(); this.theProfiler.endSection(); + if (this.tickCounter % 10000 == 0) { + ChunkGarbageCollector.garbageCollect(var4); + } this.theProfiler.endSection(); worldTickTimes.get(id)[this.tickCounter % 100] = System.nanoTime() - var2; diff --git a/src/common/me/nallar/tickthreading/util/StringFillers/ChatStringFiller.java b/src/common/me/nallar/tickthreading/util/StringFillers/ChatStringFiller.java index 45293f90..822b57ae 100644 --- a/src/common/me/nallar/tickthreading/util/StringFillers/ChatStringFiller.java +++ b/src/common/me/nallar/tickthreading/util/StringFillers/ChatStringFiller.java @@ -9,7 +9,6 @@ /** * Derived from https://github.com/andfRa/Saga/blob/master/src/org/saga/utility/chat/ChatFiller.java */ - class ChatStringFiller extends StringFiller { public final static double DEFAULT_LENGTH = 3.0 / 2.0; private final static double MAX_GAP = 1.25; diff --git a/src/common/me/nallar/tickthreading/util/TableFormatter.java b/src/common/me/nallar/tickthreading/util/TableFormatter.java index be90cc9c..ec59eb18 100644 --- a/src/common/me/nallar/tickthreading/util/TableFormatter.java +++ b/src/common/me/nallar/tickthreading/util/TableFormatter.java @@ -15,7 +15,11 @@ public class TableFormatter { public String splitter = " | "; public TableFormatter(ICommandSender commandSender) { - this(commandSender instanceof Entity ? StringFiller.CHAT : StringFiller.FIXED_WIDTH); + boolean chat = commandSender instanceof Entity; + stringFiller = chat ? StringFiller.CHAT : StringFiller.FIXED_WIDTH; + if (chat) { + splitter = " " + ChatFormat.YELLOW + '|' + ChatFormat.RESET + ' '; + } } public TableFormatter(StringFiller stringFiller) {