Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve BiomeMask performance #3082

Merged
merged 2 commits into from
Feb 9, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -652,11 +652,12 @@ public static void clearCounts(final LevelChunkSection section) throws IllegalAc

public static BiomeType adapt(Holder<Biome> biome, LevelAccessor levelAccessor) {
final Registry<Biome> 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) {
Original file line number Diff line number Diff line change
@@ -652,11 +652,12 @@ public static void clearCounts(final LevelChunkSection section) throws IllegalAc

public static BiomeType adapt(Holder<Biome> biome, LevelAccessor levelAccessor) {
final Registry<Biome> 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) {
Original file line number Diff line number Diff line change
@@ -645,11 +645,12 @@ public static void clearCounts(final LevelChunkSection section) throws IllegalAc

public static BiomeType adapt(Holder<Biome> biome, LevelAccessor levelAccessor) {
final Registry<Biome> 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) {
Original file line number Diff line number Diff line change
@@ -629,11 +629,12 @@ public static void clearCounts(final LevelChunkSection section) throws IllegalAc

public static BiomeType adapt(Holder<Biome> biome, LevelAccessor levelAccessor) {
final Registry<Biome> 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) {
Original file line number Diff line number Diff line change
@@ -636,11 +636,12 @@ public static void clearCounts(final LevelChunkSection section) throws IllegalAc

public static BiomeType adapt(Holder<Biome> biome, LevelAccessor levelAccessor) {
final Registry<Biome> 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) {
Original file line number Diff line number Diff line change
@@ -631,11 +631,12 @@ public static void clearCounts(final LevelChunkSection section) throws IllegalAc

public static BiomeType adapt(Holder<Biome> biome, LevelAccessor levelAccessor) {
final Registry<Biome> 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) {
Original file line number Diff line number Diff line change
@@ -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,9 @@
public class BiomeMask extends AbstractExtentMask {
//FAWE end

private final Set<BiomeType> biomes = new HashSet<>();
//FAWE start - avoid HashSet usage
private final boolean[] biomes;
//FAWE end

/**
* Create a new biome mask.
@@ -51,7 +51,17 @@ public BiomeMask(Extent extent, Collection<BiomeType> biomes) {
super(extent);
//FAWE end
checkNotNull(biomes);
this.biomes.addAll(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) {
super(extent);
this.biomes = biomes;
}

/**
@@ -71,7 +81,11 @@ public BiomeMask(Extent extent, BiomeType... biome) {
*/
public void add(Collection<BiomeType> biomes) {
checkNotNull(biomes);
this.biomes.addAll(biomes);
//FAWE start - avoid HashSet usage
for (final BiomeType biome : biomes) {
this.biomes[biome.getInternalId()] = true;
}
//FAWE end
}

/**
@@ -89,13 +103,17 @@ public void add(BiomeType... biome) {
* @return a list of biomes
*/
public Collection<BiomeType> getBiomes() {
return biomes;
//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.contains(biome);
return biomes[biome.getInternalId()];
//FAWE end
}

@Nullable
@@ -107,14 +125,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()];
}
//FAWE end

}
Original file line number Diff line number Diff line change
@@ -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<BiomeType> byId = create();

private static List<BiomeType> 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;
}