diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/StateApplyingPattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/StateApplyingPattern.java index b328e78ea0..63d758b217 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/StateApplyingPattern.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/StateApplyingPattern.java @@ -19,7 +19,6 @@ package com.sk89q.worldedit.function.pattern; -import com.google.common.collect.Maps; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.registry.state.Property; @@ -36,8 +35,8 @@ public class StateApplyingPattern extends AbstractExtentPattern { private final Map states; - //FAWE - avoid race conditions - private final Map, Object>> cache = new ConcurrentHashMap<>(); + //FAWE - avoid race conditions, faster property applications + private final Map cache = new ConcurrentHashMap<>(); //FAWE end public StateApplyingPattern(Extent extent, Map statesToSet) { @@ -47,16 +46,40 @@ public StateApplyingPattern(Extent extent, Map statesToSet) { @Override public BaseBlock applyBlock(BlockVector3 position) { - BlockState block = getExtent().getBlock(position); - for (Entry, Object> entry : cache - .computeIfAbsent(block.getBlockType(), (b -> resolveProperties(states, b))).entrySet()) { - //FAWE start - if (block.getBlockType().hasProperty(entry.getKey().getKey())) { - block = block.with(entry.getKey(), entry.getValue()); + //FAWE start + BlockState block = position.getBlock(getExtent()); + final BlockType blockType = block.getBlockType(); + // weak consistency is enough, no need to use computeIfAbsent + PropertyApplication[] applications = cache.get(blockType); + if (applications == null) { + applications = resolvePropertiesFor(blockType); + cache.put(blockType, applications); + } + for (PropertyApplication entry : applications) { + if (blockType.hasProperty(entry.property().getKey())) { + block = block.with(entry.property(), entry.value()); } //FAWE end } return block.toBaseBlock(); } + //FAWE start - faster property application + private record PropertyApplication(Property property, Object value) { + + } + + private PropertyApplication[] resolvePropertiesFor(BlockType blockType) { + Map, Object> map = resolveProperties(states, blockType); + final PropertyApplication[] applications = new PropertyApplication[map.size()]; + int i = 0; + for (Entry, Object> entry : map.entrySet()) { + Property property = entry.getKey(); + Object o = entry.getValue(); + applications[i++] = new PropertyApplication(property, o); + } + return applications; + } + //FAWE end + }