From f73c4debf17105e16446761594dadfb15e844eaa Mon Sep 17 00:00:00 2001 From: SirYwell Date: Wed, 15 Jan 2025 19:21:23 +0100 Subject: [PATCH 1/2] Improve BiomeMask performance --- .../v1_20_R2/PaperweightPlatformAdapter.java | 9 ++++--- .../v1_20_R3/PaperweightPlatformAdapter.java | 9 ++++--- .../v1_20_R4/PaperweightPlatformAdapter.java | 9 ++++--- .../v1_21_R1/PaperweightPlatformAdapter.java | 9 ++++--- .../v1_21_3/PaperweightPlatformAdapter.java | 9 ++++--- .../v1_21_4/PaperweightPlatformAdapter.java | 9 ++++--- .../worldedit/function/mask/BiomeMask.java | 26 ++++++++++++------- .../worldedit/world/biome/BiomeTypes.java | 17 +++++++++--- 8 files changed, 61 insertions(+), 36 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java index 99f52e4feb..d293b75e0c 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java @@ -652,11 +652,12 @@ public static void clearCounts(final LevelChunkSection section) throws IllegalAc public static BiomeType adapt(Holder biome, LevelAccessor levelAccessor) { final Registry biomeRegistry = levelAccessor.registryAccess().registryOrThrow(BIOME); - if (biomeRegistry.getKey(biome.value()) == null) { - return biomeRegistry.asHolderIdMap().getId(biome) == -1 ? BiomeTypes.OCEAN - : null; + final int id = biomeRegistry.getId(biome.value()); + if (id < 0) { + // this shouldn't be the case, but other plugins can be weird + return BiomeTypes.OCEAN; } - return BiomeTypes.get(biome.unwrapKey().orElseThrow().location().toString()); + return BiomeTypes.getLegacy(id); } static void removeBeacon(BlockEntity beacon, LevelChunk levelChunk) { diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java index 1ff6819638..2de8159e6c 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java @@ -652,11 +652,12 @@ public static void clearCounts(final LevelChunkSection section) throws IllegalAc public static BiomeType adapt(Holder biome, LevelAccessor levelAccessor) { final Registry biomeRegistry = levelAccessor.registryAccess().registryOrThrow(BIOME); - if (biomeRegistry.getKey(biome.value()) == null) { - return biomeRegistry.asHolderIdMap().getId(biome) == -1 ? BiomeTypes.OCEAN - : null; + final int id = biomeRegistry.getId(biome.value()); + if (id < 0) { + // this shouldn't be the case, but other plugins can be weird + return BiomeTypes.OCEAN; } - return BiomeTypes.get(biome.unwrapKey().orElseThrow().location().toString()); + return BiomeTypes.getLegacy(id); } static void removeBeacon(BlockEntity beacon, LevelChunk levelChunk) { diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java index 3ddfbc6fbf..e4489bedc7 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java @@ -645,11 +645,12 @@ public static void clearCounts(final LevelChunkSection section) throws IllegalAc public static BiomeType adapt(Holder biome, LevelAccessor levelAccessor) { final Registry biomeRegistry = levelAccessor.registryAccess().registryOrThrow(BIOME); - if (biomeRegistry.getKey(biome.value()) == null) { - return biomeRegistry.asHolderIdMap().getId(biome) == -1 ? BiomeTypes.OCEAN - : null; + final int id = biomeRegistry.getId(biome.value()); + if (id < 0) { + // this shouldn't be the case, but other plugins can be weird + return BiomeTypes.OCEAN; } - return BiomeTypes.get(biome.unwrapKey().orElseThrow().location().toString()); + return BiomeTypes.getLegacy(id); } static void removeBeacon(BlockEntity beacon, LevelChunk levelChunk) { diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlatformAdapter.java index 6881ea4e24..2d1c16fb1c 100644 --- a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlatformAdapter.java @@ -629,11 +629,12 @@ public static void clearCounts(final LevelChunkSection section) throws IllegalAc public static BiomeType adapt(Holder biome, LevelAccessor levelAccessor) { final Registry biomeRegistry = levelAccessor.registryAccess().registryOrThrow(BIOME); - if (biomeRegistry.getKey(biome.value()) == null) { - return biomeRegistry.asHolderIdMap().getId(biome) == -1 ? BiomeTypes.OCEAN - : null; + final int id = biomeRegistry.getId(biome.value()); + if (id < 0) { + // this shouldn't be the case, but other plugins can be weird + return BiomeTypes.OCEAN; } - return BiomeTypes.get(biome.unwrapKey().orElseThrow().location().toString()); + return BiomeTypes.getLegacy(id); } static void removeBeacon(BlockEntity beacon, LevelChunk levelChunk) { diff --git a/worldedit-bukkit/adapters/adapter-1_21_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_3/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_21_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_3/PaperweightPlatformAdapter.java index 3bd0f5fb5a..0fc453e416 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_3/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_21_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_3/PaperweightPlatformAdapter.java @@ -636,11 +636,12 @@ public static void clearCounts(final LevelChunkSection section) throws IllegalAc public static BiomeType adapt(Holder biome, LevelAccessor levelAccessor) { final Registry biomeRegistry = levelAccessor.registryAccess().lookupOrThrow(BIOME); - if (biomeRegistry.getKey(biome.value()) == null) { - return biomeRegistry.asHolderIdMap().getId(biome) == -1 ? BiomeTypes.OCEAN - : null; + final int id = biomeRegistry.getId(biome.value()); + if (id < 0) { + // this shouldn't be the case, but other plugins can be weird + return BiomeTypes.OCEAN; } - return BiomeTypes.get(biome.unwrapKey().orElseThrow().location().toString()); + return BiomeTypes.getLegacy(id); } static void removeBeacon(BlockEntity beacon, LevelChunk levelChunk) { diff --git a/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightPlatformAdapter.java index c5f896da0c..f8e0f2d7e0 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightPlatformAdapter.java @@ -631,11 +631,12 @@ public static void clearCounts(final LevelChunkSection section) throws IllegalAc public static BiomeType adapt(Holder biome, LevelAccessor levelAccessor) { final Registry biomeRegistry = levelAccessor.registryAccess().lookupOrThrow(BIOME); - if (biomeRegistry.getKey(biome.value()) == null) { - return biomeRegistry.asHolderIdMap().getId(biome) == -1 ? BiomeTypes.OCEAN - : null; + final int id = biomeRegistry.getId(biome.value()); + if (id < 0) { + // this shouldn't be the case, but other plugins can be weird + return BiomeTypes.OCEAN; } - return BiomeTypes.get(biome.unwrapKey().orElseThrow().location().toString()); + return BiomeTypes.getLegacy(id); } static void removeBeacon(BlockEntity beacon, LevelChunk levelChunk) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BiomeMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BiomeMask.java index ab919b35f5..d0593149c4 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BiomeMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BiomeMask.java @@ -26,8 +26,6 @@ import javax.annotation.Nullable; import java.util.Arrays; import java.util.Collection; -import java.util.HashSet; -import java.util.Set; import static com.google.common.base.Preconditions.checkNotNull; @@ -38,7 +36,7 @@ public class BiomeMask extends AbstractExtentMask { //FAWE end - private final Set biomes = new HashSet<>(); + private final boolean[] biomes; /** * Create a new biome mask. @@ -51,7 +49,15 @@ public BiomeMask(Extent extent, Collection biomes) { super(extent); //FAWE end checkNotNull(biomes); - this.biomes.addAll(biomes); + this.biomes = new boolean[BiomeType.REGISTRY.size()]; + for (final BiomeType biome : biomes) { + this.biomes[biome.getInternalId()] = true; + } + } + + private BiomeMask(Extent extent, boolean[] biomes) { + super(extent); + this.biomes = biomes; } /** @@ -71,7 +77,9 @@ public BiomeMask(Extent extent, BiomeType... biome) { */ public void add(Collection biomes) { checkNotNull(biomes); - this.biomes.addAll(biomes); + for (final BiomeType biome : biomes) { + this.biomes[biome.getInternalId()] = true; + } } /** @@ -89,13 +97,13 @@ public void add(BiomeType... biome) { * @return a list of biomes */ public Collection getBiomes() { - return biomes; + return BiomeType.REGISTRY.values().stream().filter(type -> biomes[type.getInternalId()]).toList(); } @Override public boolean test(BlockVector3 vector) { BiomeType biome = vector.getBiome(getExtent()); - return biomes.contains(biome); + return biomes[biome.getInternalId()]; } @Nullable @@ -107,14 +115,14 @@ public Mask2D toMask2D() { //FAWE start @Override public Mask copy() { - return new BiomeMask(getExtent(), new HashSet<>(biomes)); + return new BiomeMask(getExtent(), this.biomes.clone()); } //FAWE end @Override public boolean test(Extent extent, BlockVector3 position) { BiomeType biome = getExtent().getBiome(position); - return biomes.contains(biome); + return biomes[biome.getInternalId()]; } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeTypes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeTypes.java index 2d8973c6a0..a402625001 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeTypes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeTypes.java @@ -20,7 +20,10 @@ package com.sk89q.worldedit.world.biome; import javax.annotation.Nullable; +import java.util.Arrays; import java.util.Collection; +import java.util.Comparator; +import java.util.List; /** * Stores a list of common {@link BiomeType BiomeTypes}. @@ -297,10 +300,18 @@ public static BiomeType register(final BiomeType biome) { } public static BiomeType getLegacy(int legacyId) { - for (BiomeType type : values()) { - if (type.getLegacyId() == legacyId) { - return type; + class BiomeTypeIdCache { + private static final List byId = create(); + + private static List create() { + BiomeType[] array = values().toArray(new BiomeType[0]); + Arrays.sort(array, Comparator.comparing(BiomeType::getLegacyId)); + return List.of(array); } + + } + if (legacyId >= 0 && legacyId < BiomeTypeIdCache.byId.size()) { + return BiomeTypeIdCache.byId.get(legacyId); } return null; } From 3b4aeb392b88b9a18ad44741e3ef0c36e5b3d771 Mon Sep 17 00:00:00 2001 From: SirYwell Date: Wed, 15 Jan 2025 19:27:31 +0100 Subject: [PATCH 2/2] comments --- .../com/sk89q/worldedit/function/mask/BiomeMask.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BiomeMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BiomeMask.java index d0593149c4..3681101a27 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BiomeMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BiomeMask.java @@ -36,7 +36,9 @@ public class BiomeMask extends AbstractExtentMask { //FAWE end + //FAWE start - avoid HashSet usage private final boolean[] biomes; + //FAWE end /** * Create a new biome mask. @@ -49,10 +51,12 @@ public BiomeMask(Extent extent, Collection biomes) { super(extent); //FAWE end checkNotNull(biomes); + //FAWE start - avoid HashSet usage this.biomes = new boolean[BiomeType.REGISTRY.size()]; for (final BiomeType biome : biomes) { this.biomes[biome.getInternalId()] = true; } + //FAWE end } private BiomeMask(Extent extent, boolean[] biomes) { @@ -77,9 +81,11 @@ public BiomeMask(Extent extent, BiomeType... biome) { */ public void add(Collection biomes) { checkNotNull(biomes); + //FAWE start - avoid HashSet usage for (final BiomeType biome : biomes) { this.biomes[biome.getInternalId()] = true; } + //FAWE end } /** @@ -97,13 +103,17 @@ public void add(BiomeType... biome) { * @return a list of biomes */ public Collection getBiomes() { + //FAWE start - avoid HashSet usage return BiomeType.REGISTRY.values().stream().filter(type -> biomes[type.getInternalId()]).toList(); + //FAWE end } @Override public boolean test(BlockVector3 vector) { + //FAWE start - avoid HashSet usage BiomeType biome = vector.getBiome(getExtent()); return biomes[biome.getInternalId()]; + //FAWE end } @Nullable @@ -117,12 +127,12 @@ public Mask2D toMask2D() { public Mask copy() { return new BiomeMask(getExtent(), this.biomes.clone()); } - //FAWE end @Override public boolean test(Extent extent, BlockVector3 position) { BiomeType biome = getExtent().getBiome(position); return biomes[biome.getInternalId()]; } + //FAWE end }