diff --git a/src/main/java/net/minecraft/world/gen/ChunkProviderServer.java b/src/main/java/net/minecraft/world/gen/ChunkProviderServer.java index 9a5fe91..a911cad 100644 --- a/src/main/java/net/minecraft/world/gen/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/world/gen/ChunkProviderServer.java @@ -38,6 +38,7 @@ import org.apache.logging.log4j.Logger; import org.ultramine.server.chunk.ChunkHash; import org.ultramine.server.chunk.ChunkIOExecutor; +import org.ultramine.server.chunk.ChunkMap; public class ChunkProviderServer implements IChunkProvider { @@ -47,7 +48,7 @@ public IChunkProvider currentChunkProvider; public IChunkLoader currentChunkLoader; public boolean loadChunkOnProvideRequest = true; - public TIntObjectMap loadedChunkHashMap = new TIntObjectHashMap(); + public ChunkMap loadedChunkHashMap = new ChunkMap(); public WorldServer worldObj; private static final String __OBFID = "CL_00001436"; @@ -61,7 +62,7 @@ public boolean chunkExists(int par1, int par2) { - return this.loadedChunkHashMap.containsKey(ChunkHash.chunkToKey(par1, par2)); + return this.loadedChunkHashMap.contains(par1, par2); } public void unloadChunksIfNotNearSpawn(int par1, int par2) @@ -99,12 +100,12 @@ { int k = ChunkHash.chunkToKey(par1, par2); this.chunksToUnload.remove(k); - Chunk chunk = (Chunk)this.loadedChunkHashMap.get(k); + Chunk chunk = (Chunk)this.loadedChunkHashMap.get(par1, par2); if (chunk == null) { - chunk = ForgeChunkManager.fetchDormantChunk(k, this.worldObj); - if (chunk == null) +// chunk = ForgeChunkManager.fetchDormantChunk(k, this.worldObj); +// if (chunk == null) { chunk = this.safeLoadChunk(par1, par2); } @@ -133,7 +134,7 @@ } } - this.loadedChunkHashMap.put(k, chunk); + this.loadedChunkHashMap.put(par1, par2, chunk); chunk.onChunkLoad(); chunk.populateChunk(this, this, par1, par2); chunk.func_150804_b(false); @@ -144,7 +145,7 @@ public Chunk provideChunk(int par1, int par2) { - Chunk chunk = this.loadedChunkHashMap.get(ChunkHash.chunkToKey(par1, par2)); + Chunk chunk = this.loadedChunkHashMap.get(par1, par2); return chunk == null ? (!this.worldObj.findingSpawnPoint && !this.loadChunkOnProvideRequest ? this.defaultEmptyChunk : this.loadChunk(par1, par2)) : chunk; } @@ -368,7 +369,7 @@ public void loadAsync(int x, int z, Runnable callback) //XXX { - if(loadedChunkHashMap.containsKey(ChunkHash.chunkToKey(x, z))) + if(loadedChunkHashMap.contains(x, z)) { callback.run(); return; @@ -381,6 +382,6 @@ public Chunk getChunkIfExists(int cx, int cz) { - return loadedChunkHashMap.get(ChunkHash.chunkToKey(cx, cz)); + return loadedChunkHashMap.get(cx, cz); } } \ No newline at end of file diff --git a/src/main/java/org/ultramine/server/chunk/ChunkIOProvider.java b/src/main/java/org/ultramine/server/chunk/ChunkIOProvider.java index 4ad4667..407b4f4 100644 --- a/src/main/java/org/ultramine/server/chunk/ChunkIOProvider.java +++ b/src/main/java/org/ultramine/server/chunk/ChunkIOProvider.java @@ -42,7 +42,7 @@ // See if someone already loaded this chunk while we were working on it // (API, etc) - if(queuedChunk.provider.loadedChunkHashMap.containsKey(queuedChunk.coords)) + if(queuedChunk.provider.loadedChunkHashMap.contains(queuedChunk.coords)) { // Make sure it isn't queued for unload, we need it queuedChunk.provider.chunksToUnload.remove(queuedChunk.coords); // Spigot diff --git a/src/main/java/org/ultramine/server/chunk/ChunkMap.java b/src/main/java/org/ultramine/server/chunk/ChunkMap.java new file mode 100644 index 0000000..90d027f --- /dev/null +++ b/src/main/java/org/ultramine/server/chunk/ChunkMap.java @@ -0,0 +1,149 @@ +package org.ultramine.server.chunk; + +import java.util.Collection; + +import net.minecraft.world.chunk.Chunk; + +import org.ultramine.server.chunk.ChunkHash; + +import gnu.trove.iterator.TIntObjectIterator; +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.TIntObjectHashMap; + +public class ChunkMap +{ + private static final int FLAT_LOOKUP_SIZE = 512; + private static final int FLAT_MAP_SIZE = FLAT_LOOKUP_SIZE*2; + + private final Chunk[] flatMap = new Chunk[FLAT_MAP_SIZE*FLAT_MAP_SIZE]; + + private final TIntObjectMap map = new TIntObjectHashMap(); + + public void put(int x, int z, Chunk chunk) + { + put(x, z, ChunkHash.chunkToKey(x, z), chunk); + } + + public void put(int hash, Chunk chunk) + { + put(ChunkHash.keyToX(hash), ChunkHash.keyToZ(hash), hash, chunk); + } + + public Chunk get(int x, int z) + { + if(isFlatMapable(x, z)) + { + return getFlat(x, z); + } + + return map.get(ChunkHash.chunkToKey(x, z)); + } + + public Chunk get(int hash) + { + int x = ChunkHash.keyToX(hash); + int z = ChunkHash.keyToZ(hash); + + if(isFlatMapable(x, z)) + { + return getFlat(x, z); + } + + return map.get(hash); + } + + public Chunk remove(int x, int z) + { + if(isFlatMapable(x, z)) + { + removeFlat(x, z); + } + + return map.remove(ChunkHash.chunkToKey(x, z)); + } + + public Chunk remove(int hash) + { + int x = ChunkHash.keyToX(hash); + int z = ChunkHash.keyToZ(hash); + + if(isFlatMapable(x, z)) + { + removeFlat(x, z); + } + + return map.remove(hash); + } + + public boolean contains(int x, int z) + { + if(isFlatMapable(x, z)) + { + return containsFlat(x, z); + } + + return map.containsKey(ChunkHash.chunkToKey(x, z)); + } + + public boolean contains(int hash) + { + return map.containsKey(hash); + } + + public TIntObjectIterator iterator() + { + return map.iterator(); + } + + public Collection valueCollection() + { + return map.valueCollection(); + } + + public int size() + { + return map.size(); + } + + + + private void put(int x, int z, int hash, Chunk chunk) + { + if(isFlatMapable(x, z)) + { + putFlat(x, z, chunk); + } + + map.put(hash, chunk); + } + + private boolean isFlatMapable(int x, int z) + { + return Math.abs(x) < FLAT_LOOKUP_SIZE && Math.abs(z) < FLAT_LOOKUP_SIZE; + } + + private int getFlatIndex(int x, int z) + { + return (x + FLAT_LOOKUP_SIZE)*FLAT_MAP_SIZE + (z + FLAT_LOOKUP_SIZE); + } + + private void putFlat(int x, int z, Chunk chunk) + { + flatMap[getFlatIndex(x, z)] = chunk; + } + + private Chunk getFlat(int x, int z) + { + return flatMap[getFlatIndex(x, z)]; + } + + private void removeFlat(int x, int z) + { + flatMap[getFlatIndex(x, z)] = null; + } + + private boolean containsFlat(int x, int z) + { + return flatMap[getFlatIndex(x, z)] != null; + } +}