1919
2020package com .sk89q .worldedit .function .pattern ;
2121
22- import com .google .common .collect .Maps ;
2322import com .sk89q .worldedit .extent .Extent ;
2423import com .sk89q .worldedit .math .BlockVector3 ;
2524import com .sk89q .worldedit .registry .state .Property ;
3635public class StateApplyingPattern extends AbstractExtentPattern {
3736
3837 private final Map <String , String > states ;
39- //FAWE - avoid race conditions
40- private final Map <BlockType , Map < Property < Object >, Object > > cache = new ConcurrentHashMap <>();
38+ //FAWE - avoid race conditions, faster property applications
39+ private final Map <BlockType , PropertyApplication [] > cache = new ConcurrentHashMap <>();
4140 //FAWE end
4241
4342 public StateApplyingPattern (Extent extent , Map <String , String > statesToSet ) {
@@ -47,16 +46,40 @@ public StateApplyingPattern(Extent extent, Map<String, String> statesToSet) {
4746
4847 @ Override
4948 public BaseBlock applyBlock (BlockVector3 position ) {
50- BlockState block = getExtent ().getBlock (position );
51- for (Entry <Property <Object >, Object > entry : cache
52- .computeIfAbsent (block .getBlockType (), (b -> resolveProperties (states , b ))).entrySet ()) {
53- //FAWE start
54- if (block .getBlockType ().hasProperty (entry .getKey ().getKey ())) {
55- block = block .with (entry .getKey (), entry .getValue ());
49+ //FAWE start
50+ BlockState block = position .getBlock (getExtent ());
51+ final BlockType blockType = block .getBlockType ();
52+ // weak consistency is enough, no need to use computeIfAbsent
53+ PropertyApplication [] applications = cache .get (blockType );
54+ if (applications == null ) {
55+ applications = resolvePropertiesFor (blockType );
56+ cache .put (blockType , applications );
57+ }
58+ for (PropertyApplication entry : applications ) {
59+ if (blockType .hasProperty (entry .property ().getKey ())) {
60+ block = block .with (entry .property (), entry .value ());
5661 }
5762 //FAWE end
5863 }
5964 return block .toBaseBlock ();
6065 }
6166
67+ //FAWE start - faster property application
68+ private record PropertyApplication (Property <Object > property , Object value ) {
69+
70+ }
71+
72+ private PropertyApplication [] resolvePropertiesFor (BlockType blockType ) {
73+ Map <Property <Object >, Object > map = resolveProperties (states , blockType );
74+ final PropertyApplication [] applications = new PropertyApplication [map .size ()];
75+ int i = 0 ;
76+ for (Entry <Property <Object >, Object > entry : map .entrySet ()) {
77+ Property <Object > property = entry .getKey ();
78+ Object o = entry .getValue ();
79+ applications [i ++] = new PropertyApplication (property , o );
80+ }
81+ return applications ;
82+ }
83+ //FAWE end
84+
6285}
0 commit comments