java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogConnectivityParams.java
... ...
@@ -91,7 +91,7 @@ public class RaceLogConnectivityParams extends AbstractRaceTrackingConnectivityP
91 91
}
92 92
DynamicTrackedRegatta trackedRegatta = trackedRegattaRegistry.getOrCreateTrackedRegatta(regatta);
93 93
return new RaceLogRaceTracker(trackedRegatta, this, windStore, raceLogResolver, this, trackedRegattaRegistry,
94
- raceTrackingHandler, markPassingRaceFingerprintRegistry);
94
+ raceTrackingHandler, markPassingRaceFingerprintRegistry, maneuverRaceFingerprintRegistry);
95 95
}
96 96
97 97
@Override
java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogRaceTracker.java
... ...
@@ -60,6 +60,7 @@ import com.sap.sailing.domain.common.abstractlog.TimePointSpecificationFoundInLo
60 60
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
61 61
import com.sap.sailing.domain.common.racelog.tracking.RaceLogTrackingState;
62 62
import com.sap.sailing.domain.common.racelog.tracking.RaceNotCreatedException;
63
+import com.sap.sailing.domain.maneuverhash.ManeuverRaceFingerprintRegistry;
63 64
import com.sap.sailing.domain.markpassinghash.MarkPassingRaceFingerprintRegistry;
64 65
import com.sap.sailing.domain.racelog.RaceLogAndTrackedRaceResolver;
65 66
import com.sap.sailing.domain.racelogtracking.RaceLogTrackingAdapter;
... ...
@@ -102,13 +103,14 @@ public class RaceLogRaceTracker extends AbstractRaceTrackerBaseImpl<RaceLogConne
102 103
private final RaceLogAndTrackedRaceResolver raceLogResolver;
103 104
private final TrackedRegattaRegistry trackedRegattaRegistry;
104 105
private final MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry;
106
+ private final ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry;
105 107
106 108
private volatile DynamicTrackedRace trackedRace;
107 109
private final RaceTrackingHandler raceTrackingHandler;
108 110
109 111
public RaceLogRaceTracker(DynamicTrackedRegatta regatta, RaceLogConnectivityParams params, WindStore windStore,
110 112
RaceLogAndTrackedRaceResolver raceLogResolver, RaceLogConnectivityParams connectivityParams,
111
- TrackedRegattaRegistry trackedRegattaRegistry, RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry) {
113
+ TrackedRegattaRegistry trackedRegattaRegistry, RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) {
112 114
super(params);
113 115
this.trackedRegattaRegistry = trackedRegattaRegistry;
114 116
this.params = params;
... ...
@@ -116,6 +118,7 @@ public class RaceLogRaceTracker extends AbstractRaceTrackerBaseImpl<RaceLogConne
116 118
this.trackedRegatta = regatta;
117 119
this.raceLogResolver = raceLogResolver;
118 120
this.markPassingRaceFingerprintRegistry = markPassingRaceFingerprintRegistry;
121
+ this.maneuverRaceFingerprintRegistry = maneuverRaceFingerprintRegistry;
119 122
this.raceTrackingHandler = raceTrackingHandler;
120 123
// add log listeners
121 124
for (AbstractLog<?, ?> log : params.getLogHierarchy()) {
... ...
@@ -355,7 +358,7 @@ public class RaceLogRaceTracker extends AbstractRaceTrackerBaseImpl<RaceLogConne
355 358
boatClass.getApproximateManeuverDurationInMilliseconds(), null, /*useMarkPassingCalculator*/ true, raceLogResolver,
356 359
/* Not needed because the RaceTracker is not active on a replica */ Optional.empty(),
357 360
new TrackingConnectorInfoImpl(RaceLogTrackingAdapter.NAME, RaceLogTrackingAdapter.DEFAULT_URL, /* no webUrl */ null),
358
- markPassingRaceFingerprintRegistry, /* maneuverRaceFingerprintRegistry */ null);
361
+ markPassingRaceFingerprintRegistry, maneuverRaceFingerprintRegistry );
359 362
notifyRaceCreationListeners();
360 363
logger.info(String.format("Started tracking race-log race (%s)", raceLog));
361 364
// this wakes up all waiting race handles
java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverhash/ManeuverCache.java
... ...
@@ -0,0 +1,16 @@
1
+package com.sap.sailing.domain.maneuverhash;
2
+
3
+
4
+import com.sap.sse.util.SmartFutureCache;
5
+import com.sap.sse.util.SmartFutureCache.UpdateInterval;
6
+
7
+public interface ManeuverCache<K, V, U extends UpdateInterval<U>>{
8
+
9
+ void resume();
10
+
11
+ V get(K key, boolean waitForLatest);
12
+
13
+ void suspend();
14
+
15
+ void triggerUpdate(K key, U updateInterval);
16
+}
... ...
\ No newline at end of file
java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverhash/impl/ManeuverCacheDelegate.java
... ...
@@ -2,38 +2,33 @@ package com.sap.sailing.domain.maneuverhash.impl;
2 2
3 3
import java.util.ArrayList;
4 4
import java.util.Collections;
5
+import java.util.HashMap;
5 6
import java.util.List;
6 7
import java.util.Map;
7 8
8
-//import java.util.logging.Logger;
9
+import java.util.logging.Logger;
9 10
10
-import com.sap.sailing.domain.base.CPUMeteringType;
11 11
import com.sap.sailing.domain.base.Competitor;
12
-import com.sap.sailing.domain.common.NoWindException;
13
-import com.sap.sailing.domain.maneuverdetection.ManeuverDetector;
12
+import com.sap.sailing.domain.maneuverhash.ManeuverCache;
14 13
import com.sap.sailing.domain.maneuverhash.ManeuverRaceFingerprint;
15 14
import com.sap.sailing.domain.maneuverhash.ManeuverRaceFingerprintFactory;
16 15
import com.sap.sailing.domain.maneuverhash.ManeuverRaceFingerprintRegistry;
17 16
import com.sap.sailing.domain.tracking.Maneuver;
18 17
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
19 18
import com.sap.sailing.domain.tracking.impl.TrackedRaceImpl;
20
-import com.sap.sse.common.Duration;
21
-import com.sap.sse.util.ManeuverCache;
22
-import com.sap.sse.util.SmartFutureCache;
23
-import com.sap.sse.util.SmartFutureCache.AbstractCacheUpdater;
24 19
import com.sap.sse.util.SmartFutureCache.EmptyUpdateInterval;
25 20
26
-
27 21
public class ManeuverCacheDelegate implements ManeuverCache<Competitor, List<Maneuver>, EmptyUpdateInterval> {
28 22
29
-
30 23
private final TrackedRaceImpl race;
31
- // private static final Logger logger = Logger.getLogger(ManeuverCacheDelegate.class.getName());
24
+ private static final Logger logger = Logger.getLogger(ManeuverCacheDelegate.class.getName());
32 25
private final ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry;
33 26
// private ManeuverCache<Competitor, List<Maneuver>, EmptyUpdateInterval> maneuverCache;
34
- private ManeuverFromDatabase cache;
35
- private SmartFutureCache<Competitor, List<Maneuver>, EmptyUpdateInterval> smartFutureCache;
36
- Map<Competitor, List<Maneuver>> maneuvers;
27
+ Map<Competitor, List<Maneuver>> maneuvers = new HashMap<>();
28
+// private ManeuverFromDatabase cache;
29
+// private SmartFutureCache<Competitor, List<Maneuver>, EmptyUpdateInterval> smartFutureCache;
30
+ private ManeuverCache<Competitor, List<Maneuver>, EmptyUpdateInterval> cacheToUse;
31
+
37 32
// // flag suspended / resume
38 33
private boolean cachesSuspended;
39 34
private boolean triggerManeuverCacheInvalidationForAllCompetitors;
... ...
@@ -43,35 +38,32 @@ public class ManeuverCacheDelegate implements ManeuverCache<Competitor, List<Man
43 38
super();
44 39
this.race = race;
45 40
this.maneuverRaceFingerprintRegistry = maneuverRaceFingerprintRegistry;
46
- this.cache = new ManeuverFromDatabase( false, (DynamicTrackedRaceImpl) race, maneuverRaceFingerprintRegistry);
47
- this.smartFutureCache = new SmartFutureCache<Competitor, List<Maneuver>, EmptyUpdateInterval>(
48
- new AbstractCacheUpdater<Competitor, List<Maneuver>, EmptyUpdateInterval>() {
49
- @Override
50
- public List<Maneuver> computeCacheUpdate(Competitor competitor, EmptyUpdateInterval updateInterval)
51
- throws NoWindException {
52
- return race.getTrackedRegatta().callWithCPUMeterWithException(()->{
53
- Duration averageIntervalBetweenRawFixes = race.getTrack(competitor).getAverageIntervalBetweenRawFixes();
54
- if (averageIntervalBetweenRawFixes != null) {
55
- ManeuverDetector maneuverDetector;
56
- // FIXME The LowGPSSamplingRateManeuverDetectorImpl doesn't work very well; it recognizes many tacks only as bear-away and doesn't seem to have any noticeable benefits... See ORC Worlds 2019 ORC A Long Offshore
57
- // if (averageIntervalBetweenRawFixes.asSeconds() >= 30) {
58
- // maneuverDetector = new LowGPSSamplingRateManeuverDetectorImpl(TrackedRaceImpl.this, competitor);
59
- // } else {
60
- maneuverDetector = race.getManeuverDetectorPerCompetitorCache().getValue(competitor);
61
-
62
- // }
63
- List<Maneuver> maneuvers = race.computeManeuvers(competitor, maneuverDetector);
64
- return maneuvers;
65
- } else {
66
- return Collections.emptyList();
67
- }
68
- }, CPUMeteringType.MANEUVER_DETECTION.name());
69
- }
70
- }, /* nameForLocks */ "Maneuver cache for race " + race.getRace().getName());
41
+ this.cacheToUse = new ManeuverFromSmartFutureCache((DynamicTrackedRaceImpl) race);
42
+// this.cache = new ManeuverFromDatabase( false, (DynamicTrackedRaceImpl) race, maneuverRaceFingerprintRegistry);
43
+// this.smartFutureCache = new SmartFutureCache<Competitor, List<Maneuver>, EmptyUpdateInterval>(
44
+// new AbstractCacheUpdater<Competitor, List<Maneuver>, EmptyUpdateInterval>() {
45
+// @Override
46
+// public List<Maneuver> computeCacheUpdate(Competitor competitor, EmptyUpdateInterval updateInterval)
47
+// throws NoWindException {
48
+// return race.getTrackedRegatta().callWithCPUMeterWithException(()->{
49
+// Duration averageIntervalBetweenRawFixes = race.getTrack(competitor).getAverageIntervalBetweenRawFixes();
50
+// if (averageIntervalBetweenRawFixes != null) {
51
+// ManeuverDetector maneuverDetector;
52
+// maneuverDetector = race.getManeuverDetectorPerCompetitorCache().getValue(competitor);
53
+//
54
+// List<Maneuver> maneuvers = race.computeManeuvers(competitor, maneuverDetector);
55
+// return maneuvers;
56
+// } else {
57
+// return Collections.emptyList();
58
+// }
59
+// }, CPUMeteringType.MANEUVER_DETECTION.name());
60
+// }
61
+// }, /* nameForLocks */ "Maneuver cache for race " + race.getRace().getName());
71 62
}
72 63
73 64
@Override
74 65
public void resume() {
66
+
75 67
// richtigen Ort bestimmen
76 68
if (triggerManeuverCacheInvalidationForAllCompetitors) {
77 69
triggerManeuverCacheRecalculationForAllCompetitors();
... ...
@@ -82,17 +74,23 @@ public class ManeuverCacheDelegate implements ManeuverCache<Competitor, List<Man
82 74
try {
83 75
synchronized (this) {
84 76
if (maneuverRaceFingerprintRegistry != null) {
77
+ logger.info("Compare maneuverfingerprints");
85 78
fingerprint = maneuverRaceFingerprintRegistry.getManeuverRaceFingerprint(race.getRaceIdentifier());
86 79
} else {
87 80
fingerprint = null;
88 81
}
89 82
if (fingerprint != null && fingerprint.matches(race)) {
90
- cache.resume();
83
+ logger.info("maneuverfingerprints match");
84
+ maneuvers = maneuverRaceFingerprintRegistry.loadManeuvers(race, race.getRace().getCourse());
85
+ // Laden der maneuver um an MFD mitzugeben
86
+ cacheToUse = new ManeuverFromDatabase( /*false, (DynamicTrackedRaceImpl) race, maneuverRaceFingerprintRegistry,*/ maneuvers);
91 87
} else {
92 88
new Thread(()->{
93
- smartFutureCache.resume();
89
+ logger.info("maneuverfingerprints do not match");
90
+ cacheToUse.resume();
94 91
for(Competitor competitor : race.getRace().getCompetitors()) {
95
- maneuvers.put(competitor, (List<Maneuver>) smartFutureCache.get(competitor, true));
92
+
93
+ maneuvers.put(competitor, (List<Maneuver>) cacheToUse.get(competitor, true));
96 94
}
97 95
maneuverRaceFingerprintRegistry.storeManeuvers(race.getRaceIdentifier(), ManeuverRaceFingerprintFactory.INSTANCE.createFingerprint(race), maneuvers, race.getRace().getCourse());
98 96
}, "Waiting for mark passings for "+race.getName()+" after having resumed to store the results in registry")
... ...
@@ -106,21 +104,13 @@ public class ManeuverCacheDelegate implements ManeuverCache<Competitor, List<Man
106 104
107 105
@Override
108 106
public List<Maneuver> get(Competitor competitor, boolean waitForLatest) {
109
- ManeuverRaceFingerprint fingerprint;
110 107
race.getRace().getCourse().lockForRead();
111 108
try {
112 109
synchronized (this) {
113
- if (maneuverRaceFingerprintRegistry != null) {
114
- fingerprint = maneuverRaceFingerprintRegistry.getManeuverRaceFingerprint(race.getRaceIdentifier());
115
- } else {
116
- fingerprint = null;
117
- }
118
- if (fingerprint != null && fingerprint.matches(race)) {
119
- return cache.get(competitor, waitForLatest);
120
- } else {
121
- return smartFutureCache.get(competitor, waitForLatest);
110
+
111
+ return (List<Maneuver>) cacheToUse.get(competitor, waitForLatest);
122 112
}
123
- }
113
+
124 114
} finally {
125 115
race.getRace().getCourse().unlockAfterRead();
126 116
}
... ...
@@ -128,46 +118,32 @@ public class ManeuverCacheDelegate implements ManeuverCache<Competitor, List<Man
128 118
129 119
@Override
130 120
public void suspend() {
131
- ManeuverRaceFingerprint fingerprint;
132 121
race.getRace().getCourse().lockForRead();
133 122
try {
134 123
synchronized (this) {
135
- if (maneuverRaceFingerprintRegistry != null) {
136
- fingerprint = maneuverRaceFingerprintRegistry.getManeuverRaceFingerprint(race.getRaceIdentifier());
137
- } else {
138
- fingerprint = null;
139
- }
140
- if (fingerprint != null && fingerprint.matches(race)) {
141
- cache.suspend();
142
- } else {
143
- smartFutureCache.suspend();
144
- }
124
+
125
+ cacheToUse.suspend();
145 126
}
146 127
} finally {
147 128
race.getRace().getCourse().unlockAfterRead();
148
- }
129
+ }
130
+
149 131
}
150 132
151 133
@Override
152 134
public void triggerUpdate(Competitor competitor, EmptyUpdateInterval updateInterval) {
153
- ManeuverRaceFingerprint fingerprint;
135
+
154 136
race.getRace().getCourse().lockForRead();
155 137
try {
156 138
synchronized (this) {
157
- if (maneuverRaceFingerprintRegistry != null) {
158
- fingerprint = maneuverRaceFingerprintRegistry.getManeuverRaceFingerprint(race.getRaceIdentifier());
159
- } else {
160
- fingerprint = null;
161
- }
162
- if (fingerprint != null && fingerprint.matches(race)) {
163
- cache.triggerUpdate(competitor, updateInterval);
164
- } else {
165
- smartFutureCache.triggerUpdate(competitor, updateInterval);;
166
- }
139
+
140
+ cacheToUse.suspend();
167 141
}
168 142
} finally {
169 143
race.getRace().getCourse().unlockAfterRead();
170 144
}
145
+
146
+
171 147
}
172 148
173 149
... ...
@@ -193,4 +169,4 @@ public class ManeuverCacheDelegate implements ManeuverCache<Competitor, List<Man
193 169
triggerUpdate(competitor, /* updateInterval */null);
194 170
}
195 171
}
196
-}
172
+}
... ...
\ No newline at end of file
java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverhash/impl/ManeuverFromDatabase.java
... ...
@@ -2,49 +2,51 @@ package com.sap.sailing.domain.maneuverhash.impl;
2 2
3 3
import java.util.List;
4 4
import java.util.Map;
5
-import java.util.Map.Entry;
5
+//import java.util.Map.Entry;
6 6
import java.util.logging.Level;
7 7
import java.util.logging.Logger;
8
-import java.util.stream.Collectors;
8
+//import java.util.stream.Collectors;
9 9
10 10
import com.sap.sailing.domain.base.Competitor;
11
-import com.sap.sailing.domain.maneuverhash.ManeuverRaceFingerprintRegistry;
12
-import com.sap.sailing.domain.shared.tracking.impl.TimedComparator;
11
+import com.sap.sailing.domain.maneuverhash.ManeuverCache;
12
+//import com.sap.sailing.domain.maneuverhash.ManeuverRaceFingerprintRegistry;
13
+//import com.sap.sailing.domain.shared.tracking.impl.TimedComparator;
13 14
import com.sap.sailing.domain.tracking.Maneuver;
14
-import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
15
-//import com.sap.sailing.domain.tracking.impl.TrackedRaceImpl;
16
-import com.sap.sse.util.ManeuverCache;
15
+//import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
17 16
import com.sap.sse.util.SmartFutureCache.EmptyUpdateInterval;
18 17
19 18
public class ManeuverFromDatabase implements ManeuverCache<Competitor, List<Maneuver>, EmptyUpdateInterval> {
20 19
21
- public ManeuverFromDatabase(boolean suspended, DynamicTrackedRaceImpl race,
22
- ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) {
20
+ public ManeuverFromDatabase(/*boolean suspended, DynamicTrackedRaceImpl race,*/
21
+ Map<Competitor, List<Maneuver>> maneuvers) {
23 22
super();
24
- this.suspended = suspended;
25
- this.race = race;
26
- this.maneuverRaceFingerprintRegistry = maneuverRaceFingerprintRegistry;
23
+// this.suspended = suspended;
24
+// this.race = race;
25
+// this.maneuverRaceFingerprintRegistry = maneuverRaceFingerprintRegistry;
26
+ this.maneuvers = maneuvers;
27 27
}
28 28
29 29
boolean suspended;
30
- private DynamicTrackedRaceImpl race;
31
- private ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry;
30
+// private DynamicTrackedRaceImpl race;
31
+// private ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry;
32 32
private static final Logger logger = Logger.getLogger(ManeuverFromDatabase.class.getName());
33 33
Map<Competitor, List<Maneuver>> maneuvers;
34 34
35 35
public void resume() {
36
- logger.info("Found stored set of maneuvers for race "+race.getName()+" with matching fingerprint; loading instead of computing...");
37
- updateManeuversFromRegistry();
38
- suspended = false;
36
+// logger.info("Found stored set of maneuvers for race "+race.getName()+" with matching fingerprint; loading instead of computing...");
37
+// updateManeuversFromRegistry();
38
+// suspended = false;
39
+// logger.info("maneuver geladen");
40
+ logger.log(Level.WARNING, "Method should never be called");
39 41
}
40 42
41
- private void updateManeuversFromRegistry() {
42
- maneuvers = maneuverRaceFingerprintRegistry.loadManeuvers(race, race.getRace().getCourse());
43
- for (final Entry<Competitor, List<Maneuver>> e : maneuverRaceFingerprintRegistry.loadManeuvers(
44
- race, race.getRace().getCourse()).entrySet()) {
45
- race.updateManeuvers(e.getKey(), e.getValue().stream().sorted(TimedComparator.INSTANCE).collect(Collectors.toList()));
46
- }
47
- }
43
+// private void updateManeuversFromRegistry() {
44
+// maneuvers = maneuverRaceFingerprintRegistry.loadManeuvers(race, race.getRace().getCourse());
45
+// for (final Entry<Competitor, List<Maneuver>> e : maneuverRaceFingerprintRegistry.loadManeuvers(
46
+// race, race.getRace().getCourse()).entrySet()) {
47
+// race.updateManeuvers(e.getKey(), e.getValue().stream().sorted(TimedComparator.INSTANCE).collect(Collectors.toList()));
48
+// }
49
+// }
48 50
49 51
public void suspend() {
50 52
synchronized (this) {
... ...
@@ -60,5 +62,6 @@ public class ManeuverFromDatabase implements ManeuverCache<Competitor, List<Mane
60 62
@Override
61 63
public void triggerUpdate(Competitor key, EmptyUpdateInterval updateInterval) {
62 64
logger.log(Level.WARNING, "If Fingerprint matches, no Update should be triggered");
65
+ //TODO change to smartFutureCache in Delegate
63 66
}
64 67
}
... ...
\ No newline at end of file
java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverhash/impl/ManeuverFromSmartFutureCache.java
... ...
@@ -0,0 +1,103 @@
1
+package com.sap.sailing.domain.maneuverhash.impl;
2
+
3
+import java.util.Collections;
4
+import java.util.List;
5
+
6
+import com.sap.sailing.domain.base.CPUMeteringType;
7
+import com.sap.sailing.domain.base.Competitor;
8
+import com.sap.sailing.domain.common.NoWindException;
9
+import com.sap.sailing.domain.maneuverdetection.ManeuverDetector;
10
+import com.sap.sailing.domain.maneuverhash.ManeuverCache;
11
+import com.sap.sailing.domain.tracking.Maneuver;
12
+import com.sap.sailing.domain.tracking.TrackedRace;
13
+import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
14
+import com.sap.sse.common.Duration;
15
+import com.sap.sse.util.SmartFutureCache;
16
+import com.sap.sse.util.SmartFutureCache.AbstractCacheUpdater;
17
+import com.sap.sse.util.SmartFutureCache.EmptyUpdateInterval;
18
+
19
+public class ManeuverFromSmartFutureCache implements ManeuverCache<Competitor, List<Maneuver>, EmptyUpdateInterval> {
20
+
21
+// private final TrackedRace race;
22
+ private final SmartFutureCache<Competitor, List<Maneuver>, EmptyUpdateInterval> smartFutureCache;
23
+
24
+ public ManeuverFromSmartFutureCache(DynamicTrackedRaceImpl race) {
25
+// this.race = race;
26
+// this.smartFutureCache = new SmartFutureCache<Competitor, List<Maneuver>, EmptyUpdateInterval>(
27
+// new AbstractCacheUpdater<Competitor, List<Maneuver>, EmptyUpdateInterval>() {
28
+// @Override
29
+// public List<Maneuver> computeCacheUpdate(Competitor competitor, EmptyUpdateInterval updateInterval)
30
+// throws NoWindException {
31
+// return race.getTrackedRegatta().callWithCPUMeterWithException(()->{
32
+// Duration averageIntervalBetweenRawFixes = race.getTrack(competitor).getAverageIntervalBetweenRawFixes();
33
+// if (averageIntervalBetweenRawFixes != null) {
34
+// ManeuverDetector maneuverDetector;
35
+// maneuverDetector = race.getManeuverDetectorPerCompetitorCache().getValue(competitor);
36
+//
37
+// List<Maneuver> maneuvers = race.computeManeuvers(competitor, maneuverDetector);
38
+// return maneuvers;
39
+// } else {
40
+// return Collections.emptyList();
41
+// }
42
+// }, CPUMeteringType.MANEUVER_DETECTION.name());
43
+// }
44
+// }, /* nameForLocks */ "Maneuver cache for race " + race.getRace().getName());
45
+
46
+
47
+ this.smartFutureCache= new SmartFutureCache<Competitor, List<Maneuver>, EmptyUpdateInterval>(
48
+ new AbstractCacheUpdater<Competitor, List<Maneuver>, EmptyUpdateInterval>() {
49
+ @Override
50
+ public List<Maneuver> computeCacheUpdate(Competitor competitor, EmptyUpdateInterval updateInterval)
51
+ throws NoWindException {
52
+ return race.getTrackedRegatta().callWithCPUMeterWithException(()->{
53
+ Duration averageIntervalBetweenRawFixes = race.getTrack(competitor).getAverageIntervalBetweenRawFixes();
54
+ if (averageIntervalBetweenRawFixes != null) {
55
+ ManeuverDetector maneuverDetector;
56
+ // FIXME The LowGPSSamplingRateManeuverDetectorImpl doesn't work very well; it recognizes many tacks only as bear-away and doesn't seem to have any noticeable benefits... See ORC Worlds 2019 ORC A Long Offshore
57
+ // if (averageIntervalBetweenRawFixes.asSeconds() >= 30) {
58
+ // maneuverDetector = new LowGPSSamplingRateManeuverDetectorImpl(TrackedRaceImpl.this, competitor);
59
+ // } else {
60
+ maneuverDetector = race.getManeuverDetectorPerCompetitorCache().getValue(competitor);
61
+ // }
62
+ List<Maneuver> maneuvers = race.computeManeuvers(competitor, maneuverDetector);
63
+ return maneuvers;
64
+ } else {
65
+ return Collections.emptyList();
66
+ }
67
+ }, CPUMeteringType.MANEUVER_DETECTION.name());
68
+ }
69
+ },//.computeCacheUpdate(competitor, null),
70
+ /* nameForLocks */ "Maneuver cache for race " + race.getRace().getName());
71
+ }
72
+
73
+
74
+
75
+
76
+
77
+
78
+
79
+ @Override
80
+ public void resume() {
81
+ smartFutureCache.resume();
82
+
83
+ }
84
+
85
+ @Override
86
+ public List<Maneuver> get(Competitor key, boolean waitForLatest) {
87
+// smartFutureCache.getAbstractCacheUpdater().computeCacheUpdate(key);
88
+ return smartFutureCache.get(key, waitForLatest);
89
+ }
90
+
91
+ @Override
92
+ public void suspend() {
93
+ smartFutureCache.suspend();
94
+
95
+ }
96
+
97
+ @Override
98
+ public void triggerUpdate(Competitor key, EmptyUpdateInterval updateInterval) {
99
+ smartFutureCache.triggerUpdate(key, updateInterval);
100
+
101
+ }
102
+
103
+}
java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/ManeuverRaceFingerprintConversionTest.java
... ...
@@ -70,7 +70,7 @@ public class ManeuverRaceFingerprintConversionTest extends OnlineTracTracBasedTe
70 70
//List<Competitor> competetors = trackedRace1.getCompetitor(null);
71 71
final Map<Competitor, List<Maneuver>> maneuvers = new HashMap<>();
72 72
for (Competitor competitor : getRace().getCompetitors()) {
73
- List<Maneuver> maneuversForCompetitor = (List<Maneuver>) trackedRace1.getManeuvers(competitor, false);
73
+ List<Maneuver> maneuversForCompetitor = (List<Maneuver>) trackedRace1.getManeuvers(competitor, true);
74 74
maneuvers.put(competitor,maneuversForCompetitor);
75 75
}
76 76
//final Map<Competitor, List<Maneuver>> maneuvers = trackedRace1.getManeuvers(null, false);
java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RacingEventServiceImpl.java
... ...
@@ -1011,6 +1011,7 @@ Replicator {
1011 1011
1012 1012
@Override
1013 1013
public ManeuverRaceFingerprint getManeuverRaceFingerprint(RaceIdentifier raceIdentifier) {
1014
+ logger.log(Level.INFO, "Getting Maneuver fingerprint");
1014 1015
return maneuverRaceFingerprints.get(raceIdentifier);
1015 1016
}
1016 1017
... ...
@@ -3096,6 +3097,7 @@ Replicator {
3096 3097
TrackedRace trackedRace = getExistingTrackedRace(regatta, race);
3097 3098
if (trackedRace != null) {
3098 3099
removeStoredMarkPassings(trackedRace.getRaceIdentifier());
3100
+ removeStoredManeuvers(trackedRace.getRaceIdentifier());
3099 3101
TrackedRegatta trackedRegatta = getTrackedRegatta(regatta);
3100 3102
final boolean isTrackedRacesBecameEmpty;
3101 3103
if (trackedRegatta != null) {
java/com.sap.sse/src/com/sap/sse/util/ManeuverCache.java
... ...
@@ -1,15 +0,0 @@
1
-package com.sap.sse.util;
2
-
3
-
4
-import com.sap.sse.util.SmartFutureCache.UpdateInterval;
5
-
6
-public interface ManeuverCache<K, V, U extends UpdateInterval<U>>{
7
-
8
- void resume();
9
-
10
- V get(K key, boolean waitForLatest);
11
-
12
- void suspend();
13
-
14
- void triggerUpdate(K key, U updateInterval);
15
-}
... ...
\ No newline at end of file
java/com.sap.sse/src/com/sap/sse/util/SmartFutureCache.java
... ...
@@ -77,7 +77,7 @@ import com.sap.sse.util.impl.KnowsExecutorAndTracingGetImpl;
77 77
* @author Axel Uhl (D043530)
78 78
*
79 79
*/
80
-public class SmartFutureCache<K, V, U extends UpdateInterval<U>> implements ManeuverCache<K, V, U> {
80
+public class SmartFutureCache<K, V, U extends UpdateInterval<U>> {
81 81
private static final Logger logger = Logger.getLogger(SmartFutureCache.class.getName());
82 82
83 83
/**
... ...
@@ -413,7 +413,6 @@ public class SmartFutureCache<K, V, U extends UpdateInterval<U>> implements Mane
413 413
}
414 414
}
415 415
416
- @Override
417 416
public void suspend() {
418 417
logger.finest("suspending cache "+nameForLocks);
419 418
synchronized (ongoingRecalculations) {
... ...
@@ -421,7 +420,6 @@ public class SmartFutureCache<K, V, U extends UpdateInterval<U>> implements Mane
421 420
}
422 421
}
423 422
424
- @Override
425 423
public void resume() {
426 424
synchronized (ongoingRecalculations) {
427 425
suspended = false;
... ...
@@ -459,7 +457,6 @@ public class SmartFutureCache<K, V, U extends UpdateInterval<U>> implements Mane
459 457
* If the running task has a different setting for the caller's waiting for the task, the task will be canceled
460 458
* (which may or may not work), and a new task with the joined update interval is scheduled.
461 459
*/
462
- @Override
463 460
public void triggerUpdate(final K key, U updateInterval) {
464 461
// establish and maintain the following invariant: after lock on ongoingRecalculations is released,
465 462
// no Future contained in it is in cancelled state
... ...
@@ -675,7 +672,6 @@ public class SmartFutureCache<K, V, U extends UpdateInterval<U>> implements Mane
675 672
* ongoing, the result of that ongoing re-calculation is returned. When {@link #remove(Object)} has been called for the {@code key} and
676 673
* no update has finished computing since then, this method will also return {@code null} in case {@code waitForLatest} is {@code false}.
677 674
*/
678
- @Override
679 675
public V get(final K key, boolean waitForLatest) {
680 676
final V value;
681 677
final Future<V> future;