From 11567b13d3f893ffc5e35aef790b9dc592e855f5 Mon Sep 17 00:00:00 2001 From: Julian Krings Date: Tue, 18 Feb 2025 17:08:08 +0100 Subject: [PATCH] potentially fix chunk position bug --- .../core/nms/v1_20_R1/headless/Region.java | 18 ++++++++++--- .../nms/v1_20_R1/headless/RegionStorage.java | 27 ++++++++++++++++--- .../core/nms/v1_20_R2/headless/Region.java | 18 ++++++++++--- .../nms/v1_20_R2/headless/RegionStorage.java | 27 ++++++++++++++++--- .../core/nms/v1_20_R3/headless/Region.java | 18 ++++++++++--- .../nms/v1_20_R3/headless/RegionStorage.java | 27 ++++++++++++++++--- .../core/nms/v1_20_R4/headless/Region.java | 18 ++++++++++--- .../nms/v1_20_R4/headless/RegionStorage.java | 27 ++++++++++++++++--- .../core/nms/v1_21_R1/headless/Region.java | 18 ++++++++++--- .../nms/v1_21_R1/headless/RegionStorage.java | 27 ++++++++++++++++--- .../core/nms/v1_21_R2/headless/Region.java | 18 ++++++++++--- .../nms/v1_21_R2/headless/RegionStorage.java | 27 ++++++++++++++++--- .../core/nms/v1_21_R3/headless/Region.java | 18 ++++++++++--- .../nms/v1_21_R3/headless/RegionStorage.java | 27 ++++++++++++++++--- 14 files changed, 266 insertions(+), 49 deletions(-) diff --git a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/headless/Region.java b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/headless/Region.java index c237a2c08..d3cc08368 100644 --- a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/headless/Region.java +++ b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/headless/Region.java @@ -3,6 +3,7 @@ package com.volmit.iris.core.nms.v1_20_R1.headless; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.headless.IRegion; import com.volmit.iris.core.nms.headless.SerializableChunk; +import com.volmit.iris.util.math.M; import lombok.NonNull; import lombok.Synchronized; import net.minecraft.nbt.CompoundTag; @@ -15,12 +16,13 @@ import java.io.DataOutputStream; import java.io.IOException; import java.nio.file.Path; -class Region implements IRegion { +class Region implements IRegion, Comparable { private final RegionFile regionFile; transient long references; + transient long lastUsed; Region(Path path, Path folder) throws IOException { - this.regionFile = new RegionFile(path, folder, true); + this.regionFile = new RegionFile(path, folder, false); } @Override @@ -45,10 +47,15 @@ class Region implements IRegion { @Override public void close() { --references; + lastUsed = M.ms(); + } + + public boolean unused() { + return references <= 0; } public boolean remove() { - if (references > 0) return false; + if (!unused()) return false; try { regionFile.close(); } catch (IOException e) { @@ -57,4 +64,9 @@ class Region implements IRegion { } return true; } + + @Override + public int compareTo(Region o) { + return Long.compare(lastUsed, o.lastUsed); + } } diff --git a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/headless/RegionStorage.java b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/headless/RegionStorage.java index 48da8a5a5..659fe5192 100644 --- a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/headless/RegionStorage.java +++ b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/headless/RegionStorage.java @@ -14,6 +14,7 @@ import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.context.ChunkContext; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.scheduling.J; import lombok.Getter; import lombok.NonNull; import net.minecraft.FileUtil; @@ -101,7 +102,7 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { @Override public boolean exists(int x, int z) { - try (IRegion region = getRegion(x, z, true)) { + try (IRegion region = getRegion(x >> 5, z >> 5, true)) { return region != null && region.exists(x, z); } catch (Exception e) { return false; @@ -112,9 +113,7 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { public IRegion getRegion(int x, int z, boolean existingOnly) throws IOException { AtomicReference exception = new AtomicReference<>(); Region region = regions.computeIfAbsent(Cache.key(x, z), k -> { - if (regions.size() >= 256) { - regions.values().removeIf(Region::remove); - } + trim(); try { FileUtil.createDirectoriesSafe(this.folder); @@ -158,6 +157,7 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { while (!regions.isEmpty()) { regions.values().removeIf(Region::remove); + J.sleep(1); } closed = true; @@ -165,6 +165,25 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { minecraftBiomes.clear(); } + private void trim() { + int size = regions.size(); + if (size < 256) return; + int remove = size - 255; + + var list = regions.values() + .stream() + .filter(Region::unused) + .sorted() + .collect(Collectors.toList()) + .reversed(); + + int skip = list.size() - remove; + if (skip > 0) list.subList(0, skip).clear(); + + if (list.isEmpty()) return; + regions.values().removeIf(r -> list.contains(r) && r.remove()); + } + private Holder getNoiseBiome(Engine engine, ChunkContext ctx, int x, int y, int z) { int m = y - engine.getMinHeight(); IrisBiome ib = ctx == null ? engine.getSurfaceBiome(x, z) : ctx.getBiome().get(x & 15, z & 15); diff --git a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/headless/Region.java b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/headless/Region.java index 086fdd9e6..c8d49bdf0 100644 --- a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/headless/Region.java +++ b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/headless/Region.java @@ -3,6 +3,7 @@ package com.volmit.iris.core.nms.v1_20_R2.headless; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.headless.IRegion; import com.volmit.iris.core.nms.headless.SerializableChunk; +import com.volmit.iris.util.math.M; import lombok.NonNull; import lombok.Synchronized; import net.minecraft.nbt.CompoundTag; @@ -15,12 +16,13 @@ import java.io.DataOutputStream; import java.io.IOException; import java.nio.file.Path; -class Region implements IRegion { +class Region implements IRegion, Comparable { private final RegionFile regionFile; transient long references; + transient long lastUsed; Region(Path path, Path folder) throws IOException { - this.regionFile = new RegionFile(path, folder, true); + this.regionFile = new RegionFile(path, folder, false); } @Override @@ -45,10 +47,15 @@ class Region implements IRegion { @Override public void close() { --references; + lastUsed = M.ms(); + } + + public boolean unused() { + return references <= 0; } public boolean remove() { - if (references > 0) return false; + if (!unused()) return false; try { regionFile.close(); } catch (IOException e) { @@ -57,4 +64,9 @@ class Region implements IRegion { } return true; } + + @Override + public int compareTo(Region o) { + return Long.compare(lastUsed, o.lastUsed); + } } diff --git a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/headless/RegionStorage.java b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/headless/RegionStorage.java index 7f0c02a94..ad267b7be 100644 --- a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/headless/RegionStorage.java +++ b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/headless/RegionStorage.java @@ -14,6 +14,7 @@ import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.context.ChunkContext; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.scheduling.J; import lombok.Getter; import lombok.NonNull; import net.minecraft.FileUtil; @@ -100,7 +101,7 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { @Override public boolean exists(int x, int z) { - try (IRegion region = getRegion(x, z, true)) { + try (IRegion region = getRegion(x >> 5, z >> 5, true)) { return region != null && region.exists(x, z); } catch (Exception e) { return false; @@ -111,9 +112,7 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { public IRegion getRegion(int x, int z, boolean existingOnly) throws IOException { AtomicReference exception = new AtomicReference<>(); Region region = regions.computeIfAbsent(Cache.key(x, z), k -> { - if (regions.size() >= 256) { - regions.values().removeIf(Region::remove); - } + trim(); try { FileUtil.createDirectoriesSafe(this.folder); @@ -157,6 +156,7 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { while (!regions.isEmpty()) { regions.values().removeIf(Region::remove); + J.sleep(1); } closed = true; @@ -164,6 +164,25 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { minecraftBiomes.clear(); } + private void trim() { + int size = regions.size(); + if (size < 256) return; + int remove = size - 255; + + var list = regions.values() + .stream() + .filter(Region::unused) + .sorted() + .collect(Collectors.toList()) + .reversed(); + + int skip = list.size() - remove; + if (skip > 0) list.subList(0, skip).clear(); + + if (list.isEmpty()) return; + regions.values().removeIf(r -> list.contains(r) && r.remove()); + } + private Holder getNoiseBiome(Engine engine, ChunkContext ctx, int x, int y, int z) { int m = y - engine.getMinHeight(); IrisBiome ib = ctx == null ? engine.getSurfaceBiome(x, z) : ctx.getBiome().get(x & 15, z & 15); diff --git a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/headless/Region.java b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/headless/Region.java index 5fcc557fc..a7dff95a1 100644 --- a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/headless/Region.java +++ b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/headless/Region.java @@ -3,6 +3,7 @@ package com.volmit.iris.core.nms.v1_20_R3.headless; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.headless.IRegion; import com.volmit.iris.core.nms.headless.SerializableChunk; +import com.volmit.iris.util.math.M; import lombok.NonNull; import lombok.Synchronized; import net.minecraft.nbt.CompoundTag; @@ -15,12 +16,13 @@ import java.io.DataOutputStream; import java.io.IOException; import java.nio.file.Path; -class Region implements IRegion { +class Region implements IRegion, Comparable { private final RegionFile regionFile; transient long references; + transient long lastUsed; Region(Path path, Path folder) throws IOException { - this.regionFile = new RegionFile(path, folder, true); + this.regionFile = new RegionFile(path, folder, false); } @Override @@ -45,10 +47,15 @@ class Region implements IRegion { @Override public void close() { --references; + lastUsed = M.ms(); + } + + public boolean unused() { + return references <= 0; } public boolean remove() { - if (references > 0) return false; + if (!unused()) return false; try { regionFile.close(); } catch (IOException e) { @@ -57,4 +64,9 @@ class Region implements IRegion { } return true; } + + @Override + public int compareTo(Region o) { + return Long.compare(lastUsed, o.lastUsed); + } } diff --git a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/headless/RegionStorage.java b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/headless/RegionStorage.java index 76b3d02c2..4124f34a3 100644 --- a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/headless/RegionStorage.java +++ b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/headless/RegionStorage.java @@ -14,6 +14,7 @@ import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.context.ChunkContext; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.scheduling.J; import lombok.Getter; import lombok.NonNull; import net.minecraft.FileUtil; @@ -100,7 +101,7 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { @Override public boolean exists(int x, int z) { - try (IRegion region = getRegion(x, z, true)) { + try (IRegion region = getRegion(x >> 5, z >> 5, true)) { return region != null && region.exists(x, z); } catch (Exception e) { return false; @@ -111,9 +112,7 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { public IRegion getRegion(int x, int z, boolean existingOnly) throws IOException { AtomicReference exception = new AtomicReference<>(); Region region = regions.computeIfAbsent(Cache.key(x, z), k -> { - if (regions.size() >= 256) { - regions.values().removeIf(Region::remove); - } + trim(); try { FileUtil.createDirectoriesSafe(this.folder); @@ -157,6 +156,7 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { while (!regions.isEmpty()) { regions.values().removeIf(Region::remove); + J.sleep(1); } closed = true; @@ -164,6 +164,25 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { minecraftBiomes.clear(); } + private void trim() { + int size = regions.size(); + if (size < 256) return; + int remove = size - 255; + + var list = regions.values() + .stream() + .filter(Region::unused) + .sorted() + .collect(Collectors.toList()) + .reversed(); + + int skip = list.size() - remove; + if (skip > 0) list.subList(0, skip).clear(); + + if (list.isEmpty()) return; + regions.values().removeIf(r -> list.contains(r) && r.remove()); + } + private Holder getNoiseBiome(Engine engine, ChunkContext ctx, int x, int y, int z) { int m = y - engine.getMinHeight(); IrisBiome ib = ctx == null ? engine.getSurfaceBiome(x, z) : ctx.getBiome().get(x & 15, z & 15); diff --git a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/headless/Region.java b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/headless/Region.java index 389cf7a99..bb1533c29 100644 --- a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/headless/Region.java +++ b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/headless/Region.java @@ -3,6 +3,7 @@ package com.volmit.iris.core.nms.v1_20_R4.headless; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.headless.IRegion; import com.volmit.iris.core.nms.headless.SerializableChunk; +import com.volmit.iris.util.math.M; import lombok.NonNull; import lombok.Synchronized; import net.minecraft.nbt.CompoundTag; @@ -17,13 +18,14 @@ import java.io.DataOutputStream; import java.io.IOException; import java.nio.file.Path; -class Region implements IRegion { +class Region implements IRegion, Comparable { private static final RegionStorageInfo info = new RegionStorageInfo("headless", Level.OVERWORLD, "headless"); private final RegionFile regionFile; transient long references; + transient long lastUsed; Region(Path path, Path folder) throws IOException { - this.regionFile = new RegionFile(info, path, folder, true); + this.regionFile = new RegionFile(info, path, folder, false); } @Override @@ -48,10 +50,15 @@ class Region implements IRegion { @Override public void close() { --references; + lastUsed = M.ms(); + } + + public boolean unused() { + return references <= 0; } public boolean remove() { - if (references > 0) return false; + if (!unused()) return false; try { regionFile.close(); } catch (IOException e) { @@ -60,4 +67,9 @@ class Region implements IRegion { } return true; } + + @Override + public int compareTo(Region o) { + return Long.compare(lastUsed, o.lastUsed); + } } diff --git a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/headless/RegionStorage.java b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/headless/RegionStorage.java index c6a609fd0..80dcb071d 100644 --- a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/headless/RegionStorage.java +++ b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/headless/RegionStorage.java @@ -14,6 +14,7 @@ import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.context.ChunkContext; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.scheduling.J; import lombok.Getter; import lombok.NonNull; import net.minecraft.FileUtil; @@ -100,7 +101,7 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { @Override public boolean exists(int x, int z) { - try (IRegion region = getRegion(x, z, true)) { + try (IRegion region = getRegion(x >> 5, z >> 5, true)) { return region != null && region.exists(x, z); } catch (Exception e) { return false; @@ -111,9 +112,7 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { public IRegion getRegion(int x, int z, boolean existingOnly) throws IOException { AtomicReference exception = new AtomicReference<>(); Region region = regions.computeIfAbsent(Cache.key(x, z), k -> { - if (regions.size() >= 256) { - regions.values().removeIf(Region::remove); - } + trim(); try { FileUtil.createDirectoriesSafe(this.folder); @@ -157,6 +156,7 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { while (!regions.isEmpty()) { regions.values().removeIf(Region::remove); + J.sleep(1); } closed = true; @@ -164,6 +164,25 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { minecraftBiomes.clear(); } + private void trim() { + int size = regions.size(); + if (size < 256) return; + int remove = size - 255; + + var list = regions.values() + .stream() + .filter(Region::unused) + .sorted() + .collect(Collectors.toList()) + .reversed(); + + int skip = list.size() - remove; + if (skip > 0) list.subList(0, skip).clear(); + + if (list.isEmpty()) return; + regions.values().removeIf(r -> list.contains(r) && r.remove()); + } + private Holder getNoiseBiome(Engine engine, ChunkContext ctx, int x, int y, int z) { int m = y - engine.getMinHeight(); IrisBiome ib = ctx == null ? engine.getSurfaceBiome(x, z) : ctx.getBiome().get(x & 15, z & 15); diff --git a/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/headless/Region.java b/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/headless/Region.java index 0ffef6e35..8be20190b 100644 --- a/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/headless/Region.java +++ b/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/headless/Region.java @@ -3,6 +3,7 @@ package com.volmit.iris.core.nms.v1_21_R1.headless; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.headless.IRegion; import com.volmit.iris.core.nms.headless.SerializableChunk; +import com.volmit.iris.util.math.M; import lombok.NonNull; import lombok.Synchronized; import net.minecraft.nbt.CompoundTag; @@ -17,13 +18,14 @@ import java.io.DataOutputStream; import java.io.IOException; import java.nio.file.Path; -class Region implements IRegion { +class Region implements IRegion, Comparable { private static final RegionStorageInfo info = new RegionStorageInfo("headless", Level.OVERWORLD, "headless"); private final RegionFile regionFile; transient long references; + transient long lastUsed; Region(Path path, Path folder) throws IOException { - this.regionFile = new RegionFile(info, path, folder, true); + this.regionFile = new RegionFile(info, path, folder, false); } @Override @@ -48,10 +50,15 @@ class Region implements IRegion { @Override public void close() { --references; + lastUsed = M.ms(); + } + + public boolean unused() { + return references <= 0; } public boolean remove() { - if (references > 0) return false; + if (!unused()) return false; try { regionFile.close(); } catch (IOException e) { @@ -60,4 +67,9 @@ class Region implements IRegion { } return true; } + + @Override + public int compareTo(Region o) { + return Long.compare(lastUsed, o.lastUsed); + } } diff --git a/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/headless/RegionStorage.java b/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/headless/RegionStorage.java index 35237c522..b97f3def3 100644 --- a/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/headless/RegionStorage.java +++ b/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/headless/RegionStorage.java @@ -14,6 +14,7 @@ import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.context.ChunkContext; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.scheduling.J; import lombok.Getter; import lombok.NonNull; import net.minecraft.FileUtil; @@ -96,7 +97,7 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { @Override public boolean exists(int x, int z) { - try (IRegion region = getRegion(x, z, true)) { + try (IRegion region = getRegion(x >> 5, z >> 5, true)) { return region != null && region.exists(x, z); } catch (Exception e) { return false; @@ -107,9 +108,7 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { public IRegion getRegion(int x, int z, boolean existingOnly) throws IOException { AtomicReference exception = new AtomicReference<>(); Region region = regions.computeIfAbsent(Cache.key(x, z), k -> { - if (regions.size() >= 256) { - regions.values().removeIf(Region::remove); - } + trim(); try { FileUtil.createDirectoriesSafe(this.folder); @@ -153,6 +152,7 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { while (!regions.isEmpty()) { regions.values().removeIf(Region::remove); + J.sleep(1); } closed = true; @@ -160,6 +160,25 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { minecraftBiomes.clear(); } + private void trim() { + int size = regions.size(); + if (size < 256) return; + int remove = size - 255; + + var list = regions.values() + .stream() + .filter(Region::unused) + .sorted() + .collect(Collectors.toList()) + .reversed(); + + int skip = list.size() - remove; + if (skip > 0) list.subList(0, skip).clear(); + + if (list.isEmpty()) return; + regions.values().removeIf(r -> list.contains(r) && r.remove()); + } + private Holder getNoiseBiome(Engine engine, ChunkContext ctx, int x, int y, int z) { int m = y - engine.getMinHeight(); IrisBiome ib = ctx == null ? engine.getSurfaceBiome(x, z) : ctx.getBiome().get(x & 15, z & 15); diff --git a/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/headless/Region.java b/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/headless/Region.java index d9810252d..f32fbd662 100644 --- a/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/headless/Region.java +++ b/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/headless/Region.java @@ -3,6 +3,7 @@ package com.volmit.iris.core.nms.v1_21_R2.headless; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.headless.IRegion; import com.volmit.iris.core.nms.headless.SerializableChunk; +import com.volmit.iris.util.math.M; import lombok.NonNull; import lombok.Synchronized; import net.minecraft.nbt.CompoundTag; @@ -17,13 +18,14 @@ import java.io.DataOutputStream; import java.io.IOException; import java.nio.file.Path; -class Region implements IRegion { +class Region implements IRegion, Comparable { private static final RegionStorageInfo info = new RegionStorageInfo("headless", Level.OVERWORLD, "headless"); private final RegionFile regionFile; transient long references; + transient long lastUsed; Region(Path path, Path folder) throws IOException { - this.regionFile = new RegionFile(info, path, folder, true); + this.regionFile = new RegionFile(info, path, folder, false); } @Override @@ -48,10 +50,15 @@ class Region implements IRegion { @Override public void close() { --references; + lastUsed = M.ms(); + } + + public boolean unused() { + return references <= 0; } public boolean remove() { - if (references > 0) return false; + if (!unused()) return false; try { regionFile.close(); } catch (IOException e) { @@ -60,4 +67,9 @@ class Region implements IRegion { } return true; } + + @Override + public int compareTo(Region o) { + return Long.compare(lastUsed, o.lastUsed); + } } diff --git a/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/headless/RegionStorage.java b/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/headless/RegionStorage.java index 91c594ad7..6a2a0f09b 100644 --- a/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/headless/RegionStorage.java +++ b/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/headless/RegionStorage.java @@ -11,6 +11,7 @@ import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.context.ChunkContext; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.scheduling.J; import it.unimi.dsi.fastutil.shorts.ShortArrayList; import it.unimi.dsi.fastutil.shorts.ShortList; import lombok.Getter; @@ -93,7 +94,7 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { @Override public boolean exists(int x, int z) { - try (IRegion region = getRegion(x, z, true)) { + try (IRegion region = getRegion(x >> 5, z >> 5, true)) { return region != null && region.exists(x, z); } catch (Exception e) { return false; @@ -104,9 +105,7 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { public IRegion getRegion(int x, int z, boolean existingOnly) throws IOException { AtomicReference exception = new AtomicReference<>(); Region region = regions.computeIfAbsent(Cache.key(x, z), k -> { - if (regions.size() >= 256) { - regions.values().removeIf(Region::remove); - } + trim(); try { FileUtil.createDirectoriesSafe(this.folder); @@ -150,6 +149,7 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { while (!regions.isEmpty()) { regions.values().removeIf(Region::remove); + J.sleep(1); } closed = true; @@ -157,6 +157,25 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { minecraftBiomes.clear(); } + private void trim() { + int size = regions.size(); + if (size < 256) return; + int remove = size - 255; + + var list = regions.values() + .stream() + .filter(Region::unused) + .sorted() + .collect(Collectors.toList()) + .reversed(); + + int skip = list.size() - remove; + if (skip > 0) list.subList(0, skip).clear(); + + if (list.isEmpty()) return; + regions.values().removeIf(r -> list.contains(r) && r.remove()); + } + private Holder getNoiseBiome(Engine engine, ChunkContext ctx, int x, int y, int z) { int m = y - engine.getMinHeight(); IrisBiome ib = ctx == null ? engine.getSurfaceBiome(x, z) : ctx.getBiome().get(x & 15, z & 15); diff --git a/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/headless/Region.java b/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/headless/Region.java index 8758233c2..12bc6fcad 100644 --- a/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/headless/Region.java +++ b/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/headless/Region.java @@ -3,6 +3,7 @@ package com.volmit.iris.core.nms.v1_21_R3.headless; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.headless.IRegion; import com.volmit.iris.core.nms.headless.SerializableChunk; +import com.volmit.iris.util.math.M; import lombok.NonNull; import lombok.Synchronized; import net.minecraft.nbt.CompoundTag; @@ -17,13 +18,14 @@ import java.io.DataOutputStream; import java.io.IOException; import java.nio.file.Path; -class Region implements IRegion { +class Region implements IRegion, Comparable { private static final RegionStorageInfo info = new RegionStorageInfo("headless", Level.OVERWORLD, "headless"); private final RegionFile regionFile; transient long references; + transient long lastUsed; Region(Path path, Path folder) throws IOException { - this.regionFile = new RegionFile(info, path, folder, true); + this.regionFile = new RegionFile(info, path, folder, false); } @Override @@ -48,10 +50,15 @@ class Region implements IRegion { @Override public void close() { --references; + lastUsed = M.ms(); + } + + public boolean unused() { + return references <= 0; } public boolean remove() { - if (references > 0) return false; + if (!unused()) return false; try { regionFile.close(); } catch (IOException e) { @@ -60,4 +67,9 @@ class Region implements IRegion { } return true; } + + @Override + public int compareTo(Region o) { + return Long.compare(lastUsed, o.lastUsed); + } } diff --git a/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/headless/RegionStorage.java b/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/headless/RegionStorage.java index 83340c44f..4d4ac7ccc 100644 --- a/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/headless/RegionStorage.java +++ b/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/headless/RegionStorage.java @@ -11,6 +11,7 @@ import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.context.ChunkContext; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.scheduling.J; import it.unimi.dsi.fastutil.shorts.ShortArrayList; import it.unimi.dsi.fastutil.shorts.ShortList; import lombok.Getter; @@ -93,7 +94,7 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { @Override public boolean exists(int x, int z) { - try (IRegion region = getRegion(x, z, true)) { + try (IRegion region = getRegion(x >> 5, z >> 5, true)) { return region != null && region.exists(x, z); } catch (Exception e) { return false; @@ -104,9 +105,7 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { public IRegion getRegion(int x, int z, boolean existingOnly) throws IOException { AtomicReference exception = new AtomicReference<>(); Region region = regions.computeIfAbsent(Cache.key(x, z), k -> { - if (regions.size() >= 256) { - regions.values().removeIf(Region::remove); - } + trim(); try { FileUtil.createDirectoriesSafe(this.folder); @@ -150,6 +149,7 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { while (!regions.isEmpty()) { regions.values().removeIf(Region::remove); + J.sleep(1); } closed = true; @@ -157,6 +157,25 @@ public class RegionStorage implements IRegionStorage, LevelHeightAccessor { minecraftBiomes.clear(); } + private void trim() { + int size = regions.size(); + if (size < 256) return; + int remove = size - 255; + + var list = regions.values() + .stream() + .filter(Region::unused) + .sorted() + .collect(Collectors.toList()) + .reversed(); + + int skip = list.size() - remove; + if (skip > 0) list.subList(0, skip).clear(); + + if (list.isEmpty()) return; + regions.values().removeIf(r -> list.contains(r) && r.remove()); + } + private Holder getNoiseBiome(Engine engine, ChunkContext ctx, int x, int y, int z) { int m = y - engine.getMinHeight(); IrisBiome ib = ctx == null ? engine.getSurfaceBiome(x, z) : ctx.getBiome().get(x & 15, z & 15);