diff --git a/src/main/java/net/minecraft/world/chunk/storage/AnvilChunkLoader.java b/src/main/java/net/minecraft/world/chunk/storage/AnvilChunkLoader.java index e932d29..5cb698b 100644 --- a/src/main/java/net/minecraft/world/chunk/storage/AnvilChunkLoader.java +++ b/src/main/java/net/minecraft/world/chunk/storage/AnvilChunkLoader.java @@ -1,13 +1,12 @@ package net.minecraft.world.chunk.storage; -import gnu.trove.iterator.TIntObjectIterator; -import gnu.trove.map.hash.TIntObjectHashMap; - import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.Iterator; +import java.util.List; import java.util.Set; import net.minecraft.block.Block; @@ -26,19 +25,25 @@ import net.minecraft.world.storage.ThreadedFileIOBase; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.world.ChunkDataEvent; +import net.openhft.koloboke.collect.map.IntObjCursor; +import net.openhft.koloboke.collect.map.IntObjMap; +import net.openhft.koloboke.collect.map.hash.HashIntObjMaps; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.ultramine.server.chunk.ChunkHash; import org.ultramine.server.chunk.PendingBlockUpdate; +import org.ultramine.server.util.VanillaChunkCoordIntPairSet; import cpw.mods.fml.common.FMLLog; public class AnvilChunkLoader implements IChunkLoader, IThreadedFileIO { private static final Logger logger = LogManager.getLogger(); - protected final TIntObjectHashMap pendingSaves = new TIntObjectHashMap(); + protected final IntObjMap pendingSaves = HashIntObjMaps.newMutableMap(); + private final List chunksToRemove = new ArrayList(); //mods compatibility + private final Set pendingAnvilChunksCoordinates = new VanillaChunkCoordIntPairSet(pendingSaves.keySet()); //mods compatibility protected Object syncLockObject = new Object(); public File chunkSaveLocation; private static final String __OBFID = "CL_00000384"; @@ -52,7 +57,7 @@ { synchronized(syncLockObject) { - if (pendingSaves.contains(ChunkHash.chunkToKey(i, j))) + if (pendingSaves.containsKey(ChunkHash.chunkToKey(i, j))) return true; } @@ -212,7 +217,17 @@ int hash = ChunkHash.chunkToKey(par1ChunkCoordIntPair.chunkXPos, par1ChunkCoordIntPair.chunkZPos); - pendingSaves.put(hash, new PendingChunk(par1ChunkCoordIntPair, par2NBTTagCompound)); + PendingChunk pendingChunk = new PendingChunk(par1ChunkCoordIntPair, par2NBTTagCompound); + if(pendingSaves.put(hash, pendingChunk) != null) + { + for(int i = 0, s = chunksToRemove.size(); i < s; i++) + if(chunksToRemove.get(i).chunkCoordinate.equals(par1ChunkCoordIntPair)) + { + chunksToRemove.set(i, pendingChunk); + return; + } + } + chunksToRemove.add(pendingChunk); //this.pendingAnvilChunksCoordinates.add(par1ChunkCoordIntPair); ThreadedFileIOBase.threadedIOInstance.queueIO(this); } @@ -231,8 +246,8 @@ return false; } - TIntObjectIterator it = pendingSaves.iterator(); - it.advance(); + IntObjCursor it = pendingSaves.cursor(); + it.moveNext(); pendingchunk = it.value(); key = it.key(); } @@ -251,6 +266,7 @@ synchronized (this.syncLockObject) { pendingSaves.remove(key); + chunksToRemove.remove(pendingchunk); } } @@ -545,6 +561,7 @@ synchronized(syncLockObject) { pendingSaves.clear(); + chunksToRemove.clear(); } } diff --git a/src/main/java/org/ultramine/server/util/VanillaChunkCoordIntPairSet.java b/src/main/java/org/ultramine/server/util/VanillaChunkCoordIntPairSet.java new file mode 100644 index 0000000..4fd7589 --- /dev/null +++ b/src/main/java/org/ultramine/server/util/VanillaChunkCoordIntPairSet.java @@ -0,0 +1,148 @@ +package org.ultramine.server.util; + +import java.lang.reflect.Array; +import java.util.Collection; +import java.util.Iterator; +import java.util.Set; + +import org.ultramine.server.chunk.ChunkHash; + +import com.google.common.collect.Iterators; + +import net.minecraft.world.ChunkCoordIntPair; +import net.openhft.koloboke.collect.set.IntSet; + +public class VanillaChunkCoordIntPairSet implements Set +{ + private final IntSet intset; + + public VanillaChunkCoordIntPairSet(IntSet intset) + { + this.intset = intset; + } + + private static int v2um(ChunkCoordIntPair coord) + { + return ChunkHash.chunkToKey(coord.chunkXPos, coord.chunkZPos); + } + + private static ChunkCoordIntPair um2v(int key) + { + return new ChunkCoordIntPair(ChunkHash.keyToX(key), ChunkHash.keyToZ(key)); + } + + @Override + public int size() + { + return intset.size(); + } + + @Override + public boolean isEmpty() + { + return intset.isEmpty(); + } + + @Override + public boolean contains(Object o) + { + return o instanceof ChunkCoordIntPair && contains((ChunkCoordIntPair)o); + } + + public boolean contains(ChunkCoordIntPair coord) + { + return intset.contains(v2um(coord)); + } + + @Override + @SuppressWarnings("deprecation") + public Iterator iterator() + { + return Iterators.transform(intset.iterator(), (Integer key) -> um2v(key)); + } + + @Override + public Object[] toArray() + { + return toArray(new ChunkCoordIntPair[size()]); + } + + @Override + @SuppressWarnings("unchecked") + public T[] toArray(T[] a) + { + int size = size(); + ChunkCoordIntPair[] r = a.length >= size() ? (ChunkCoordIntPair[]) a : (ChunkCoordIntPair[]) Array.newInstance(a.getClass().getComponentType(), size); + int i = 0; + for(ChunkCoordIntPair coord : this) + r[i++] = coord; + return (T[]) r; + } + + @Override + public boolean add(ChunkCoordIntPair e) + { + return intset.add(v2um(e)); + } + + @Override + public boolean remove(Object o) + { + return o instanceof ChunkCoordIntPair && remove((ChunkCoordIntPair)o); + } + + public boolean remove(ChunkCoordIntPair coord) + { + return intset.removeInt(v2um(coord)); + } + + @Override + public boolean containsAll(Collection c) + { + for(Object o : c) + if(!contains(o)) + return false; + return true; + } + + @Override + public boolean addAll(Collection c) + { + boolean modified = false; + for(Object o : c) + modified |= add((ChunkCoordIntPair)o); + return modified; + } + + @Override + public boolean retainAll(Collection c) + { + boolean modified = false; + for(Iterator it = iterator(); it.hasNext();) + { + ChunkCoordIntPair coord = it.next(); + if(!c.contains(coord)) + { + it.remove(); + modified = true; + } + } + + return modified; + } + + @Override + public boolean removeAll(Collection c) + { + boolean modified = false; + for(Object o : c) + modified |= remove(o); + return modified; + } + + @Override + public void clear() + { + intset.clear(); + } +}