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