java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackedRaceStartTimeUpdateForDependentStartTimeTest.java
... ...
@@ -6,6 +6,7 @@ import static org.junit.jupiter.api.Assertions.assertNull;
6 6
7 7
import java.io.IOException;
8 8
import java.net.MalformedURLException;
9
+import java.util.List;
9 10
10 11
import org.junit.jupiter.api.Test;
11 12
... ...
@@ -19,11 +20,17 @@ import com.sap.sailing.domain.abstractlog.race.impl.RaceLogPassChangeEventImpl;
19 20
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartTimeEventImpl;
20 21
import com.sap.sailing.domain.abstractlog.race.impl.SimpleRaceLogIdentifierImpl;
21 22
import com.sap.sailing.domain.base.CompetitorWithBoat;
23
+import com.sap.sailing.domain.base.Fleet;
24
+import com.sap.sailing.domain.base.RaceColumn;
25
+import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
26
+import com.sap.sailing.domain.leaderboard.Leaderboard;
22 27
import com.sap.sailing.domain.racelog.RaceLogAndTrackedRaceResolver;
23 28
import com.sap.sailing.domain.tracking.StartTimeChangedListener;
24 29
import com.sap.sailing.domain.tracking.TrackedRace;
25 30
import com.sap.sse.common.Duration;
26 31
import com.sap.sse.common.TimePoint;
32
+import com.sap.sse.common.Util.Pair;
33
+import com.sap.sse.common.Util.Triple;
27 34
import com.sap.sse.common.impl.MillisecondsTimePoint;
28 35
29 36
public class TrackedRaceStartTimeUpdateForDependentStartTimeTest extends TrackBasedTest {
... ...
@@ -47,6 +54,13 @@ public class TrackedRaceStartTimeUpdateForDependentStartTimeTest extends TrackBa
47 54
public TrackedRace resolveTrackedRace(SimpleRaceLogIdentifier identifier) {
48 55
return null;
49 56
}
57
+
58
+ @Override
59
+ public List<Triple<Leaderboard, RaceColumn, Fleet>> getColumnsWithRaceLogForTrackedRace(
60
+ RegattaAndRaceIdentifier trackedRaceIdentifier) {
61
+ // TODO Auto-generated method stub
62
+ return null;
63
+ }
50 64
};
51 65
final TrackedRace r1 = createTestTrackedRace("Regatta", "R1", "J/70", createCompetitorAndBoatsMap(hasso),
52 66
MillisecondsTimePoint.now(), /* useMarkPassingCalculator */ false, raceLogResolver);
java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/tracking/TestTracTracRaceAndCompetitorStatusReconciler.java
... ...
@@ -9,6 +9,7 @@ import static org.mockito.Mockito.mock;
9 9
import static org.mockito.Mockito.when;
10 10
11 11
import java.util.Collections;
12
+import java.util.List;
12 13
import java.util.UUID;
13 14
14 15
import org.junit.jupiter.api.BeforeEach;
... ...
@@ -27,6 +28,8 @@ import com.sap.sailing.domain.abstractlog.race.impl.RaceLogFlagEventImpl;
27 28
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogPassChangeEventImpl;
28 29
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartTimeEventImpl;
29 30
import com.sap.sailing.domain.base.Competitor;
31
+import com.sap.sailing.domain.base.Fleet;
32
+import com.sap.sailing.domain.base.RaceColumn;
30 33
import com.sap.sailing.domain.base.RaceDefinition;
31 34
import com.sap.sailing.domain.base.impl.BoatClassImpl;
32 35
import com.sap.sailing.domain.base.impl.BoatImpl;
... ...
@@ -38,10 +41,12 @@ import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
38 41
import com.sap.sailing.domain.base.impl.TeamImpl;
39 42
import com.sap.sailing.domain.common.LeaderboardNameConstants;
40 43
import com.sap.sailing.domain.common.MaxPointsReason;
44
+import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
41 45
import com.sap.sailing.domain.common.impl.DegreePosition;
42 46
import com.sap.sailing.domain.common.impl.MeterDistance;
43 47
import com.sap.sailing.domain.common.racelog.Flags;
44 48
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
49
+import com.sap.sailing.domain.leaderboard.Leaderboard;
45 50
import com.sap.sailing.domain.leaderboard.impl.FlexibleLeaderboardImpl;
46 51
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
47 52
import com.sap.sailing.domain.leaderboard.impl.ThresholdBasedResultDiscardingRuleImpl;
... ...
@@ -55,6 +60,7 @@ import com.sap.sse.common.Color;
55 60
import com.sap.sse.common.Duration;
56 61
import com.sap.sse.common.TimePoint;
57 62
import com.sap.sse.common.Util.Pair;
63
+import com.sap.sse.common.Util.Triple;
58 64
import com.sap.sse.common.impl.MillisecondsTimePoint;
59 65
import com.sap.sse.metering.CPUMeter;
60 66
import com.tractrac.model.lib.api.event.ICompetitor;
... ...
@@ -112,6 +118,14 @@ public class TestTracTracRaceAndCompetitorStatusReconciler {
112 118
public TrackedRace resolveTrackedRace(SimpleRaceLogIdentifier identifier) {
113 119
return null;
114 120
}
121
+
122
+ @Override
123
+ public List<Triple<Leaderboard, RaceColumn, Fleet>> getColumnsWithRaceLogForTrackedRace(
124
+ RegattaAndRaceIdentifier trackedRaceIdentifier) {
125
+ // TODO Auto-generated method stub
126
+ return null;
127
+ }
128
+
115 129
});
116 130
tractracCompetitor = mock(ICompetitor.class);
117 131
tractracRaceCompetitor = mock(IRaceCompetitor.class);
... ...
@@ -243,6 +257,13 @@ public class TestTracTracRaceAndCompetitorStatusReconciler {
243 257
public TrackedRace resolveTrackedRace(SimpleRaceLogIdentifier identifier) {
244 258
return null;
245 259
}
260
+
261
+ @Override
262
+ public List<Triple<Leaderboard, RaceColumn, Fleet>> getColumnsWithRaceLogForTrackedRace(
263
+ RegattaAndRaceIdentifier trackedRaceIdentifier) {
264
+ // TODO Auto-generated method stub
265
+ return null;
266
+ }
246 267
});
247 268
final TimePoint noneStatusTimePoint = manualAbortTimePoint.plus(Duration.ONE_MINUTE.times(1));
248 269
when(tractracRace.getStatusLastChangedTime()).thenReturn(noneStatusTimePoint.asMillis());
java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/DomainFactory.java
... ...
@@ -34,6 +34,8 @@ import com.sap.sailing.domain.tracking.impl.RaceAbortedHandler;
34 34
import com.sap.sailing.domain.tracking.impl.StartTimeUpdateHandler;
35 35
import com.sap.sse.common.IsManagedByCache;
36 36
import com.sap.sse.common.TimePoint;
37
+import com.sap.sse.common.Util.Pair;
38
+import com.sap.sse.common.Util.Triple;
37 39
import com.sap.sse.util.ObjectInputStreamResolvingAgainstCache;
38 40
import com.sap.sse.util.ObjectInputStreamResolvingAgainstCache.ResolveListener;
39 41
... ...
@@ -48,6 +50,16 @@ public interface DomainFactory extends SharedDomainFactory<RaceLogAndTrackedRace
48 50
public TrackedRace resolveTrackedRace(SimpleRaceLogIdentifier identifier) {
49 51
return null;
50 52
}
53
+
54
+ @Override
55
+ public List<Triple<Leaderboard, RaceColumn, Fleet>> getColumnsWithRaceLogForTrackedRace(
56
+ RegattaAndRaceIdentifier trackedRaceIdentifier) {
57
+ // TODO Auto-generated method stub
58
+ return null;
59
+ }
60
+
61
+
62
+
51 63
};
52 64
53 65
/**
java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/RegattaRegistry.java
... ...
@@ -3,7 +3,9 @@ package com.sap.sailing.domain.base;
3 3
import java.util.ConcurrentModificationException;
4 4
5 5
import com.sap.sailing.domain.common.RegattaIdentifier;
6
+import com.sap.sailing.domain.tracking.TrackedRace;
6 7
import com.sap.sailing.domain.tracking.TrackedRegattaListener;
8
+import com.sap.sse.common.Util.Pair;
7 9
8 10
public interface RegattaRegistry {
9 11
/**
java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverhash/impl/ManeuverCacheDelegate.java
... ...
@@ -65,9 +65,9 @@ public class ManeuverCacheDelegate implements ManeuverCache<Competitor, List<Man
65 65
public void resume() {
66 66
67 67
// richtigen Ort bestimmen
68
- if (triggerManeuverCacheInvalidationForAllCompetitors) {
69
- triggerManeuverCacheRecalculationForAllCompetitors();
70
- }
68
+// if (triggerManeuverCacheInvalidationForAllCompetitors) {
69
+// triggerManeuverCacheRecalculationForAllCompetitors();
70
+// }
71 71
72 72
ManeuverRaceFingerprint fingerprint;
73 73
race.getRace().getCourse().lockForRead();
... ...
@@ -137,7 +137,7 @@ public class ManeuverCacheDelegate implements ManeuverCache<Competitor, List<Man
137 137
try {
138 138
synchronized (this) {
139 139
140
- cacheToUse.suspend();
140
+ cacheToUse.triggerUpdate(competitor, updateInterval);
141 141
}
142 142
} finally {
143 143
race.getRace().getCourse().unlockAfterRead();
... ...
@@ -147,26 +147,26 @@ public class ManeuverCacheDelegate implements ManeuverCache<Competitor, List<Man
147 147
}
148 148
149 149
150
- public void triggerManeuverCacheRecalculationForAllCompetitors() {
151
- if (cachesSuspended) {
152
- triggerManeuverCacheInvalidationForAllCompetitors = true;
153
- } else {
154
- final List<Competitor> shuffledCompetitors = new ArrayList<>();
155
- for (Competitor competitor : (race.getRace().getCompetitors())) {
156
- shuffledCompetitors.add(competitor);
157
- }
158
- Collections.shuffle(shuffledCompetitors);
159
- for (Competitor competitor : shuffledCompetitors) {
160
- triggerManeuverCacheRecalculation(competitor);
161
- }
162
- }
163
- }
164
-
165
- public void triggerManeuverCacheRecalculation(final Competitor competitor) {
166
- if (cachesSuspended) {
167
- triggerManeuverCacheInvalidationForAllCompetitors = true;
168
- } else {
169
- triggerUpdate(competitor, /* updateInterval */null);
170
- }
171
- }
150
+// public void triggerManeuverCacheRecalculationForAllCompetitors() {
151
+// if (cachesSuspended) {
152
+// triggerManeuverCacheInvalidationForAllCompetitors = true;
153
+// } else {
154
+// final List<Competitor> shuffledCompetitors = new ArrayList<>();
155
+// for (Competitor competitor : (race.getRace().getCompetitors())) {
156
+// shuffledCompetitors.add(competitor);
157
+// }
158
+// Collections.shuffle(shuffledCompetitors);
159
+// for (Competitor competitor : shuffledCompetitors) {
160
+// triggerManeuverCacheRecalculation(competitor);
161
+// }
162
+// }
163
+// }
164
+//
165
+// public void triggerManeuverCacheRecalculation(final Competitor competitor) {
166
+// if (cachesSuspended) {
167
+// triggerManeuverCacheInvalidationForAllCompetitors = true;
168
+// } else {
169
+// triggerUpdate(competitor, /* updateInterval */null);
170
+// }
171
+// }
172 172
}
... ...
\ No newline at end of file
java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverhash/impl/ManeuverFromSmartFutureCache.java
... ...
@@ -68,13 +68,7 @@ public class ManeuverFromSmartFutureCache implements ManeuverCache<Competitor, L
68 68
}
69 69
},//.computeCacheUpdate(competitor, null),
70 70
/* nameForLocks */ "Maneuver cache for race " + race.getRace().getName());
71
- }
72
-
73
-
74
-
75
-
76
-
77
-
71
+ }
78 72
79 73
@Override
80 74
public void resume() {
java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverhash/impl/ManeuverRaceFingerprintImpl.java
... ...
@@ -2,6 +2,7 @@ package com.sap.sailing.domain.maneuverhash.impl;
2 2
3 3
4 4
import java.util.Map;
5
+import java.util.Set;
5 6
import java.util.stream.Collectors;
6 7
7 8
import org.json.simple.JSONObject;
... ...
@@ -11,6 +12,7 @@ import com.sap.sailing.domain.abstractlog.race.analyzing.impl.MarkPassingDataFin
11 12
import com.sap.sailing.domain.base.Competitor;
12 13
import com.sap.sailing.domain.base.Mark;
13 14
import com.sap.sailing.domain.base.Waypoint;
15
+import com.sap.sailing.domain.common.Wind;
14 16
import com.sap.sailing.domain.common.WindSource;
15 17
import com.sap.sailing.domain.common.tracking.GPSFix;
16 18
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
... ...
@@ -221,19 +223,39 @@ public class ManeuverRaceFingerprintImpl implements ManeuverRaceFingerprint {
221 223
}
222 224
223 225
private int calculateWindHash(TrackedRace trackedRace) {
224
-// Set<WindSource> windSoure = trackedRace.getWindSources();
226
+ Set<WindSource> windSoures = trackedRace.getWindSources();
225 227
int res = 0;
226
- String regattaName = trackedRace.getTrackedRegatta().getRegatta().getName();
227
- Map<? extends WindSource, ? extends WindTrack> windTrack = trackedRace.getWindStore().loadWindTracks(regattaName, trackedRace, 10000);
228
- Map<WindSource, WindTrack> gefilterteMap = windTrack.entrySet()
229
- .stream().filter(entry -> entry.getKey().getType().isObserved())
230
- .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
231
- for (Map.Entry<? extends WindSource, ? extends WindTrack> w : gefilterteMap.entrySet() ) {
232
- int k = w.getKey().hashCode();
233
- int v = w.getValue().hashCode();
234
- res = res ^ k;
235
- res = res ^ v;
228
+// String regattaName = trackedRace.getTrackedRegatta().getRegatta().getName();
229
+ Set<WindSource> windSouresToExclude = trackedRace.getWindSourcesToExclude();
230
+
231
+ for(WindSource w : windSoures) {
232
+ if(w.getType().isObserved() && !windSouresToExclude.contains(w)) {
233
+ WindTrack windTrack = trackedRace.getOrCreateWindTrack(w);
234
+ windTrack.lockForRead();
235
+ try {
236
+ int k = w.getId().hashCode();
237
+ int v = 0;
238
+ for(Wind wf : trackedRace.getOrCreateWindTrack(w).getFixes()) {
239
+ v = v + (int) ( wf.getPosition().getLatDeg() + wf.getPosition().getLngDeg() + wf.getKilometersPerHour());
240
+ }
241
+ res = res ^ k;
242
+ res = res ^ v;
243
+ } finally {
244
+ windTrack.unlockAfterRead();
245
+ }
246
+
247
+ }
236 248
}
249
+// Map<? extends WindSource, ? extends WindTrack> windTrack = trackedRace.getOrCreateWindTrack(null)
250
+// Map<WindSource, WindTrack> gefilterteMap = windTrack.entrySet()
251
+// .stream().filter(entry -> entry.getKey().getType().isObserved())
252
+// .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
253
+// for (Map.Entry<? extends WindSource, ? extends WindTrack> w : gefilterteMap.entrySet() ) {
254
+// int k = w.getKey().hashCode();
255
+// int v = w.getValue().hashCode();
256
+// res = res ^ k;
257
+// res = res ^ v;
258
+// }
237 259
return res;
238 260
}
239 261
java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/RaceLogAndTrackedRaceResolver.java
... ...
@@ -1,11 +1,17 @@
1 1
package com.sap.sailing.domain.racelog;
2 2
3
+import java.util.List;
4
+
5
+import com.sap.sailing.domain.abstractlog.race.RaceLog;
3 6
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
4 7
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
5 8
import com.sap.sailing.domain.base.Fleet;
6 9
import com.sap.sailing.domain.base.RaceColumn;
10
+import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
11
+import com.sap.sailing.domain.leaderboard.Leaderboard;
7 12
import com.sap.sailing.domain.regattalike.IsRegattaLike;
8 13
import com.sap.sailing.domain.tracking.TrackedRace;
14
+import com.sap.sse.common.Util.Triple;
9 15
10 16
/**
11 17
* In addition to being able to resolve a race log from a {@link SimpleRaceLogIdentifier}, this
... ...
@@ -22,4 +28,10 @@ public interface RaceLogAndTrackedRaceResolver extends RaceLogResolver {
22 28
* With this, both, the {@link RaceLog} as well as a {@link TrackedRace} can be looked up.
23 29
*/
24 30
TrackedRace resolveTrackedRace(SimpleRaceLogIdentifier identifier);
31
+
32
+ // could be implemtet as dafault
33
+
34
+ List<Triple<Leaderboard, RaceColumn, Fleet>> getColumnsWithRaceLogForTrackedRace(
35
+ RegattaAndRaceIdentifier trackedRaceIdentifier);
36
+
25 37
}
java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceImpl.java
... ...
@@ -339,7 +339,7 @@ DynamicTrackedRace, GPSTrackListener<Competitor, GPSFixMoving> {
339 339
}
340 340
}
341 341
updated(/* time point */null);
342
- maneuverCache.triggerManeuverCacheRecalculationForAllCompetitors();
342
+ triggerManeuverCacheRecalculationForAllCompetitors();
343 343
}
344 344
345 345
@Override
... ...
@@ -350,7 +350,7 @@ DynamicTrackedRace, GPSTrackListener<Competitor, GPSFixMoving> {
350 350
getOrCreateWindTrack(windSource).setMillisecondsOverWhichToAverage(millisecondsOverWhichToAverageWind);
351 351
}
352 352
updated(/* time point */null);
353
- maneuverCache.triggerManeuverCacheRecalculationForAllCompetitors();
353
+ triggerManeuverCacheRecalculationForAllCompetitors();
354 354
notifyListenersWindAveragingChanged(oldMillisecondsOverWhichToAverageWind, millisecondsOverWhichToAverageWind);
355 355
}
356 356
... ...
@@ -407,7 +407,7 @@ DynamicTrackedRace, GPSTrackListener<Competitor, GPSFixMoving> {
407 407
final GPSFix firstFixAfter = result.getFirstFixAfter(fixTimePoint);
408 408
invalidateDistancesFromStarboardSideOfStartLineProjectedOntoLineCache(TimeRange.create(lastFixBefore==null?null:lastFixBefore.getTimePoint(),
409 409
firstFixAfter==null?null:firstFixAfter.getTimePoint()));
410
- maneuverCache.triggerManeuverCacheRecalculationForAllCompetitors();
410
+ triggerManeuverCacheRecalculationForAllCompetitors();
411 411
notifyListeners(fix, mark, firstFixInTrack, addedOrReplaced);
412 412
}
413 413
... ...
@@ -924,7 +924,7 @@ DynamicTrackedRace, GPSTrackListener<Competitor, GPSFixMoving> {
924 924
getRace().getCourse().unlockAfterRead();
925 925
}
926 926
updated(timePointOfLatestEvent);
927
- maneuverCache.triggerManeuverCacheRecalculation(competitor);
927
+ triggerManeuverCacheRecalculation(competitor);
928 928
// update the race times like start, end and the leg times
929 929
if (requiresStartTimeUpdate) {
930 930
invalidateStartTime();
... ...
@@ -1214,7 +1214,7 @@ DynamicTrackedRace, GPSTrackListener<Competitor, GPSFixMoving> {
1214 1214
invalidateDistancesFromStarboardSideOfStartLineProjectedOntoLineCache(TimeRange.create(
1215 1215
fix.getTimePoint().minus(getMillisecondsOverWhichToAverageSpeed()),
1216 1216
fix.getTimePoint().plus(getMillisecondsOverWhichToAverageSpeed())));
1217
- maneuverCache.triggerManeuverCacheRecalculation(competitor);
1217
+ triggerManeuverCacheRecalculation(competitor);
1218 1218
notifyListeners(fix, competitor, addedOrReplaced);
1219 1219
// getAndSet call is atomic which means, that it can be ensured that the listeners are notified only once
1220 1220
final boolean oldGPSFixReceived = gpsFixReceived.getAndSet(true);
java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java
... ...
@@ -32,6 +32,7 @@ import java.util.concurrent.Callable;
32 32
import java.util.concurrent.ConcurrentHashMap;
33 33
import java.util.concurrent.ConcurrentMap;
34 34
import java.util.concurrent.ConcurrentSkipListSet;
35
+import java.util.concurrent.CountDownLatch;
35 36
import java.util.concurrent.ExecutionException;
36 37
import java.util.concurrent.Future;
37 38
import java.util.concurrent.FutureTask;
... ...
@@ -40,6 +41,7 @@ import java.util.function.Consumer;
40 41
import java.util.logging.Level;
41 42
import java.util.logging.Logger;
42 43
import java.util.stream.Collectors;
44
+import java.util.stream.StreamSupport;
43 45
44 46
import org.apache.commons.math.FunctionEvaluationException;
45 47
import org.apache.commons.math.MaxIterationsExceededException;
... ...
@@ -70,8 +72,10 @@ import com.sap.sailing.domain.base.ControlPoint;
70 72
import com.sap.sailing.domain.base.Course;
71 73
import com.sap.sailing.domain.base.CourseListener;
72 74
import com.sap.sailing.domain.base.DomainFactory;
75
+import com.sap.sailing.domain.base.Fleet;
73 76
import com.sap.sailing.domain.base.Leg;
74 77
import com.sap.sailing.domain.base.Mark;
78
+import com.sap.sailing.domain.base.RaceColumn;
75 79
import com.sap.sailing.domain.base.RaceDefinition;
76 80
import com.sap.sailing.domain.base.Regatta;
77 81
import com.sap.sailing.domain.base.RegattaListener;
... ...
@@ -125,6 +129,7 @@ import com.sap.sailing.domain.common.tracking.GPSFixMoving;
125 129
import com.sap.sailing.domain.common.tracking.SensorFix;
126 130
import com.sap.sailing.domain.confidence.ConfidenceBasedWindAverager;
127 131
import com.sap.sailing.domain.confidence.ConfidenceFactory;
132
+import com.sap.sailing.domain.leaderboard.Leaderboard;
128 133
import com.sap.sailing.domain.leaderboard.Leaderboard.RankComparableRank;
129 134
import com.sap.sailing.domain.leaderboard.caching.LeaderboardDTOCalculationReuseCache;
130 135
import com.sap.sailing.domain.leaderboard.impl.CompetitorAndRankComparable;
... ...
@@ -133,6 +138,7 @@ import com.sap.sailing.domain.maneuverdetection.IncrementalManeuverDetector;
133 138
import com.sap.sailing.domain.maneuverdetection.ManeuverDetector;
134 139
import com.sap.sailing.domain.maneuverdetection.ShortTimeAfterLastHitCache;
135 140
import com.sap.sailing.domain.maneuverdetection.impl.IncrementalManeuverDetectorImpl;
141
+import com.sap.sailing.domain.maneuverhash.ManeuverCache;
136 142
import com.sap.sailing.domain.maneuverhash.ManeuverRaceFingerprintRegistry;
137 143
import com.sap.sailing.domain.maneuverhash.impl.ManeuverCacheDelegate;
138 144
import com.sap.sailing.domain.markpassingcalculation.MarkPassingCalculator;
... ...
@@ -185,6 +191,7 @@ import com.sap.sse.common.TimeRange;
185 191
import com.sap.sse.common.Timed;
186 192
import com.sap.sse.common.Util;
187 193
import com.sap.sse.common.Util.Pair;
194
+import com.sap.sse.common.Util.Triple;
188 195
import com.sap.sse.common.impl.DegreeBearingImpl;
189 196
import com.sap.sse.common.impl.MillisecondsTimePoint;
190 197
import com.sap.sse.concurrent.LockUtil;
... ...
@@ -192,6 +199,7 @@ import com.sap.sse.concurrent.NamedReentrantReadWriteLock;
192 199
import com.sap.sse.shared.util.impl.ApproximateTime;
193 200
import com.sap.sse.shared.util.impl.ArrayListNavigableSet;
194 201
import com.sap.sse.util.IdentityWrapper;
202
+import com.sap.sse.util.SmartFutureCache.EmptyUpdateInterval;
195 203
//import com.sap.sse.util.SmartFutureCache;
196 204
//import com.sap.sse.util.SmartFutureCache.AbstractCacheUpdater;
197 205
//import com.sap.sse.util.SmartFutureCache.EmptyUpdateInterval;
... ...
@@ -342,7 +350,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
342 350
* computed. Clients wanting to know maneuvers for the competitor outside of this time interval need to (re-)compute
343 351
* them.
344 352
*/
345
- public transient ManeuverCacheDelegate maneuverCache;
353
+ public transient ManeuverCache<Competitor, List<Maneuver>, EmptyUpdateInterval> maneuverCache;
346 354
347 355
private transient ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry;
348 356
... ...
@@ -690,7 +698,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
690 698
result = windTrack.add(wind);
691 699
if (result) {
692 700
updated(wind.getTimePoint());
693
- maneuverCache.triggerManeuverCacheRecalculationForAllCompetitors();
701
+ triggerManeuverCacheRecalculationForAllCompetitors();
694 702
}
695 703
} else {
696 704
result = false;
... ...
@@ -702,7 +710,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
702 710
public void removeWind(Wind wind, WindSource windSource) {
703 711
getOrCreateWindTrack(windSource).remove(wind);
704 712
updated(/* time point */null); // wind events shouldn't advance race time
705
- maneuverCache.triggerManeuverCacheRecalculationForAllCompetitors();
713
+ triggerManeuverCacheRecalculationForAllCompetitors();
706 714
}
707 715
708 716
@Override
... ...
@@ -809,7 +817,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
809 817
} catch (PatchFailedException e) {
810 818
throw new RuntimeException(e);
811 819
} // a bit unclean: this also tries to work on the DynamicTrackedRaceImpl which isn't fully initialized yet; see also bug6039
812
- maneuverCache.triggerManeuverCacheRecalculationForAllCompetitors(); // a bit unclean: this also tries to work on the DynamicTrackedRaceImpl which isn't fully initialized yet; see also bug6039
820
+ triggerManeuverCacheRecalculationForAllCompetitors(); // a bit unclean: this also tries to work on the DynamicTrackedRaceImpl which isn't fully initialized yet; see also bug6039
813 821
}
814 822
815 823
/**
... ...
@@ -1105,6 +1113,10 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
1105 1113
*/
1106 1114
private final String updateStartOfRaceCacheFieldsMonitor = ""+new Random().nextDouble();
1107 1115
1116
+ private boolean triggerManeuverCacheInvalidationForAllCompetitors;
1117
+
1118
+ protected int attachedRaceLogsCount;
1119
+
1108 1120
protected void updateStartOfRaceCacheFields() {
1109 1121
synchronized (updateStartOfRaceCacheFieldsMonitor) {
1110 1122
TimePoint newStartTime = null;
... ...
@@ -2130,7 +2142,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
2130 2142
}
2131 2143
if (!old.equals(new HashSet<>(getWindSourcesToExclude()))) {
2132 2144
clearAllCachesExceptManeuvers();
2133
- maneuverCache.triggerManeuverCacheRecalculationForAllCompetitors();
2145
+ triggerManeuverCacheRecalculationForAllCompetitors();
2134 2146
}
2135 2147
}
2136 2148
... ...
@@ -2479,7 +2491,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
2479 2491
} finally {
2480 2492
LockUtil.unlockAfterWrite(getMarkPassingsLock(markPassingsForOneCompetitor));
2481 2493
}
2482
- maneuverCache.triggerManeuverCacheRecalculation(competitor);
2494
+ triggerManeuverCacheRecalculation(competitor);
2483 2495
}
2484 2496
}
2485 2497
logger.info("done updating tracked race "+this+"'s data structures...");
... ...
@@ -2893,28 +2905,28 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
2893 2905
return maneuverApproximators.get(competitor).approximate(from, to);
2894 2906
}
2895 2907
2896
-// protected void triggerManeuverCacheRecalculationForAllCompetitors() {
2897
-// if (cachesSuspended) {
2898
-// triggerManeuverCacheInvalidationForAllCompetitors = true;
2899
-// } else {
2900
-// final List<Competitor> shuffledCompetitors = new ArrayList<>();
2901
-// for (Competitor competitor : (getRace().getCompetitors())) {
2902
-// shuffledCompetitors.add(competitor);
2903
-// }
2904
-// Collections.shuffle(shuffledCompetitors);
2905
-// for (Competitor competitor : shuffledCompetitors) {
2906
-// triggerManeuverCacheRecalculation(competitor);
2907
-// }
2908
-// }
2909
-// }
2910
-//
2911
-// public void triggerManeuverCacheRecalculation(final Competitor competitor) {
2912
-// if (cachesSuspended) {
2913
-// triggerManeuverCacheInvalidationForAllCompetitors = true;
2914
-// } else {
2915
-// maneuverCache.triggerUpdate(competitor, /* updateInterval */null);
2916
-// }
2917
-// }
2908
+ protected void triggerManeuverCacheRecalculationForAllCompetitors() {
2909
+ if (cachesSuspended) {
2910
+ triggerManeuverCacheInvalidationForAllCompetitors = true;
2911
+ } else {
2912
+ final List<Competitor> shuffledCompetitors = new ArrayList<>();
2913
+ for (Competitor competitor : (getRace().getCompetitors())) {
2914
+ shuffledCompetitors.add(competitor);
2915
+ }
2916
+ Collections.shuffle(shuffledCompetitors);
2917
+ for (Competitor competitor : shuffledCompetitors) {
2918
+ triggerManeuverCacheRecalculation(competitor);
2919
+ }
2920
+ }
2921
+ }
2922
+
2923
+ public void triggerManeuverCacheRecalculation(final Competitor competitor) {
2924
+ if (cachesSuspended) {
2925
+ triggerManeuverCacheInvalidationForAllCompetitors = true;
2926
+ } else {
2927
+ maneuverCache.triggerUpdate(competitor, /* updateInterval */null);
2928
+ }
2929
+ }
2918 2930
2919 2931
public List<Maneuver> computeManeuvers(Competitor competitor, ManeuverDetector maneuverDetector)
2920 2932
throws NoWindException {
... ...
@@ -2941,7 +2953,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
2941 2953
*/
2942 2954
@Override
2943 2955
public Iterable<Maneuver> getManeuvers(Competitor competitor, TimePoint from, TimePoint to, boolean waitForLatest) {
2944
- List<Maneuver> allManeuvers = maneuverCache.get(competitor, waitForLatest);
2956
+ List<Maneuver> allManeuvers = (List<Maneuver>) maneuverCache.get(competitor, waitForLatest);
2945 2957
List<Maneuver> result;
2946 2958
if (allManeuvers == null) {
2947 2959
result = Collections.emptyList();
... ...
@@ -2953,7 +2965,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
2953 2965
2954 2966
@Override
2955 2967
public Iterable<Maneuver> getManeuvers(Competitor competitor, boolean waitForLatest) {
2956
- List<Maneuver> allManeuvers = maneuverCache.get(competitor, waitForLatest);
2968
+ List<Maneuver> allManeuvers = (List<Maneuver>) maneuverCache.get(competitor, waitForLatest);
2957 2969
List<Maneuver> result;
2958 2970
if (allManeuvers == null) {
2959 2971
result = Collections.emptyList();
... ...
@@ -3132,6 +3144,46 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
3132 3144
crossTrackErrorCache.suspend();
3133 3145
maneuverCache.suspend();
3134 3146
}
3147
+
3148
+
3149
+
3150
+
3151
+
3152
+
3153
+ private void waitForAllRaceLogAttacehd() {
3154
+ final CountDownLatch latchForRaceLogs = new CountDownLatch(1); // alternative schauen
3155
+
3156
+ final Iterable<Triple<Leaderboard, RaceColumn, Fleet>> ecpextedLinks = TrackedRaceImpl.this.getRaceLogResolver()
3157
+ .getColumnsWithRaceLogForTrackedRace(getRaceIdentifier()); //Namen
3158
+ final int numberOfExpecteddRaceLogs = Util.size(ecpextedLinks); // Namen ändern
3159
+
3160
+ AbstractRaceChangeListener raceLogAttachedListener = new AbstractRaceChangeListener() {
3161
+
3162
+ @Override
3163
+ public void raceLogAttached(RaceLog raceLog) {
3164
+ int numberOfAttachedRaceLogs = Util.size(getAttachedRaceLogs());
3165
+ if(numberOfAttachedRaceLogs >=numberOfExpecteddRaceLogs) {
3166
+ latchForRaceLogs.countDown();
3167
+ }
3168
+ }
3169
+ };
3170
+
3171
+ this.addListener(raceLogAttachedListener);
3172
+
3173
+ final int numberOfAttachedRaceLogs = Util.size(getAttachedRaceLogs());
3174
+
3175
+ try {
3176
+ if (numberOfAttachedRaceLogs < numberOfExpecteddRaceLogs) {
3177
+ latchForRaceLogs.await();
3178
+ }
3179
+ } catch (InterruptedException e) {
3180
+ // TODO Auto-generated catch block
3181
+ //Logging hinzufügen
3182
+ e.printStackTrace();
3183
+ } finally {
3184
+ removeListener(raceLogAttachedListener);
3185
+ }
3186
+ }
3135 3187
3136 3188
private void resumeAllCachesNotUpdatingWhileLoading() {
3137 3189
cachesSuspended = false;
... ...
@@ -3147,10 +3199,11 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
3147 3199
}
3148 3200
crossTrackErrorCache.resume();
3149 3201
3150
-// if (triggerManeuverCacheInvalidationForAllCompetitors) {
3151
-// maneuverCache.triggerManeuverCacheRecalculationForAllCompetitors();
3152
-// }
3202
+ if (triggerManeuverCacheInvalidationForAllCompetitors) {
3203
+ triggerManeuverCacheRecalculationForAllCompetitors();
3204
+ }
3153 3205
3206
+ waitForAllRaceLogAttacehd();
3154 3207
maneuverCache.resume();
3155 3208
}
3156 3209
... ...
@@ -3211,6 +3264,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
3211 3264
attachedRaceLogs.put(raceLog.getId(), raceLog);
3212 3265
notifyAll();
3213 3266
invalidateStartTime();
3267
+
3214 3268
}
3215 3269
notifyListenersWhenAttachingRaceLog(raceLog);
3216 3270
}
... ...
@@ -4100,7 +4154,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
4100 4154
// complete maneuver curves can be fed directly into the windEstimation.
4101 4155
maneuverDetectorPerCompetitorCache.clearCache();
4102 4156
shortTimeWindCache.clearCache();
4103
- maneuverCache.triggerManeuverCacheRecalculationForAllCompetitors();
4157
+ triggerManeuverCacheRecalculationForAllCompetitors();
4104 4158
}
4105 4159
4106 4160
/**
java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RacingEventServiceImpl.java
... ...
@@ -2717,21 +2717,35 @@ Replicator {
2717 2717
* {@link RaceColumn#getTrackedRace(Fleet) tracked race assigned} and whose
2718 2718
* {@link RaceColumn#getRaceIdentifier(Fleet) race identifier} equals that of <code>trackedRace</code>.
2719 2719
*/
2720
- private void linkRaceToConfiguredLeaderboardColumns(TrackedRace trackedRace) {
2721
- RegattaAndRaceIdentifier trackedRaceIdentifier = trackedRace.getRaceIdentifier();
2720
+ private List<Triple<Leaderboard, RaceColumn, Fleet>> linkRaceToConfiguredLeaderboardColumns(TrackedRace trackedRace) {
2721
+ final RegattaAndRaceIdentifier trackedRaceIdentifier = trackedRace.getRaceIdentifier();
2722
+ final List<Triple<Leaderboard, RaceColumn, Fleet>> trackedRaceLink = getColumnsWithRaceLogForTrackedRace(trackedRaceIdentifier);
2723
+ for (final Triple<Leaderboard, RaceColumn, Fleet> leaderboardRaceColumnAndFleet : trackedRaceLink) {
2724
+ leaderboardRaceColumnAndFleet.getB().setTrackedRace(leaderboardRaceColumnAndFleet.getC(), trackedRace);
2725
+ replicate(new ConnectTrackedRaceToLeaderboardColumn(leaderboardRaceColumnAndFleet.getA().getName(), leaderboardRaceColumnAndFleet.getB().getName(),
2726
+ leaderboardRaceColumnAndFleet.getC().getName(), trackedRaceIdentifier));
2727
+ }
2728
+ return trackedRaceLink;
2729
+ }
2730
+
2731
+ @Override
2732
+ public List<Triple<Leaderboard, RaceColumn, Fleet>> getColumnsWithRaceLogForTrackedRace(
2733
+ final RegattaAndRaceIdentifier trackedRaceIdentifier) {
2734
+ final List<Triple<Leaderboard, RaceColumn, Fleet>> trackedRaceLink = new ArrayList<>();
2722 2735
for (Leaderboard leaderboard : getLeaderboards().values()) {
2723 2736
for (RaceColumn column : leaderboard.getRaceColumns()) {
2724 2737
for (Fleet fleet : column.getFleets()) {
2725 2738
if (trackedRaceIdentifier.equals(column.getRaceIdentifier(fleet))
2726 2739
&& column.getTrackedRace(fleet) == null) {
2727
- column.setTrackedRace(fleet, trackedRace);
2728
- replicate(new ConnectTrackedRaceToLeaderboardColumn(leaderboard.getName(), column.getName(),
2729
- fleet.getName(), trackedRaceIdentifier));
2740
+ trackedRaceLink.add(new Triple<>(leaderboard, column, fleet));
2730 2741
}
2731 2742
}
2732 2743
}
2733 2744
}
2745
+ return trackedRaceLink;
2734 2746
}
2747
+
2748
+
2735 2749
2736 2750
@Override
2737 2751
public void stopTracking(Regatta regatta, boolean willBeRemoved) throws MalformedURLException, IOException, InterruptedException {