From 4fd45e6a2456f24b2f98bf0996523c2d348cb7c8 Mon Sep 17 00:00:00 2001 From: Kevin Milner Date: Fri, 13 Dec 2024 16:11:18 -0800 Subject: [PATCH] removed synchronization requirement to speed up access --- .../cache/SingleLocDistanceCache.java | 100 ++++++++++-------- 1 file changed, 55 insertions(+), 45 deletions(-) diff --git a/src/main/java/org/opensha/sha/faultSurface/cache/SingleLocDistanceCache.java b/src/main/java/org/opensha/sha/faultSurface/cache/SingleLocDistanceCache.java index 787a66163..92be81d2c 100644 --- a/src/main/java/org/opensha/sha/faultSurface/cache/SingleLocDistanceCache.java +++ b/src/main/java/org/opensha/sha/faultSurface/cache/SingleLocDistanceCache.java @@ -5,6 +5,9 @@ /** * Simple {@link SurfaceDistanceCache} implementation that stores a single location/value, works well in * single threaded environments but has many collisions in multithreaded calculations. + * + * Updated in 2024 to remove synchronization bottleneck; by storing the cached values in a wrapper object along with the + * location, threads can safely get the current value without worrying about another thread updating it * @author kevin * */ @@ -12,87 +15,94 @@ public class SingleLocDistanceCache implements SurfaceDistanceCache { private CacheEnabledSurface surf; - private Location siteLocForDistCalcs; - private SurfaceDistances surfDists; + private static class LocDistCache { + final Location loc; + final E value; + private LocDistCache(Location loc, E value) { + super(); + this.loc = loc; + this.value = value; + } + } + + private LocDistCache surfDists; - private Location siteLocForQuickDistCalc; - private double quickDist; + private LocDistCache quickDist; - private Location siteLocForDistXCalc; - private double distX; + private LocDistCache distX; public SingleLocDistanceCache(CacheEnabledSurface surf) { this.surf = surf; } @Override - public synchronized SurfaceDistances getSurfaceDistances(Location loc) { - if (siteLocForDistCalcs == null || !siteLocForDistCalcs.equals(loc)) { - surfDists = surf.calcDistances(loc); - siteLocForDistCalcs = loc; + public SurfaceDistances getSurfaceDistances(Location loc) { + LocDistCache cached = surfDists; + if (cached == null || !cached.loc.equals(loc)) { + cached = new LocDistCache(loc, surf.calcDistances(loc)); + surfDists = cached; } - return surfDists; + return cached.value; } @Override - public synchronized double getQuickDistance(Location loc) { - if (siteLocForQuickDistCalc == null || !siteLocForQuickDistCalc.equals(loc)) { - quickDist = surf.calcQuickDistance(loc); - siteLocForQuickDistCalc = loc; + public double getQuickDistance(Location loc) { + LocDistCache cached = quickDist; + if (cached == null || !cached.loc.equals(loc)) { + cached = new LocDistCache(loc, surf.calcQuickDistance(loc)); + quickDist = cached; } - return quickDist; + return cached.value; } @Override - public synchronized double getDistanceX(Location loc) { - if (siteLocForDistXCalc == null || !siteLocForDistXCalc.equals(loc)) { - distX = surf.calcDistanceX(loc); - siteLocForDistXCalc = loc; + public double getDistanceX(Location loc) { + LocDistCache cached = distX; + if (cached == null || !cached.loc.equals(loc)) { + cached = new LocDistCache(loc, surf.calcDistanceX(loc)); + distX = cached; } - return distX; + return cached.value; } - synchronized SurfaceDistances getSurfaceDistancesIfPresent(Location loc) { - if (loc.equals(siteLocForDistCalcs)) - return surfDists; + SurfaceDistances getSurfaceDistancesIfPresent(Location loc) { + LocDistCache cached = surfDists; + if (cached != null && cached.loc.equals(loc)) + return cached.value; return null; } - synchronized Double getQuickDistanceIfPresent(Location loc) { - if (loc.equals(siteLocForQuickDistCalc)) - return quickDist; + Double getQuickDistanceIfPresent(Location loc) { + LocDistCache cached = quickDist; + if (cached != null && cached.loc.equals(loc)) + return cached.value; return null; } - synchronized Double getDistanceXIfPresent(Location loc) { - if (loc.equals(siteLocForDistXCalc)) - return distX; + Double getDistanceXIfPresent(Location loc) { + LocDistCache cached = distX; + if (cached != null && cached.loc.equals(loc)) + return cached.value; return null; } - synchronized void putSurfaceDistances(Location loc, SurfaceDistances dists) { - this.siteLocForDistCalcs = loc; - this.surfDists = dists; + void putSurfaceDistances(Location loc, SurfaceDistances dists) { + this.surfDists = new LocDistCache<>(loc, dists); } - synchronized void putQuickDistance(Location loc, double quickDistance) { - this.siteLocForQuickDistCalc = loc; - this.quickDist = quickDistance; + void putQuickDistance(Location loc, double quickDistance) { + this.quickDist = new LocDistCache<>(loc, quickDistance); } - synchronized void putDistanceX(Location loc, double distX) { - this.siteLocForDistXCalc = loc; - this.distX = distX; + void putDistanceX(Location loc, double distX) { + this.distX = new LocDistCache<>(loc, distX); } @Override - public synchronized void clearCache() { - this.siteLocForDistCalcs = null; + public void clearCache() { this.surfDists = null; - this.siteLocForDistXCalc = null; - this.distX = Double.NaN; - siteLocForQuickDistCalc = null; - this.quickDist = Double.NaN; + this.quickDist = null; + this.distX = null; } }