fixed caching problem in getDirectionFromStartToNextMark; fixed bug 388 (course-based wind track extended)

This commit is contained in:
Axel Uhl committed 2012-03-09 11:23:48 +01:00
1 parent b883acce9e
commit 0935a5afea
2 files changed
+28 -8

No files matched your search

@@ -2,6 +2,7 @@ package com.sap.sailing.domain.tracking.impl;
import java.util.NavigableSet;
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.Wind;
@@ -19,6 +20,12 @@ import com.sap.sailing.util.impl.UnmodifiableNavigableSet;
*
*/
public class CourseBasedWindTrackImpl extends WindTrackImpl {
/**
* The first leg's direction will be measured this many milliseconds before the estimated race start time,
* at estimated race start time and this many milliseconds after estimated race start time.
*/
private final long MILLISECONDS_AROUND_START_TO_TRACK = 30000l;
private final TrackedRace trackedRace;
private static final NavigableSet<Wind> empty = new UnmodifiableNavigableSet<Wind>(new ArrayListNavigableSet<Wind>(WindComparator.INSTANCE));
@@ -33,11 +40,14 @@ public class CourseBasedWindTrackImpl extends WindTrackImpl {
if (trackedRace.raceIsKnownToStartUpwind()) {
TimePoint startTime = trackedRace.getStart();
if (startTime != null) {
result = new ArrayListNavigableSet<Wind>(1, WindComparator.INSTANCE);
final Wind directionFromStartToNextMark = trackedRace.getDirectionFromStartToNextMark(startTime);
result = new ArrayListNavigableSet<Wind>(3, WindComparator.INSTANCE);
for (long t = startTime.asMillis() - MILLISECONDS_AROUND_START_TO_TRACK; t <= startTime.asMillis()
+ MILLISECONDS_AROUND_START_TO_TRACK; t += MILLISECONDS_AROUND_START_TO_TRACK) {
final Wind directionFromStartToNextMark = trackedRace.getDirectionFromStartToNextMark(new MillisecondsTimePoint(t));
if (directionFromStartToNextMark != null) {
result.add(directionFromStartToNextMark);
}
}
} else {
result = empty;
}
@@ -134,7 +134,7 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
*/
private final Map<WindSource, WindTrack> windTracks;
private Wind directionFromStartToNextMarkCache;
private final Map<TimePoint, Wind> directionFromStartToNextMarkCache;
private final Map<Buoy, GPSFixTrack<Buoy, GPSFix>> buoyTracks;
@@ -152,6 +152,7 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
this.updateCount = 0;
this.race = race;
this.windStore = windStore;
this.directionFromStartToNextMarkCache = new HashMap<TimePoint, Wind>();
this.millisecondsOverWhichToAverageSpeed = millisecondsOverWhichToAverageSpeed;
this.millisecondsOverWhichToAverageWind = millisecondsOverWhichToAverageWind;
this.startToNextMarkCacheInvalidationListeners = new HashMap<Buoy, TrackedRaceImpl.StartToNextMarkCacheInvalidationListener>();
@@ -591,7 +592,9 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
@Override
public Wind getDirectionFromStartToNextMark(TimePoint at) {
Wind result = directionFromStartToNextMarkCache;
Wind result;
synchronized (directionFromStartToNextMarkCache) {
result = directionFromStartToNextMarkCache.get(at);
if (result == null) {
Leg firstLeg = getRace().getCourse().getLegs().iterator().next();
Position firstLegEnd = getApproximatePosition(firstLeg.getTo(), at);
@@ -600,11 +603,12 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
result = new WindImpl(firstLegStart, at, new KnotSpeedWithBearingImpl(1.0,
firstLegEnd.getBearingGreatCircle(firstLegStart)));
final Wind finalResult = result;
directionFromStartToNextMarkCache = finalResult;
directionFromStartToNextMarkCache.put(at, finalResult);
} else {
result = null;
}
}
}
return result;
}
@@ -686,7 +690,7 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
if (zeroBasedIndex < 2) {
// the observing listener on any previous buoy will be GCed; we need to ensure
// that the cache is recomputed
directionFromStartToNextMarkCache = null;
clearDirectionFromStartToNextMarkCache();
Iterator<Waypoint> waypointsIter = getRace().getCourse().getWaypoints().iterator();
waypointsIter.next(); // skip first
if (waypointsIter.hasNext()) {
@@ -700,6 +704,12 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
addStartToNextMarkCacheInvalidationListener(waypointThatGotAdded);
}
private void clearDirectionFromStartToNextMarkCache() {
synchronized (directionFromStartToNextMarkCache) {
directionFromStartToNextMarkCache.clear();
}
}
private void addStartToNextMarkCacheInvalidationListener(Waypoint waypoint) {
for (Buoy buoy : waypoint.getBuoys()) {
addStartToNextMarkCacheInvalidationListener(buoy);
@@ -756,7 +766,7 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
if (zeroBasedIndex < 2) {
// the observing listener on any previous buoy will be GCed; we need to ensure
// that the cache is recomputed
directionFromStartToNextMarkCache = null;
clearDirectionFromStartToNextMarkCache();
stopAndRemoveStartToNextMarkCacheInvalidationListener(waypointThatGotRemoved);
Iterator<Waypoint> waypointsIter = getRace().getCourse().getWaypoints().iterator();
waypointsIter.next(); // skip first
@@ -1253,7 +1263,7 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
@Override
public void gpsFixReceived(GPSFix fix, Buoy buoy) {
directionFromStartToNextMarkCache = null;
clearDirectionFromStartToNextMarkCache();
}
@Override