cache = value.get();
+ if (cache.trim(aggressive)) {
iter.remove();
continue;
}
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/SingleThreadQueueExtent.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/SingleThreadQueueExtent.java
index 31d2946b4..0622f26c9 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/SingleThreadQueueExtent.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/SingleThreadQueueExtent.java
@@ -1,41 +1,49 @@
package com.boydti.fawe.beta.implementation;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.boydti.fawe.Fawe;
import com.boydti.fawe.beta.IChunk;
import com.boydti.fawe.beta.IChunkGet;
+import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.beta.IQueueExtent;
+import com.boydti.fawe.beta.implementation.blocks.CharSetBlocks;
+import com.boydti.fawe.beta.implementation.holder.ChunkHolder;
import com.boydti.fawe.beta.implementation.holder.ReferenceChunk;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.MemUtil;
import com.google.common.util.concurrent.Futures;
+import com.sk89q.worldedit.extent.Extent;
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
+
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
-import java.util.function.Supplier;
/**
* Single threaded implementation for IQueueExtent (still abstract) - Does not implement creation of
* chunks (that has to implemented by the platform e.g. Bukkit)
*
- * This queue is reusable {@link #init(WorldChunkCache)}
+ * This queue is reusable {@link #init(IChunkCache)}
*/
public abstract class SingleThreadQueueExtent implements IQueueExtent {
- // Pool discarded chunks for reuse (can safely be cleared by another thread)
- private static final ConcurrentLinkedQueue CHUNK_POOL = new ConcurrentLinkedQueue<>();
+// // Pool discarded chunks for reuse (can safely be cleared by another thread)
+// private static final ConcurrentLinkedQueue CHUNK_POOL = new ConcurrentLinkedQueue<>();
// Chunks currently being queued / worked on
private final Long2ObjectLinkedOpenHashMap chunks = new Long2ObjectLinkedOpenHashMap<>();
- private WorldChunkCache cache;
+
+ private IChunkCache cacheGet;
+ private IChunkCache cacheSet;
+ private boolean initialized;
+
private Thread currentThread;
private ConcurrentLinkedQueue submissions = new ConcurrentLinkedQueue<>();
// Last access pointers
private IChunk lastChunk;
private long lastPair = Long.MAX_VALUE;
+ private boolean enabledQueue = true;
+
/**
* Safety check to ensure that the thread being used matches the one being initialized on. - Can
* be removed later
@@ -48,23 +56,42 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
}
@Override
- public IChunkGet getCachedGet(int x, int z, Supplier supplier) {
- return cache.get(MathMan.pairInt(x, z), supplier);
+ public void enableQueue() {
+ enabledQueue = true;
+ }
+
+ @Override
+ public void disableQueue() {
+ enabledQueue = false;
+ }
+
+ @Override
+ public IChunkGet getCachedGet(int x, int z) {
+ return cacheGet.get(x, z);
+ }
+
+ @Override
+ public IChunkSet getCachedSet(int x, int z) {
+ return cacheSet.get(x, z);
}
/**
* Resets the queue.
*/
protected synchronized void reset() {
+ if (!initialized) return;
checkThread();
- cache = null;
if (!chunks.isEmpty()) {
- CHUNK_POOL.addAll(chunks.values());
+ for (IChunk chunk : chunks.values()) {
+ chunk.recycle();
+ }
chunks.clear();
}
+ enabledQueue = true;
lastChunk = null;
lastPair = Long.MAX_VALUE;
currentThread = null;
+ initialized = false;
}
/**
@@ -73,17 +100,18 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
* @param cache
*/
@Override
- public synchronized void init(WorldChunkCache cache) {
- if (this.cache != null) {
- reset();
- }
+ public synchronized void init(Extent extent, IChunkCache get, IChunkCache set) {
+ reset();
currentThread = Thread.currentThread();
- checkNotNull(cache);
- this.cache = cache;
- }
-
- public void returnToPool(IChunk chunk) {
- CHUNK_POOL.add(chunk);
+ if (get == null) {
+ get = (x, z) -> { throw new UnsupportedOperationException(); };
+ }
+ if (set == null) {
+ set = (x, z) -> CharSetBlocks.newInstance();
+ }
+ this.cacheGet = get;
+ this.cacheSet = set;
+ initialized = true;
}
@Override
@@ -116,8 +144,9 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
*/
private > T submitUnchecked(IChunk chunk) {
if (chunk.isEmpty()) {
- CHUNK_POOL.add(chunk);
- return (T) (Future) Futures.immediateFuture(null);
+ chunk.recycle();
+ Future result = Futures.immediateFuture(null);
+ return (T) result;
}
if (Fawe.isMainThread()) {
@@ -130,7 +159,8 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
@Override
public synchronized boolean trim(boolean aggressive) {
// TODO trim individial chunk sections
- CHUNK_POOL.clear();
+ cacheGet.trim(aggressive);
+ cacheSet.trim(aggressive);
if (Thread.currentThread() == currentThread) {
lastChunk = null;
lastPair = Long.MAX_VALUE;
@@ -157,10 +187,7 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
* @return IChunk
*/
private IChunk poolOrCreate(int X, int Z) {
- IChunk next = CHUNK_POOL.poll();
- if (next == null) {
- next = create(false);
- }
+ IChunk next = create(false);
next.init(this, X, Z);
return next;
}
@@ -187,7 +214,7 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
checkThread();
final int size = chunks.size();
final boolean lowMem = MemUtil.isMemoryLimited();
- if (lowMem || size > Settings.IMP.QUEUE.TARGET_SIZE) {
+ if (enabledQueue && (lowMem || size > Settings.IMP.QUEUE.TARGET_SIZE)) {
chunk = chunks.removeFirst();
final Future future = submitUnchecked(chunk);
if (future != null && !future.isDone()) {
@@ -211,6 +238,11 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
return chunk;
}
+ @Override
+ public IChunk create(boolean isFull) {
+ return ChunkHolder.newInstance();
+ }
+
private void pollSubmissions(int targetSize, boolean aggressive) {
final int overflow = submissions.size() - targetSize;
if (aggressive) {
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/BitSetBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/BitSetBlocks.java
index 74498610a..02642433f 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/BitSetBlocks.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/BitSetBlocks.java
@@ -63,7 +63,7 @@ public class BitSetBlocks implements IChunkSet {
@Override
public char[] getArray(int layer) {
- char[] arr = FaweCache.SECTION_BITS_TO_CHAR.get();
+ char[] arr = FaweCache.IMP.SECTION_BITS_TO_CHAR.get();
MemBlockSet.IRow nullRowY = row.getRow(layer);
if (nullRowY instanceof MemBlockSet.RowY) {
char value = blockState.getOrdinalChar();
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharGetBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharGetBlocks.java
index 84b857470..2f3dfd368 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharGetBlocks.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharGetBlocks.java
@@ -6,6 +6,8 @@ import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypes;
+import java.util.concurrent.Future;
+
public abstract class CharGetBlocks extends CharBlocks implements IChunkGet {
@Override
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharSetBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharSetBlocks.java
index aff10f536..ee71ccf56 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharSetBlocks.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharSetBlocks.java
@@ -1,6 +1,8 @@
package com.boydti.fawe.beta.implementation.blocks;
+import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.IChunkSet;
+import com.boydti.fawe.config.Settings;
import com.boydti.fawe.util.MathMan;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.world.biome.BiomeType;
@@ -14,21 +16,21 @@ import java.util.Set;
import java.util.UUID;
public class CharSetBlocks extends CharBlocks implements IChunkSet {
+ private static FaweCache.Pool POOL = FaweCache.IMP.registerPool(CharSetBlocks.class, CharSetBlocks::new, Settings.IMP.QUEUE.POOL);
+ public static CharSetBlocks newInstance() {
+ return POOL.poll();
+ }
public BiomeType[] biomes;
public HashMap tiles;
public HashSet entities;
public HashSet entityRemoves;
- public CharSetBlocks(CharBlocks other) {
- super(other);
- if (other instanceof CharSetBlocks) {
-
- }
- }
-
- public CharSetBlocks() {
+ private CharSetBlocks() {}
+ @Override
+ public void recycle() {
+ POOL.offer(this);
}
@Override
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/holder/ChunkHolder.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/holder/ChunkHolder.java
index a8a08c5d4..d47808dd2 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/holder/ChunkHolder.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/holder/ChunkHolder.java
@@ -1,5 +1,6 @@
package com.boydti.fawe.beta.implementation.holder;
+import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.ChunkFilterBlock;
import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.FilterBlockMask;
@@ -10,19 +11,67 @@ import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.beta.implementation.SingleThreadQueueExtent;
import com.boydti.fawe.beta.implementation.blocks.CharSetBlocks;
+import com.boydti.fawe.config.Settings;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
+
+import java.util.concurrent.Future;
import java.util.function.Supplier;
import javax.annotation.Nullable;
/**
* An abstract {@link IChunk} class that implements basic get/set blocks
*/
-public abstract class ChunkHolder implements IChunk {
+public class ChunkHolder> implements IChunk {
+
+ private static FaweCache.Pool POOL = FaweCache.IMP.registerPool(ChunkHolder.class, ChunkHolder::new, Settings.IMP.QUEUE.POOL);
+
+ public static ChunkHolder newInstance() {
+ return POOL.poll();
+ }
+
+ private IChunkGet get;
+ private IChunkSet set;
+ private IBlockDelegate delegate;
+ private IQueueExtent extent;
+ private int chunkX;
+ private int chunkZ;
+
+ public ChunkHolder() {
+ this.delegate = NULL;
+ }
+
+ public void init(IBlockDelegate delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public void recycle() {
+ delegate = NULL;
+ }
+
+ public IBlockDelegate getDelegate() {
+ return delegate;
+ }
+
+ @Override
+ public IQueueExtent getQueue() {
+ return extent;
+ }
+
+ @Override
+ public boolean setTile(int x, int y, int z, CompoundTag tag) {
+ return false;
+ }
+
+ @Override
+ public char[] load(int layer) {
+ return getOrCreateGet().load(layer);
+ }
public static final IBlockDelegate BOTH = new IBlockDelegate() {
@Override
@@ -160,20 +209,6 @@ public abstract class ChunkHolder implements IChunk {
return chunk.getFullBlock(x, y, z);
}
};
- private IChunkGet get;
- private IChunkSet set;
- private IBlockDelegate delegate;
- private IQueueExtent extent;
- private int chunkX;
- private int chunkZ;
-
- public ChunkHolder() {
- this.delegate = NULL;
- }
-
- public ChunkHolder(IBlockDelegate delegate) {
- this.delegate = delegate;
- }
@Override
public void flood(Flood flood, FilterBlockMask mask, ChunkFilterBlock block) {
@@ -264,14 +299,6 @@ public abstract class ChunkHolder implements IChunk {
return set;
}
- /**
- * Create the settable part of this chunk (defaults to a char array)
- * @return
- */
- public IChunkSet createSet() {
- return new CharSetBlocks();
- }
-
/**
* Create a wrapped set object
* - The purpose of wrapping is to allow different extents to intercept / alter behavior
@@ -279,13 +306,7 @@ public abstract class ChunkHolder implements IChunk {
* @return
*/
private IChunkSet newWrappedSet() {
- if (extent instanceof SingleThreadQueueExtent) {
- IChunkSet newSet = extent.getCachedSet(chunkX, chunkZ, this::createSet);
- if (newSet != null) {
- return newSet;
- }
- }
- return createSet();
+ return extent.getCachedSet(chunkX, chunkZ);
}
/**
@@ -295,17 +316,9 @@ public abstract class ChunkHolder implements IChunk {
* @return
*/
private IChunkGet newWrappedGet() {
- if (extent instanceof SingleThreadQueueExtent) {
- IChunkGet newGet = extent.getCachedGet(chunkX, chunkZ, this::get);
- if (newGet != null) {
- return newGet;
- }
- }
- return get();
+ return extent.getCachedGet(chunkX, chunkZ);
}
- public abstract IChunkGet get();
-
@Override
public void init(IQueueExtent extent, int chunkX, int chunkZ) {
this.extent = extent;
@@ -320,6 +333,22 @@ public abstract class ChunkHolder implements IChunk {
get = null;
}
+ @Override
+ public synchronized T call() {
+ if (get != null && set != null) {
+ return getOrCreateGet().call(getOrCreateSet(), this::recycle);
+ }
+ return null;
+ }
+
+ @Override
+ public T call(IChunkSet set, Runnable finalize) {
+ if (get != null && set != null) {
+ return getOrCreateGet().call(set, finalize);
+ }
+ return null;
+ }
+
public IQueueExtent getExtent() {
return extent;
}
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/holder/DelegateChunk.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/holder/DelegateChunk.java
index 6c285b320..7a284df67 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/holder/DelegateChunk.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/holder/DelegateChunk.java
@@ -1,27 +1,29 @@
package com.boydti.fawe.beta.implementation.holder;
import com.boydti.fawe.beta.IChunk;
+import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.beta.IDelegateChunk;
+import com.sk89q.jnbt.CompoundTag;
+
+import java.util.concurrent.Future;
/**
* Implementation of IDelegateChunk
- *
- * @param
*/
-public class DelegateChunk implements IDelegateChunk {
+public class DelegateChunk implements IDelegateChunk {
- private T parent;
+ private U parent;
- public DelegateChunk(T parent) {
+ public DelegateChunk(U parent) {
this.parent = parent;
}
@Override
- public final T getParent() {
+ public final U getParent() {
return parent;
}
- public final void setParent(T parent) {
+ public final void setParent(U parent) {
this.parent = parent;
}
}
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/command/AnvilCommands.java b/worldedit-core/src/main/java/com/boydti/fawe/command/AnvilCommands.java
index 4b9fb7110..0401419d5 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/command/AnvilCommands.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/command/AnvilCommands.java
@@ -475,7 +475,7 @@ public class AnvilCommands {
// });
// if (useData) {
// for (long[] c : map) {
-// BaseBlock block = FaweCache.CACHE_BLOCK[(int) c[0]];
+// BaseBlock block = FaweCache.IMP.CACHE_BLOCK[(int) c[0]];
// String name = BlockType.fromID(block.getId()).getName();
// String str = String.format("%-7s (%.3f%%) %s #%d:%d",
// String.valueOf(c[1]),
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/config/Settings.java b/worldedit-core/src/main/java/com/boydti/fawe/config/Settings.java
index 82229b7bd..18a9b5e59 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/config/Settings.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/config/Settings.java
@@ -293,7 +293,13 @@ public class Settings extends Config {
" - Low values may result in FAWE waiting on requests to the main thread",
" - Higher values use more memory and isn't noticeably faster",
})
- public int PRELOAD_CHUNKS = 32;
+ public int PRELOAD_CHUNKS = 100000;
+
+ @Comment({
+ "If pooling is enabled (reduces GC, higher memory usage)",
+ " - Enable to improve performance at the expense of memory",
+ })
+ public boolean POOL = true;
@Comment({
"Discard edits which have been idle for a certain amount of time (ms)",
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/logging/LoggingChangeSet.java b/worldedit-core/src/main/java/com/boydti/fawe/logging/LoggingChangeSet.java
index 8ac50bbde..76809abb3 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/logging/LoggingChangeSet.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/logging/LoggingChangeSet.java
@@ -58,10 +58,10 @@ public class LoggingChangeSet extends AbstractDelegateChangeSet {
// loc.x = x;
// loc.y = y;
// loc.z = z;
-// oldBlock.id = FaweCache.getId(combinedId4DataFrom);
-// oldBlock.data = FaweCache.getData(combinedId4DataFrom);
-// newBlock.id = FaweCache.getId(combinedId4DataTo);
-// newBlock.data = FaweCache.getData(combinedId4DataTo);
+// oldBlock.id = FaweCache.IMP.getId(combinedId4DataFrom);
+// oldBlock.data = FaweCache.IMP.getData(combinedId4DataFrom);
+// newBlock.id = FaweCache.IMP.getId(combinedId4DataTo);
+// newBlock.data = FaweCache.IMP.getData(combinedId4DataTo);
// // Log to BlocksHub and parent
// api.logBlock(loc, player, world, oldBlock, newBlock);
parent.add(x, y, z, combinedId4DataFrom, combinedId4DataTo);
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/cfi/HeightMapMCAGenerator.java b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/cfi/HeightMapMCAGenerator.java
index 3d78a73fe..bb2c17763 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/cfi/HeightMapMCAGenerator.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/cfi/HeightMapMCAGenerator.java
@@ -1,7 +1,12 @@
package com.boydti.fawe.object.brush.visualization.cfi;
import com.boydti.fawe.Fawe;
+import com.boydti.fawe.FaweCache;
+import com.boydti.fawe.beta.IBlocks;
+import com.boydti.fawe.beta.IChunkGet;
+import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.beta.IQueueExtent;
+import com.boydti.fawe.beta.implementation.FallbackChunkGet;
import com.boydti.fawe.object.FaweInputStream;
import com.boydti.fawe.object.FaweOutputStream;
import com.boydti.fawe.object.FawePlayer;
@@ -44,6 +49,7 @@ import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.biome.BiomeTypes;
+import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockID;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
@@ -58,6 +64,7 @@ import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
+import java.util.concurrent.Future;
import java.util.concurrent.ThreadLocalRandom;
import javax.annotation.Nullable;
@@ -65,13 +72,6 @@ import javax.annotation.Nullable;
public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Drawable, VirtualWorld {
private final MutableBlockVector3 mutable = new MutableBlockVector3();
- private final ThreadLocal indexStore = new ThreadLocal() {
- @Override
- protected int[] initialValue() {
- return new int[256];
- }
- };
-
private final DifferentialBlockBuffer blocks;
protected final DifferentialArray heights;
protected final DifferentialArray biomes;
@@ -1571,7 +1571,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
int[] floor = this.floor.get();
int[] overlay = this.overlay != null ? this.overlay.get() : null;
try {
- int[] indexes = indexStore.get();
+ int[] indexes = FaweCache.IMP.INDEX_STORE.get();
int index;
int maxY = 0;
@@ -1902,12 +1902,6 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
}));
}
- @Override
- protected void finalize() throws Throwable {
- IterableThreadLocal.clean(indexStore);
- super.finalize();
- }
-
@Override
public int getMaxY() {
return 255;
@@ -1973,4 +1967,10 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
// TODO Auto-generated method stub
return null;
}
+
+ @Override
+ public IChunkGet get(int x, int z) {
+ Fawe.debug("Should not be using buffering with HMMG");
+ return new FallbackChunkGet(this, x, z);
+ }
}
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/cfi/WritableMCAChunk.java b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/cfi/WritableMCAChunk.java
index 6f681bd90..fbe06d76c 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/cfi/WritableMCAChunk.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/cfi/WritableMCAChunk.java
@@ -79,10 +79,10 @@ public class WritableMCAChunk {
}
public void write(NBTOutputStream nbtOut) throws IOException {
- int[] blockToPalette = FaweCache.BLOCK_TO_PALETTE.get();
- int[] paletteToBlock = FaweCache.PALETTE_TO_BLOCK.get();
- long[] blockstates = FaweCache.BLOCK_STATES.get();
- int[] blocksCopy = FaweCache.SECTION_BLOCKS.get();
+ int[] blockToPalette = FaweCache.IMP.BLOCK_TO_PALETTE.get();
+ int[] paletteToBlock = FaweCache.IMP.PALETTE_TO_BLOCK.get();
+ long[] blockstates = FaweCache.IMP.BLOCK_STATES.get();
+ int[] blocksCopy = FaweCache.IMP.SECTION_BLOCKS.get();
nbtOut.writeNamedTagName("", NBTConstants.TYPE_COMPOUND);
nbtOut.writeNamedTag("DataVersion", 1631);
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java
index 6b4b3995f..dc0d27592 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java
@@ -52,7 +52,7 @@ public abstract class FaweChangeSet implements ChangeSet {
public FaweChangeSet(String world) {
this.worldName = world;
this.mainThread = Fawe.get() == null || Fawe.isMainThread();
- this.layers = FaweCache.CHUNK_LAYERS;
+ this.layers = FaweCache.IMP.CHUNK_LAYERS;
}
public FaweChangeSet(World world) {
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/remap/ClipboardRemapper.java b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/remap/ClipboardRemapper.java
index df9d21db7..e2c00c8e5 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/remap/ClipboardRemapper.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/remap/ClipboardRemapper.java
@@ -223,7 +223,7 @@ public class ClipboardRemapper {
// String name = entry.getKey();
// int id = value.get("id").getAsInt();
// int data = value.get("data").getAsInt();
-// int combined = FaweCache.getCombined(id, data);
+// int combined = FaweCache.IMP.getCombined(id, data);
// map.putIfAbsent(name, new ArrayList<>());
// map.get(name).add(combined);
// }
@@ -496,7 +496,7 @@ public class ClipboardRemapper {
// int combined = block.getCombined();
// if (remap[combined]) {
// char value = remapCombined[combined];
-// BaseBlock newBlock = FaweCache.CACHE_BLOCK[value];
+// BaseBlock newBlock = FaweCache.IMP.CACHE_BLOCK[value];
// newBlock.setNbtData(block.getNbtData());
// return newBlock;
// }
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/collection/ByteStore.java b/worldedit-core/src/main/java/com/boydti/fawe/object/collection/ByteStore.java
deleted file mode 100644
index 81671782f..000000000
--- a/worldedit-core/src/main/java/com/boydti/fawe/object/collection/ByteStore.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.boydti.fawe.object.collection;
-
-public class ByteStore extends IterableThreadLocal {
- private final int size;
-
- public ByteStore(int size) {
- this.size = size;
- }
-
- @Override
- public byte[] init() {
- return new byte[size];
- }
-}
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/collection/IterableThreadLocal.java b/worldedit-core/src/main/java/com/boydti/fawe/object/collection/IterableThreadLocal.java
index 2aef7daf7..eaa4fe297 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/object/collection/IterableThreadLocal.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/object/collection/IterableThreadLocal.java
@@ -1,5 +1,6 @@
package com.boydti.fawe.object.collection;
+import com.boydti.fawe.util.IOUtil;
import com.boydti.fawe.util.MainUtil;
import java.lang.ref.Reference;
import java.lang.reflect.Array;
@@ -8,12 +9,27 @@ import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
+import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.IntFunction;
+import java.util.function.Supplier;
-public abstract class IterableThreadLocal extends ThreadLocal implements Iterable {
+public class IterableThreadLocal extends ThreadLocal implements Iterable {
private final ConcurrentLinkedDeque allValues = new ConcurrentLinkedDeque<>();
+ private final Supplier supplier;
- public IterableThreadLocal() {
+ public IterableThreadLocal(Supplier supplier) {
+ this.supplier = supplier;
+ }
+
+ public IterableThreadLocal(Supplier supplier, Function modifier) {
+ this.supplier = supplier;
+ }
+
+ public IterableThreadLocal(Supplier