From 8770ac6cd737add34e75104f59db3099cd27f052 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Fri, 20 May 2022 20:29:40 +0200 Subject: [PATCH] some more caching for some more performance improvements! --- .../de/ellpeck/naturesaura/InternalHooks.java | 18 ++++++------ .../ellpeck/naturesaura/chunk/AuraChunk.java | 28 +++++++++++++++++++ 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/main/java/de/ellpeck/naturesaura/InternalHooks.java b/src/main/java/de/ellpeck/naturesaura/InternalHooks.java index 90d7ba01..93282c4a 100644 --- a/src/main/java/de/ellpeck/naturesaura/InternalHooks.java +++ b/src/main/java/de/ellpeck/naturesaura/InternalHooks.java @@ -152,10 +152,11 @@ public class InternalHooks implements NaturesAuraAPI.IInternalHooks { public BlockPos getLowestAuraDrainSpot(Level level, BlockPos pos, int radius, BlockPos defaultSpot) { var lowestAmount = new MutableInt(Integer.MAX_VALUE); var lowestSpot = new MutableObject(); - this.getAuraSpotsInArea(level, pos, radius, (blockPos, drainSpot) -> { - if (drainSpot < lowestAmount.intValue()) { - lowestAmount.setValue(drainSpot); - lowestSpot.setValue(blockPos); + Helper.getAuraChunksWithSpotsInArea(level, pos, radius, c -> { + var spot = c.getLowestAndHighestSpots(pos, radius)[0]; + if (spot.getRight() < lowestAmount.intValue()) { + lowestAmount.setValue(spot.getRight()); + lowestSpot.setValue(spot.getLeft()); } }); var lowest = lowestSpot.getValue(); @@ -168,10 +169,11 @@ public class InternalHooks implements NaturesAuraAPI.IInternalHooks { public BlockPos getHighestAuraDrainSpot(Level level, BlockPos pos, int radius, BlockPos defaultSpot) { var highestAmount = new MutableInt(Integer.MIN_VALUE); var highestSpot = new MutableObject(); - this.getAuraSpotsInArea(level, pos, radius, (blockPos, drainSpot) -> { - if (drainSpot > highestAmount.intValue()) { - highestAmount.setValue(drainSpot); - highestSpot.setValue(blockPos); + Helper.getAuraChunksWithSpotsInArea(level, pos, radius, c -> { + var spot = c.getLowestAndHighestSpots(pos, radius)[1]; + if (spot.getRight() > highestAmount.intValue()) { + highestAmount.setValue(spot.getRight()); + highestSpot.setValue(spot.getLeft()); } }); var highest = highestSpot.getValue(); diff --git a/src/main/java/de/ellpeck/naturesaura/chunk/AuraChunk.java b/src/main/java/de/ellpeck/naturesaura/chunk/AuraChunk.java index 036197b3..6896306a 100644 --- a/src/main/java/de/ellpeck/naturesaura/chunk/AuraChunk.java +++ b/src/main/java/de/ellpeck/naturesaura/chunk/AuraChunk.java @@ -20,6 +20,7 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.chunk.LevelChunk; import org.apache.commons.lang3.mutable.MutableInt; +import org.apache.commons.lang3.mutable.MutableObject; import org.apache.commons.lang3.tuple.Pair; import java.util.ArrayList; @@ -34,6 +35,7 @@ public class AuraChunk implements IAuraChunk { private final IAuraType type; private final Map drainSpots = new ConcurrentHashMap<>(); private final Table> auraAndSpotAmountCache = HashBasedTable.create(); + private final Table[]> limitSpotCache = HashBasedTable.create(); private final List effects = new ArrayList<>(); private boolean needsSync; @@ -143,6 +145,7 @@ public class AuraChunk implements IAuraChunk { this.chunk.setUnsaved(true); this.needsSync = true; this.auraAndSpotAmountCache.clear(); + this.limitSpotCache.clear(); this.addOrRemoveAsActive(); } @@ -194,6 +197,31 @@ public class AuraChunk implements IAuraChunk { return ret; } + public Pair[] getLowestAndHighestSpots(BlockPos pos, int radius) { + var ret = this.limitSpotCache.get(pos, radius); + if (ret == null) { + var lowestSpot = new MutableObject(); + var highestSpot = new MutableObject(); + var lowestAmount = new MutableInt(Integer.MAX_VALUE); + var highestAmount = new MutableInt(Integer.MIN_VALUE); + this.getSpots(pos, radius, (p, i) -> { + if (i > highestAmount.intValue()) { + highestAmount.setValue(i); + highestSpot.setValue(p); + } + if (i < lowestAmount.intValue()) { + lowestAmount.setValue(i); + lowestSpot.setValue(p); + } + }); + ret = new Pair[]{ + Pair.of(lowestSpot.getValue(), lowestAmount.intValue()), + Pair.of(highestSpot.getValue(), highestAmount.intValue())}; + this.limitSpotCache.put(pos, radius, ret); + } + return ret; + } + public void getActiveEffectIcons(Player player, Map> icons) { for (var effect : this.effects) { var alreadyThere = icons.get(effect.getName());