mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-30 17:36:40 +00:00
fixed caching problem in getDirectionFromStartToNextMark; fixed bug 388 (course-based wind track extended)
This commit is contained in:
1 parent
b883acce9e
commit
0935a5afea
2 files changed
+40
-20
No files matched your search
+14
-4
@@ -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,10 +40,13 @@ 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);
|
||||
if (directionFromStartToNextMark != null) {
|
||||
result.add(directionFromStartToNextMark);
|
||||
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;
|
||||
|
||||
+26
-16
@@ -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,18 +592,21 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
|
||||
|
||||
@Override
|
||||
public Wind getDirectionFromStartToNextMark(TimePoint at) {
|
||||
Wind result = directionFromStartToNextMarkCache;
|
||||
if (result == null) {
|
||||
Leg firstLeg = getRace().getCourse().getLegs().iterator().next();
|
||||
Position firstLegEnd = getApproximatePosition(firstLeg.getTo(), at);
|
||||
Position firstLegStart = getApproximatePosition(firstLeg.getFrom(), at);
|
||||
if (firstLegStart != null && firstLegEnd != null) {
|
||||
result = new WindImpl(firstLegStart, at, new KnotSpeedWithBearingImpl(1.0,
|
||||
firstLegEnd.getBearingGreatCircle(firstLegStart)));
|
||||
final Wind finalResult = result;
|
||||
directionFromStartToNextMarkCache = finalResult;
|
||||
} else {
|
||||
result = null;
|
||||
Wind result;
|
||||
synchronized (directionFromStartToNextMarkCache) {
|
||||
result = directionFromStartToNextMarkCache.get(at);
|
||||
if (result == null) {
|
||||
Leg firstLeg = getRace().getCourse().getLegs().iterator().next();
|
||||
Position firstLegEnd = getApproximatePosition(firstLeg.getTo(), at);
|
||||
Position firstLegStart = getApproximatePosition(firstLeg.getFrom(), at);
|
||||
if (firstLegStart != null && firstLegEnd != null) {
|
||||
result = new WindImpl(firstLegStart, at, new KnotSpeedWithBearingImpl(1.0,
|
||||
firstLegEnd.getBearingGreatCircle(firstLegStart)));
|
||||
final Wind finalResult = result;
|
||||
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
|
||||
|
||||
Reference in new issue
Block a user