Skip to content

Commit

Permalink
removed synchronization requirement to speed up access
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin Milner committed Dec 14, 2024
1 parent 8603c6b commit 4fd45e6
Showing 1 changed file with 55 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,94 +5,104 @@
/**
* 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
*
*/
public class SingleLocDistanceCache implements SurfaceDistanceCache {

private CacheEnabledSurface surf;

private Location siteLocForDistCalcs;
private SurfaceDistances surfDists;
private static class LocDistCache<E> {
final Location loc;
final E value;
private LocDistCache(Location loc, E value) {
super();
this.loc = loc;
this.value = value;
}
}

private LocDistCache<SurfaceDistances> surfDists;

private Location siteLocForQuickDistCalc;
private double quickDist;
private LocDistCache<Double> quickDist;

private Location siteLocForDistXCalc;
private double distX;
private LocDistCache<Double> 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<SurfaceDistances> cached = surfDists;
if (cached == null || !cached.loc.equals(loc)) {
cached = new LocDistCache<SurfaceDistances>(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<Double> cached = quickDist;
if (cached == null || !cached.loc.equals(loc)) {
cached = new LocDistCache<Double>(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<Double> cached = distX;
if (cached == null || !cached.loc.equals(loc)) {
cached = new LocDistCache<Double>(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<SurfaceDistances> 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<Double> 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<Double> 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;
}

}

0 comments on commit 4fd45e6

Please sign in to comment.