diff --git a/src/main/java/me/cortex/voxy/common/world/ActiveSectionTracker.java b/src/main/java/me/cortex/voxy/common/world/ActiveSectionTracker.java index a06a57ce..00f3aaf0 100644 --- a/src/main/java/me/cortex/voxy/common/world/ActiveSectionTracker.java +++ b/src/main/java/me/cortex/voxy/common/world/ActiveSectionTracker.java @@ -2,6 +2,9 @@ package me.cortex.voxy.common.world; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import me.cortex.voxy.common.util.VolatileHolder; +import me.cortex.voxy.common.world.other.Mapper; + +import java.util.Arrays; public class ActiveSectionTracker { //Deserialize into the supplied section, returns true on success, false on failure @@ -60,6 +63,10 @@ public class ActiveSectionTracker { section.release(); return null; } + if (status == 1) { + //We need to set the data to air as it is undefined state + Arrays.fill(section.data, Mapper.AIR); + } return section; } else { WorldSection section = null; diff --git a/src/main/java/me/cortex/voxy/common/world/WorldSection.java b/src/main/java/me/cortex/voxy/common/world/WorldSection.java index dfdce516..584a7cc7 100644 --- a/src/main/java/me/cortex/voxy/common/world/WorldSection.java +++ b/src/main/java/me/cortex/voxy/common/world/WorldSection.java @@ -1,20 +1,26 @@ package me.cortex.voxy.common.world; +import java.util.ArrayDeque; import java.util.Arrays; +import java.util.Deque; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; //Represents a loaded world section at a specific detail level // holds a 32x32x32 region of detail public final class WorldSection { + private static final int ARRAY_REUSE_CACHE_SIZE = 256; + private static final Deque ARRAY_REUSE_CACHE = new ArrayDeque<>(1024); + + public final int lvl; public final int x; public final int y; public final int z; public final long key; - long[] data; + long[] data = null; private final ActiveSectionTracker tracker; public final AtomicBoolean inSaveQueue = new AtomicBoolean(); @@ -29,7 +35,14 @@ public final class WorldSection { this.key = WorldEngine.getWorldSectionId(lvl, x, y, z); this.tracker = tracker; - this.data = new long[32*32*32]; + if (!ARRAY_REUSE_CACHE.isEmpty()) { + synchronized (ARRAY_REUSE_CACHE) { + this.data = ARRAY_REUSE_CACHE.poll(); + } + } + if (this.data == null) { + this.data = new long[32 * 32 * 32]; + } } @Override @@ -73,6 +86,11 @@ public final class WorldSection { } boolean isFreed = witness == 1; if (isFreed) { + if (ARRAY_REUSE_CACHE.size() < ARRAY_REUSE_CACHE_SIZE) { + synchronized (ARRAY_REUSE_CACHE) { + ARRAY_REUSE_CACHE.add(this.data); + } + } this.data = null; } return isFreed;