Skip to content

Commit

Permalink
Implement chunk garbage collection
Browse files Browse the repository at this point in the history
Signed-off-by: Ross Allan <rallanpcl@gmail.com>
  • Loading branch information
LunNova committed Jan 20, 2013
1 parent 12a9192 commit 0357b22
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 3 deletions.
@@ -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<Long> chunksToUnload = new HashSet<Long>();
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();
}
}
Expand Up @@ -2,13 +2,15 @@

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;

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;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -192,6 +194,16 @@ public boolean saveChunks(boolean par1, IProgressUpdate par2IProgressUpdate) {
return true;
}

@Declare
public List<Chunk> getLoadedChunks() {
return loadedChunks;
}

@Declare
public Set<Long> getChunksToUnloadSet() {
return chunksToUnloadSet;
}

public Object getLock(int x, int z) {
long hash = hash(x, z);
Object lock = chunkLoadLocks.get(hash);
Expand Down
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
Expand Up @@ -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;
Expand Down
6 changes: 5 additions & 1 deletion src/common/me/nallar/tickthreading/util/TableFormatter.java
Expand Up @@ -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) {
Expand Down

2 comments on commit 0357b22

@Puremin0rez
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wondering - would Chunk GC interfere with TTs new chunk cache since it keeps x amount loaded away from a player?

@LunNova
Copy link
Member Author

@LunNova LunNova commented on 0357b22 Jan 21, 2013 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.