diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/regions/QueryCache.java b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/regions/QueryCache.java index 0dc290786..7bb12ea76 100644 --- a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/regions/QueryCache.java +++ b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/regions/QueryCache.java @@ -57,6 +57,16 @@ public ApplicableRegionSet queryContains(RegionManager manager, Location locatio checkNotNull(option); CacheKey key = new CacheKey(location); + + // Fast path: avoid locking if the result is already cached + Map existing = cache.get(key); + if (existing != null) { + ApplicableRegionSet result = existing.get(option); + if (result != null) { + return result; + } + } + return cache.compute(key, (k, v) -> option.createCache(manager, location, v)).get(option); } diff --git a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/regions/RegionQuery.java b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/regions/RegionQuery.java index 2ee030c1e..e2495dd8f 100644 --- a/worldguard-core/src/main/java/com/sk89q/worldguard/protection/regions/RegionQuery.java +++ b/worldguard-core/src/main/java/com/sk89q/worldguard/protection/regions/RegionQuery.java @@ -45,11 +45,11 @@ import com.sk89q.worldguard.protection.util.RegionCollectionConsumer; import java.util.Collection; -import java.util.EnumMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import javax.annotation.Nullable; @@ -513,7 +513,7 @@ public List constructResult(Set applicable) { @Override Map createCache(RegionManager manager, Location location, Map cache) { if (cache == null) { - cache = new EnumMap<>(QueryOption.class); + cache = new ConcurrentHashMap<>(QueryOption.values().length); cache.put(QueryOption.NONE, manager.getApplicableRegions(location.toVector().toBlockPoint(), QueryOption.NONE)); } @@ -530,7 +530,7 @@ Map createCache(RegionManager manager, Locatio @Override Map createCache(RegionManager manager, Location location, Map cache) { if (cache == null) { - Map newCache = new EnumMap<>(QueryOption.class); + Map newCache = new ConcurrentHashMap<>(QueryOption.values().length); ApplicableRegionSet result = manager.getApplicableRegions(location.toVector().toBlockPoint(), QueryOption.SORT); newCache.put(QueryOption.NONE, result); newCache.put(QueryOption.SORT, result); @@ -551,7 +551,7 @@ Map createCache(RegionManager manager, Locatio @Override Map createCache(RegionManager manager, Location location, Map cache) { if (cache == null) { - Map newCache = new EnumMap<>(QueryOption.class); + Map newCache = new ConcurrentHashMap<>(QueryOption.values().length); ApplicableRegionSet noParResult = manager.getApplicableRegions(location.toVector().toBlockPoint(), QueryOption.NONE); Set noParRegions = noParResult.getRegions(); Set regions = new HashSet<>();