.redirects.gollum
... ...
@@ -0,0 +1,2 @@
1
+---
2
+wiki/howto/onboarding-glossary.md: wiki/howto/glossary.md
java/com.google.gwt.ajaxloader/.settings/com.gwtplugins.gwt.eclipse.core.prefs
... ...
@@ -1,2 +0,0 @@
1
-//gwtVersion_/com.google.gwt.user/lib=
2
-eclipse.preferences.version=1
java/com.google.gwt.dev/.settings/com.gwtplugins.gwt.eclipse.core.prefs
... ...
@@ -1,2 +0,0 @@
1
-//gwtVersion_/com.google.gwt.dev/lib=2.11.1
2
-eclipse.preferences.version=1
java/com.google.gwt.servlet/.settings/com.gwtplugins.gwt.eclipse.core.prefs
... ...
@@ -1,2 +0,0 @@
1
-//gwtVersion_/com.google.gwt.servlet/lib=
2
-eclipse.preferences.version=1
java/com.sap.sailing.aiagent/META-INF/MANIFEST.MF
... ...
@@ -10,9 +10,6 @@ Automatic-Module-Name: com.sap.sailing.aiagent
10 10
Import-Package: com.sap.sailing.aiagent.interfaces,
11 11
com.sap.sailing.domain.abstractlog.race,
12 12
com.sap.sailing.domain.abstractlog.regatta,
13
- com.sap.sailing.domain.leaderboard,
14
- com.sap.sailing.domain.tracking,
15
- com.sap.sailing.domain.tracking.impl,
16 13
com.sap.sailing.domain.shared.tracking,
17 14
com.sap.sse.common,
18 15
com.sap.sse.concurrent,
java/com.sap.sailing.dashboards.gwt/.settings/com.gwtplugins.gwt.eclipse.core.prefs
... ...
@@ -2,8 +2,6 @@
2 2
//gwtVersion_/com.google.gwt.user/lib=2.11.1
3 3
//gwtVersion_/opt/gwt-2.11.0=2.11.0
4 4
//gwtVersion_/opt/gwt-2.11.1=2.11.1
5
-//gwtVersion_/opt/gwt/gwt-2.11.1=2.11.1
6
-//gwtVersion_/opt/gwt/gwt-2.12.2=2.12.2
7 5
//gwtVersion_/opt/gwt-2.12.2=2.12.2
8 6
//gwtVersion_/usr/local/gwt-2.11.0=2.11.0
9 7
//gwtVersion_/usr/local/gwt-2.12.2=2.12.2
java/com.sap.sailing.dashboards.gwt/GWT Dashboards DevMode.launch
... ...
@@ -20,7 +20,6 @@
20 20
</listAttribute>
21 21
<booleanAttribute key="org.eclipse.jdt.debug.ui.CONSIDER_INHERITED_MAIN" value="true"/>
22 22
<booleanAttribute key="org.eclipse.jdt.debug.ui.INCLUDE_EXTERNAL_JARS" value="true"/>
23
- <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
24 23
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
25 24
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8&quot; javaProject=&quot;com.sap.sailing.gwt.ui&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
26 25
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#13;&#10; &lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;com.sap.sailing.dashboards.gwt&quot;/&gt;&#13;&#10;&lt;/runtimeClasspathEntry&gt;&#13;&#10;"/>
java/com.sap.sailing.dashboards.gwt/GWT Dashboards SDM.launch
... ...
@@ -23,7 +23,6 @@
23 23
<booleanAttribute key="org.eclipse.jdt.debug.ui.CONSIDER_INHERITED_MAIN" value="true"/>
24 24
<booleanAttribute key="org.eclipse.jdt.debug.ui.INCLUDE_EXTERNAL_JARS" value="true"/>
25 25
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
26
- <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
27 26
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
28 27
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8&quot; javaProject=&quot;com.sap.sailing.gwt.ui&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#10;"/>
29 28
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#10; &lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;com.sap.sailing.dashboards.gwt&quot;/&gt;&#10;&lt;/runtimeClasspathEntry&gt;&#10;"/>
java/com.sap.sailing.datamining.shared/.settings/com.gwtplugins.gwt.eclipse.core.prefs
... ...
@@ -1,8 +1,6 @@
1 1
//gwtVersion_/opt/gwt-2.11.0=2.11.0
2 2
//gwtVersion_/opt/gwt-2.11.1=2.11.1
3
-//gwtVersion_/opt/gwt/gwt-2.11.1=2.11.1
4 3
//gwtVersion_/opt/gwt-2.12.2=2.12.2
5
-//gwtVersion_/opt/gwt/gwt-2.12.2=2.12.2
6 4
//gwtVersion_/usr/local/gwt-2.11.0=2.11.0
7 5
//gwtVersion_/usr/local/gwt-2.12.2=2.12.2
8 6
eclipse.preferences.version=1
java/com.sap.sailing.datamining/.settings/com.gwtplugins.gwt.eclipse.core.prefs
... ...
@@ -1,8 +1,6 @@
1 1
//gwtVersion_/opt/gwt-2.11.0=2.11.0
2 2
//gwtVersion_/opt/gwt-2.11.1=2.11.1
3
-//gwtVersion_/opt/gwt/gwt-2.11.1=2.11.1
4 3
//gwtVersion_/opt/gwt-2.12.2=2.12.2
5
-//gwtVersion_/opt/gwt/gwt-2.12.2=2.12.2
6 4
//gwtVersion_/usr/local/gwt-2.11.0=2.11.0
7 5
//gwtVersion_/usr/local/gwt-2.12.2=2.12.2
8 6
eclipse.preferences.version=1
java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/WindSourceType.java
... ...
@@ -14,57 +14,57 @@ public enum WindSourceType {
14 14
/**
15 15
* Manually entered via a web form or received through a REST service call, e.g., from BeTomorrow's estimation
16 16
*/
17
- WEB(true, 0.9, /* useSpeed */ true, true),
17
+ WEB(true, 0.9, /* useSpeed */ true, /* observed */ true),
18 18
19 19
/**
20 20
* Measured using wind sensors
21 21
*/
22
- EXPEDITION(true, 0.9, /* useSpeed */ true, true),
22
+ EXPEDITION(true, 0.9, /* useSpeed */ true, /* observed */ true),
23 23
24 24
/**
25 25
* Estimates wind conditions by analyzing the boat tracks; may not have results for all time points, e.g.,
26 26
* because at a given time point all boats may sail on the same tack and hence no averaging between the
27 27
* two tacks is possible. This is the more likely to happen the smaller the fleet tracked is.
28 28
*/
29
- TRACK_BASED_ESTIMATION(false, 0.1, /* useSpeed */ false, false),
29
+ TRACK_BASED_ESTIMATION(false, 0.1, /* useSpeed */ false, /* observed */ false),
30 30
31 31
/**
32 32
* Estimates wind conditions by analyzing the maneuvers of all boat tracks closely interoperating with incremental
33 33
* maneuver detector.
34 34
*/
35
- MANEUVER_BASED_ESTIMATION(false, 0.001, /* useSpeed */ false, false),
35
+ MANEUVER_BASED_ESTIMATION(false, 0.001, /* useSpeed */ false, /* observed */ false),
36 36
37 37
/**
38 38
* Inferred from the race course layout if the course is known to have its first leg be an upwind leg. This
39 39
* source has very low confidence and must be superseded by any other wind source.
40 40
*/
41
- COURSE_BASED(false, 0.01, /* useSpeed */ false, false),
41
+ COURSE_BASED(false, 0.01, /* useSpeed */ false, /* observed */ false),
42 42
43 43
/**
44 44
* Wind estimation combined from all other wind sources, using <code>TrackedRace.getWind(...)</code>, based on
45 45
* confidences
46 46
*/
47
- COMBINED(false, 0.9, /* useSpeed */ true, false),
47
+ COMBINED(false, 0.9, /* useSpeed */ true, /* observed */ false),
48 48
49 49
/**
50 50
* Manually entered by the race committee over the app. As the race committee measures the wind several times over races for documentation purposes,
51 51
* their measures are stored in the race log.
52 52
*
53 53
*/
54
- RACECOMMITTEE(false, 0.9, /* useSpeed */ true, true),
54
+ RACECOMMITTEE(false, 0.9, /* useSpeed */ true, /* observed */ true),
55 55
56 56
/**
57 57
* Like {@link #COMBINED}, only that when combined with an ID into a {@link WindSourceWithAdditionalID} then the
58 58
* position for the wind is taken to be the middle of the tracked leg whose number is identified by the ID.
59 59
*/
60
- LEG_MIDDLE(/* can be stored */ false, /* base confidence */ 0.9, /* useSpeed */ true, false),
60
+ LEG_MIDDLE(/* can be stored */ false, /* base confidence */ 0.9, /* useSpeed */ true, /* observed */ false),
61 61
62 62
/**
63 63
* A wind measurement spot as provided by https://www.windfinder.com; when used with a
64 64
* {@link WindSourceWithAdditionalID}, the {@link WindSourceWithAdditionalID#getId() ID} is
65 65
* the WindFinder's "Spot ID" such as "10044N" for Kiel Lighthouse.
66 66
*/
67
- WINDFINDER(/* can be stored */ true, /* base confidence */ 0.3, /* useSpeed */ true, true);
67
+ WINDFINDER(/* can be stored */ true, /* base confidence */ 0.3, /* useSpeed */ true, /* observed */ true);
68 68
69 69
private final boolean canBeStored;
70 70
java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/DomainObjectFactory.java
... ...
@@ -236,7 +236,6 @@ public interface DomainObjectFactory {
236 236
237 237
Map<RaceIdentifier, ManeuverRaceFingerprint> loadFingerprintsForManeuverHashes();
238 238
239
-
240 239
/**
241 240
* For races that have a {@link MarkPassingRaceFingerprint} stored in the database (see {@link #loadFingerprintsForMarkPassingHashes()})
242 241
* a caller can load the corresponding mark passings with this method.
java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/FieldNames.java
... ...
@@ -197,11 +197,15 @@ public enum FieldNames {
197 197
// MARKPASSINGS collection
198 198
MARK_PASSINGS_FINGERPRINT, MARK_PASSINGS,
199 199
200
- // MANEUVER collection
201
- MANEUVER_FINGERPRINT, MANEUVER, TYPE, TACK, POSITION_LAT_RAD, POSITION_LNG_RAD, TIMEPOINT, MAIN_CURVE_BOUNDARIES, MANEUVER_CURVE_WITH_STABLE_SPEED_AND_COURSE_BOUNDERIES, MAX_TURNING_RATE_IN_DEGREE_PER_SECOUND, MANEUVER_LOSS,
202
- //Test
203
- TIMEPOINT_BEFORE, TIMEPOINT_AFTER, SPEED_WITH_BEARING_BEFORE, SPEED_WITH_BEARING_AFTER, DIRECTION_CHANGE_IN_DEGREES, LOWEST_SPEED, HIGHEST_SPEED,
204
- DISTANCE_SAILED_POMA, DISTANCE_SAILED_INMPOMA, SPEED_WITH_BEARING_BEFORE_DEGREES, SPEED_WITH_BEARING_BEFORE_SPEED, SPEED_WITH_BEARING_AFTER_DEGREES, SPEED_WITH_BEARING_AFTER_SPEED,
205
- START_POSITION_LAT_RAD, START_POSITION_LNG_RAD, END_POSITION_LAT_RAD, END_POSITION_LNG_RAD, MIDDLE_MAEUVER_ANGLE, DURATION
200
+ // MANEUVERS collection:
201
+ MANEUVER_FINGERPRINT, MANEUVERS, TYPE, TACK, POSITION_LAT_RAD, POSITION_LNG_RAD, TIMEPOINT, MAIN_CURVE_BOUNDARIES,
202
+ MANEUVER_CURVE_WITH_STABLE_SPEED_AND_COURSE_BOUNDERIES, MAX_TURNING_RATE_IN_DEGREE_PER_SECOUND, MANEUVER_LOSS,
203
+ // MANEUVERS main curve boundaries properties, see MAIN_CURVE_BOUNDARIES field above
204
+ MANEUVER_TIMEPOINT_BEFORE, MANEUVER_TIMEPOINT_AFTER, MANEUVER_SPEED_WITH_BEARING_BEFORE, MANEUVER_SPEED_WITH_BEARING_AFTER,
205
+ MANEUVER_DIRECTION_CHANGE_IN_DEGREES, MANEUVER_LOWEST_SPEED, MANEUVER_HIGHEST_SPEED,
206
+ MANEUVER_DISTANCE_SAILED_POMA, MANEUVER_DISTANCE_SAILED_INMPOMA, MANEUVER_SPEED_WITH_BEARING_BEFORE_DEGREES,
207
+ MANEUVER_SPEED_WITH_BEARING_BEFORE_SPEED, MANEUVER_SPEED_WITH_BEARING_AFTER_DEGREES, MANEUVER_SPEED_WITH_BEARING_AFTER_SPEED,
208
+ MANEUVER_START_POSITION_LAT_RAD, MANEUVER_START_POSITION_LNG_RAD, MANEUVER_END_POSITION_LAT_RAD,
209
+ MANEUVER_END_POSITION_LNG_RAD, MIDDLE_MAEUVER_ANGLE, MANEUVER_LOSS_DURATION
206 210
;
207 211
}
java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/MongoObjectFactory.java
... ...
@@ -250,7 +250,6 @@ public interface MongoObjectFactory {
250 250
251 251
void removeMarkPassings(RaceIdentifier raceIdentifier);
252 252
253
-
254 253
void storeManeuvers(RaceIdentifier raceIdentifier, ManeuverRaceFingerprint fingerprint, Course course, Map<Competitor, List<Maneuver>> maneuvers);
255 254
256 255
void removeManeuvers(RaceIdentifier raceIdentifier);
java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/CollectionNames.java
... ...
@@ -2,6 +2,8 @@ package com.sap.sailing.domain.persistence.impl;
2 2
3 3
import com.sap.sailing.domain.base.RaceDefinition;
4 4
import com.sap.sailing.domain.common.tracking.GPSFix;
5
+import com.sap.sailing.domain.maneuverhash.ManeuverRaceFingerprint;
6
+import com.sap.sailing.domain.markpassinghash.MarkPassingRaceFingerprint;
5 7
import com.sap.sailing.domain.tracking.RaceTrackingConnectivityParameters;
6 8
7 9
/**
... ...
@@ -123,13 +125,12 @@ public enum CollectionNames {
123 125
ANNIVERSARIES,
124 126
125 127
/**
126
- * Contains the Hashes for the {@link MarkPassingHashFingerprint}
128
+ * Contains the hashes for the {@link MarkPassingRaceFingerprint} and the mark passings for those races
127 129
*/
128 130
MARKPASSINGS,
131
+
129 132
/**
130
- * Contains the Hashes for the
133
+ * Contains the hashes for the {@link ManeuverRaceFingerprint} and the maneuvers for those races
131 134
*/
132
-
133
- MANEUVER;
134
-
135
+ MANEUVERS;
135 136
}
java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java
... ...
@@ -244,10 +244,10 @@ import com.sap.sailing.domain.leaderboard.impl.RegattaLeaderboardWithOtherTieBre
244 244
import com.sap.sailing.domain.leaderboard.impl.ThresholdBasedResultDiscardingRuleImpl;
245 245
import com.sap.sailing.domain.leaderboard.meta.LeaderboardGroupMetaLeaderboard;
246 246
import com.sap.sailing.domain.maneuverhash.ManeuverRaceFingerprint;
247
+import com.sap.sailing.domain.maneuverhash.ManeuverRaceFingerprintFactory;
247 248
import com.sap.sailing.domain.maneuverhash.MarkPassingProxy;
248
-import com.sap.sailing.domain.maneuverhash.impl.ManeuverRaceFingerprintImpl;
249 249
import com.sap.sailing.domain.markpassinghash.MarkPassingRaceFingerprint;
250
-import com.sap.sailing.domain.markpassinghash.impl.MarkPassingRaceFingerprintImpl;
250
+import com.sap.sailing.domain.markpassinghash.MarkPassingRaceFingerprintFactory;
251 251
import com.sap.sailing.domain.persistence.DomainObjectFactory;
252 252
import com.sap.sailing.domain.persistence.FieldNames;
253 253
import com.sap.sailing.domain.persistence.MongoRaceLogStoreFactory;
... ...
@@ -3253,7 +3253,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
3253 3253
try {
3254 3254
final JSONObject json = Helpers.toJSONObjectSafe(
3255 3255
new JSONParser().parse(((Document) currentDocument.get(FieldNames.MARK_PASSINGS_FINGERPRINT.name())).toJson()));
3256
- fingerprint = new MarkPassingRaceFingerprintImpl(json);
3256
+ fingerprint = MarkPassingRaceFingerprintFactory.INSTANCE.fromJson(json);
3257 3257
} catch (JsonDeserializationException | ParseException e) {
3258 3258
logger.log(Level.WARNING, "Problem de-serializing mark passings from document; ignoring", e);
3259 3259
fingerprint = null;
... ...
@@ -3293,15 +3293,13 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
3293 3293
return new Pair<>(waypoint, markPassing);
3294 3294
}
3295 3295
3296
- // Methods for ManeuverFingerprint - not finished
3297
-
3298 3296
private Pair<RaceIdentifier, ManeuverRaceFingerprint> loadManeuversFingerprint(final Document currentDocument) {
3299 3297
final RaceIdentifier raceIdentifier = loadRaceIdentifier(currentDocument);
3300 3298
ManeuverRaceFingerprint fingerprint;
3301 3299
try {
3302 3300
final JSONObject json = Helpers.toJSONObjectSafe(
3303 3301
new JSONParser().parse(((Document) currentDocument.get(FieldNames.MANEUVER_FINGERPRINT.name())).toJson()));
3304
- fingerprint = new ManeuverRaceFingerprintImpl(json);
3302
+ fingerprint = ManeuverRaceFingerprintFactory.INSTANCE.fromJson(json);
3305 3303
} catch (JsonDeserializationException | ParseException e) {
3306 3304
logger.log(Level.WARNING, "Problem de-serializing maneuvers from document; ignoring", e);
3307 3305
fingerprint = null;
... ...
@@ -3309,10 +3307,9 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
3309 3307
return new Pair<>(raceIdentifier, fingerprint);
3310 3308
}
3311 3309
3312
-
3313 3310
@Override
3314 3311
public Map<RaceIdentifier, ManeuverRaceFingerprint> loadFingerprintsForManeuverHashes() {
3315
- final MongoCollection<Document> maneuversCollection = database.getCollection(CollectionNames.MANEUVER.name());
3312
+ final MongoCollection<Document> maneuversCollection = database.getCollection(CollectionNames.MANEUVERS.name());
3316 3313
maneuversCollection.createIndex(new Document()
3317 3314
.append(FieldNames.EVENT_NAME.name(), 1)
3318 3315
.append(FieldNames.RACE_NAME.name(), 1),
... ...
@@ -3334,20 +3331,20 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
3334 3331
public Map<Competitor, List<Maneuver>> loadManeuvers(TrackedRace trackedRace, Course course) {
3335 3332
final Map<Competitor, List<Maneuver>> result;
3336 3333
final Document query = new Document();
3337
- RaceIdentifier raceIdentifier = trackedRace.getRaceIdentifier();
3334
+ final RaceIdentifier raceIdentifier = trackedRace.getRaceIdentifier();
3338 3335
addRaceIdentifierToQuery(query, raceIdentifier);
3339
- final MongoCollection<Document> maneuversCollection = database.getCollection(CollectionNames.MANEUVER.name());
3336
+ final MongoCollection<Document> maneuversCollection = database.getCollection(CollectionNames.MANEUVERS.name());
3340 3337
final Document doc = maneuversCollection.find(query).first();
3341 3338
if (doc != null) {
3342 3339
result = new HashMap<>();
3343
- final List<Document> maneuversDoc = doc.getList(FieldNames.MANEUVER.name(), Document.class);
3340
+ final List<Document> maneuversDoc = doc.getList(FieldNames.MANEUVERS.name(), Document.class);
3344 3341
for (final Document maneuversForOneCompetitorDoc : maneuversDoc) {
3345 3342
final Serializable competitorId = maneuversForOneCompetitorDoc.get(FieldNames.COMPETITOR_ID.name(), Serializable.class);
3346 3343
final Competitor competitor = baseDomainFactory.getExistingCompetitorById(competitorId);
3347
- for (final Document maneuvers: maneuversForOneCompetitorDoc.getList(FieldNames.MANEUVER.name(), Document.class)) {
3348
- final Maneuver maneuver = loadManeuver(competitor, maneuvers, course, trackedRace);
3344
+ for (final Document maneuverDoc : maneuversForOneCompetitorDoc.getList(FieldNames.MANEUVERS.name(), Document.class)) {
3345
+ final Maneuver maneuver = loadManeuver(competitor, maneuverDoc, course, trackedRace);
3349 3346
result.computeIfAbsent(competitor, c -> new ArrayList<>()).add(maneuver);
3350
- }
3347
+ }
3351 3348
}
3352 3349
} else {
3353 3350
result = null;
... ...
@@ -3355,74 +3352,75 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
3355 3352
return result;
3356 3353
}
3357 3354
3358
- private Maneuver loadManeuver(Competitor competitor, Document maneuvers, Course course, TrackedRace trackedRace) {
3359
- //final int waypointIndex = maneuvers.getInteger(FieldNames.MANEUVER.name());
3360
- //final Waypoint waypoint = Util.get(course.getWaypoints(), waypointIndex);
3361
- //final TimePoint timePoint = TimePoint.of(maneuvers.getLong(FieldNames.TIME_AS_MILLIS.name()));
3362
- final TimePoint timePoint = TimePoint.of( maneuvers.getLong(FieldNames.TIMEPOINT.name()));
3363
- final double maxTurningRateInDegreesPerSecond = maneuvers.getDouble(FieldNames.MAX_TURNING_RATE_IN_DEGREE_PER_SECOUND.name());
3364
- final String typeName = maneuvers.getString(FieldNames.TYPE.name());
3355
+ private Maneuver loadManeuver(Competitor competitor, Document maneuverDoc, Course course, TrackedRace trackedRace) {
3356
+ final TimePoint timePoint = TimePoint.of( maneuverDoc.getLong(FieldNames.TIMEPOINT.name()));
3357
+ final double maxTurningRateInDegreesPerSecond = maneuverDoc.getDouble(FieldNames.MAX_TURNING_RATE_IN_DEGREE_PER_SECOUND.name());
3358
+ final String typeName = maneuverDoc.getString(FieldNames.TYPE.name());
3365 3359
final ManeuverType type = ManeuverType.valueOf(typeName);
3366
- final String newTackName = maneuvers.getString(FieldNames.TACK.name());
3360
+ final String newTackName = maneuverDoc.getString(FieldNames.TACK.name());
3367 3361
final Tack newTack = Tack.valueOf(newTackName);
3368
- final int waypointIndex = maneuvers.getInteger(FieldNames.INDEX_OF_PASSED_WAYPOINT.name());
3369
- final double positionLatRad = maneuvers.getDouble(FieldNames.POSITION_LAT_RAD.name());
3370
- final double positionLngRad = maneuvers.getDouble(FieldNames.POSITION_LNG_RAD.name());
3362
+ final int waypointIndex = maneuverDoc.getInteger(FieldNames.INDEX_OF_PASSED_WAYPOINT.name());
3363
+ final double positionLatRad = maneuverDoc.getDouble(FieldNames.POSITION_LAT_RAD.name());
3364
+ final double positionLngRad = maneuverDoc.getDouble(FieldNames.POSITION_LNG_RAD.name());
3371 3365
final Position position = new RadianPosition(positionLatRad, positionLngRad);
3372
- final ManeuverCurveBoundaries mainCurveBoundaries = loadManeuverCurveBoundaries((Document) maneuvers.get(FieldNames.MAIN_CURVE_BOUNDARIES.name()));
3373
- final ManeuverCurveBoundaries maneuverCurveWithStableSpeedAndCourseBoundaries = loadManeuverCurveBoundaries((Document) maneuvers.get(FieldNames.MANEUVER_CURVE_WITH_STABLE_SPEED_AND_COURSE_BOUNDERIES.name()));
3374
- final ManeuverLoss maneuverLoss = loadManeuverLoss((Document) maneuvers.get(FieldNames.MANEUVER_LOSS.name()));
3375
- MarkPassingProxy markPassingProxy = new MarkPassingProxy(timePoint, waypointIndex, competitor.getId(), trackedRace );// wie kommt man auf das Race?
3366
+ final ManeuverCurveBoundaries mainCurveBoundaries = loadManeuverCurveBoundaries((Document) maneuverDoc.get(FieldNames.MAIN_CURVE_BOUNDARIES.name()));
3367
+ final ManeuverCurveBoundaries maneuverCurveWithStableSpeedAndCourseBoundaries = loadManeuverCurveBoundaries((Document) maneuverDoc.get(FieldNames.MANEUVER_CURVE_WITH_STABLE_SPEED_AND_COURSE_BOUNDERIES.name()));
3368
+ final ManeuverLoss maneuverLoss = loadManeuverLoss((Document) maneuverDoc.get(FieldNames.MANEUVER_LOSS.name()));
3369
+ final MarkPassing markPassing;
3376 3370
if (waypointIndex == -1) {
3377
- final Maneuver maneuver = new ManeuverWithMainCurveBoundariesImpl(type, newTack, position, timePoint, mainCurveBoundaries, maneuverCurveWithStableSpeedAndCourseBoundaries,
3378
- maxTurningRateInDegreesPerSecond, null, maneuverLoss);
3379
- return maneuver;
3371
+ markPassing = null;
3372
+ } else {
3373
+ markPassing = new MarkPassingProxy(timePoint, waypointIndex, competitor.getId(), trackedRace);
3380 3374
}
3381
- MarkPassing markpassing = new MarkPassingImpl(timePoint, markPassingProxy.getWaypoint(), competitor);
3382
- final Maneuver maneuver = new ManeuverWithMainCurveBoundariesImpl(type, newTack, position, timePoint, mainCurveBoundaries, maneuverCurveWithStableSpeedAndCourseBoundaries,
3383
- maxTurningRateInDegreesPerSecond, markpassing, maneuverLoss);
3384
- return maneuver;
3375
+ return new ManeuverWithMainCurveBoundariesImpl(type, newTack, position, timePoint, mainCurveBoundaries,
3376
+ maneuverCurveWithStableSpeedAndCourseBoundaries, maxTurningRateInDegreesPerSecond, markPassing,
3377
+ maneuverLoss);
3385 3378
}
3386 3379
3387 3380
private ManeuverLoss loadManeuverLoss(Document document) {
3388
- if(document == null)
3389
- return null;
3390
- final Double distanceDouble = document.getDouble(FieldNames.DISTANCE_SAILED_POMA.name());
3391
- final Distance distance = new MeterDistance(distanceDouble);
3392
- final Distance distanceIfNorManeuvering = new MeterDistance(document.getDouble(FieldNames.DISTANCE_SAILED_INMPOMA.name()));
3393
- final double startPositionLatRad = document.getDouble(FieldNames.START_POSITION_LAT_RAD.name());
3394
- final double startPositionLngRad = document.getDouble(FieldNames.START_POSITION_LNG_RAD.name());
3395
- final Position startPosition = new RadianPosition(startPositionLatRad, startPositionLngRad);
3396
- final double endPositionLatRad = document.getDouble(FieldNames.END_POSITION_LAT_RAD.name());
3397
- final double endPositionLngRad = document.getDouble(FieldNames.END_POSITION_LNG_RAD.name());
3398
- final Position endPosition = new RadianPosition(endPositionLatRad, endPositionLngRad);
3399
- final Duration duration = Duration.ofMillis(document.getLong(FieldNames.DURATION.name()));
3400
- final Double SpeedWithBearingBeforeDegrees = document.getDouble(FieldNames.SPEED_WITH_BEARING_BEFORE_DEGREES.name());
3401
- final Double SpeedWithBearingBeforeSpeed = document.getDouble(FieldNames.SPEED_WITH_BEARING_BEFORE_SPEED.name());
3402
- final Bearing bearingBefore = new DegreeBearingImpl(SpeedWithBearingBeforeDegrees);
3403
- final SpeedWithBearing SpeedWithBearingBefore = new KnotSpeedWithBearingImpl(SpeedWithBearingBeforeSpeed, bearingBefore);
3404
- final Bearing middeManeuverAngle = new DegreeBearingImpl(document.getDouble(FieldNames.DEGREE_BEARING.name()));
3405
-
3406
- return new ManeuverLoss(distance, distanceIfNorManeuvering, startPosition, endPosition, duration, SpeedWithBearingBefore, middeManeuverAngle);
3381
+ final ManeuverLoss maneuverLoss;
3382
+ if (document != null) {
3383
+ final Double distanceDouble = document.getDouble(FieldNames.MANEUVER_DISTANCE_SAILED_POMA.name());
3384
+ final Distance distance = new MeterDistance(distanceDouble);
3385
+ final Distance distanceIfNorManeuvering = new MeterDistance(document.getDouble(FieldNames.MANEUVER_DISTANCE_SAILED_INMPOMA.name()));
3386
+ final double startPositionLatRad = document.getDouble(FieldNames.MANEUVER_START_POSITION_LAT_RAD.name());
3387
+ final double startPositionLngRad = document.getDouble(FieldNames.MANEUVER_START_POSITION_LNG_RAD.name());
3388
+ final Position startPosition = new RadianPosition(startPositionLatRad, startPositionLngRad);
3389
+ final double endPositionLatRad = document.getDouble(FieldNames.MANEUVER_END_POSITION_LAT_RAD.name());
3390
+ final double endPositionLngRad = document.getDouble(FieldNames.MANEUVER_END_POSITION_LNG_RAD.name());
3391
+ final Position endPosition = new RadianPosition(endPositionLatRad, endPositionLngRad);
3392
+ final Duration duration = Duration.ofMillis(document.getLong(FieldNames.MANEUVER_LOSS_DURATION.name()));
3393
+ final Double SpeedWithBearingBeforeDegrees = document.getDouble(FieldNames.MANEUVER_SPEED_WITH_BEARING_BEFORE_DEGREES.name());
3394
+ final Double SpeedWithBearingBeforeSpeed = document.getDouble(FieldNames.MANEUVER_SPEED_WITH_BEARING_BEFORE_SPEED.name());
3395
+ final Bearing bearingBefore = new DegreeBearingImpl(SpeedWithBearingBeforeDegrees);
3396
+ final SpeedWithBearing SpeedWithBearingBefore = new KnotSpeedWithBearingImpl(SpeedWithBearingBeforeSpeed, bearingBefore);
3397
+ final Bearing middeManeuverAngle = new DegreeBearingImpl(document.getDouble(FieldNames.MIDDLE_MAEUVER_ANGLE.name()));
3398
+ maneuverLoss = new ManeuverLoss(distance, distanceIfNorManeuvering, startPosition, endPosition, duration, SpeedWithBearingBefore, middeManeuverAngle);
3399
+ } else {
3400
+ maneuverLoss = null;
3401
+ }
3402
+ return maneuverLoss;
3407 3403
}
3408 3404
3409
- private ManeuverCurveBoundaries loadManeuverCurveBoundaries(Document maneuvers) {
3410
- final TimePoint timePointBefore = TimePoint.of( maneuvers.getLong(FieldNames.TIMEPOINT_BEFORE.name()));
3411
- final TimePoint timePointAfter = TimePoint.of( maneuvers.getLong(FieldNames.TIMEPOINT_AFTER.name()));
3412
- final Double SpeedWithBearingBeforeDegrees = maneuvers.getDouble(FieldNames.SPEED_WITH_BEARING_BEFORE_DEGREES.name());
3413
- final Double SpeedWithBearingBeforeSpeed = maneuvers.getDouble(FieldNames.SPEED_WITH_BEARING_BEFORE_SPEED.name());
3405
+ private ManeuverCurveBoundaries loadManeuverCurveBoundaries(Document document) {
3406
+ final TimePoint timePointBefore = TimePoint.of(document.getLong(FieldNames.MANEUVER_TIMEPOINT_BEFORE.name()));
3407
+ final TimePoint timePointAfter = TimePoint.of(document.getLong(FieldNames.MANEUVER_TIMEPOINT_AFTER.name()));
3408
+ final Double SpeedWithBearingBeforeDegrees = document.getDouble(FieldNames.MANEUVER_SPEED_WITH_BEARING_BEFORE_DEGREES.name());
3409
+ final Double SpeedWithBearingBeforeSpeed = document.getDouble(FieldNames.MANEUVER_SPEED_WITH_BEARING_BEFORE_SPEED.name());
3414 3410
final Bearing bearingBefore = new DegreeBearingImpl(SpeedWithBearingBeforeDegrees);
3415 3411
final SpeedWithBearing SpeedWithBearingBefore = new KnotSpeedWithBearingImpl(SpeedWithBearingBeforeSpeed, bearingBefore);
3416
- final Double SpeedWithBearingAfterDegrees = maneuvers.getDouble(FieldNames.SPEED_WITH_BEARING_AFTER_DEGREES.name());
3417
- final Double SpeedWithBearingAfterSpeed = maneuvers.getDouble(FieldNames.SPEED_WITH_BEARING_AFTER_SPEED.name());
3412
+ final Double SpeedWithBearingAfterDegrees = document.getDouble(FieldNames.MANEUVER_SPEED_WITH_BEARING_AFTER_DEGREES.name());
3413
+ final Double SpeedWithBearingAfterSpeed = document.getDouble(FieldNames.MANEUVER_SPEED_WITH_BEARING_AFTER_SPEED.name());
3418 3414
final Bearing bearingAfter = new DegreeBearingImpl(SpeedWithBearingAfterSpeed);
3419 3415
final SpeedWithBearing SpeedWithBearingAfter = new KnotSpeedWithBearingImpl(SpeedWithBearingAfterDegrees, bearingAfter);
3420
- final double directionChangeInDegrees = maneuvers.getDouble(FieldNames.DIRECTION_CHANGE_IN_DEGREES.name());
3421
- final double lowestSpeedDouble = maneuvers.getDouble(FieldNames.LOWEST_SPEED.name());
3416
+ final double directionChangeInDegrees = document.getDouble(FieldNames.MANEUVER_DIRECTION_CHANGE_IN_DEGREES.name());
3417
+ final double lowestSpeedDouble = document.getDouble(FieldNames.MANEUVER_LOWEST_SPEED.name());
3422 3418
final Speed lowestSpeed = new KnotSpeedImpl(lowestSpeedDouble);
3423
- final double highestSpeedDouble = maneuvers.getDouble(FieldNames.HIGHEST_SPEED.name());
3419
+ final double highestSpeedDouble = document.getDouble(FieldNames.MANEUVER_HIGHEST_SPEED.name());
3424 3420
final Speed highestSpeed = new KnotSpeedImpl(highestSpeedDouble);
3425
- ManeuverCurveBoundaries maneuverCurveBoundaries = new ManeuverCurveBoundariesImpl(timePointBefore, timePointAfter, SpeedWithBearingBefore, SpeedWithBearingAfter, directionChangeInDegrees, lowestSpeed, highestSpeed );
3421
+ ManeuverCurveBoundaries maneuverCurveBoundaries = new ManeuverCurveBoundariesImpl(timePointBefore,
3422
+ timePointAfter, SpeedWithBearingBefore, SpeedWithBearingAfter, directionChangeInDegrees, lowestSpeed,
3423
+ highestSpeed);
3426 3424
return maneuverCurveBoundaries;
3427 3425
}
3428 3426
}
... ...
\ No newline at end of file
java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java
... ...
@@ -2043,69 +2043,60 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
2043 2043
final Document competitorManeuver = new Document();
2044 2044
competitorManeuver.put(FieldNames.COMPETITOR_ID.name(), e.getKey().getId());
2045 2045
final List<Document> maneuverList = new ArrayList<>();
2046
- for (final Maneuver f : e.getValue()) {
2046
+ for (final Maneuver maneuver : e.getValue()) {
2047 2047
final Document maneuverDoc = new Document();
2048
- maneuverDoc.put(FieldNames.TYPE.name(), f.getType().name());
2049
- maneuverDoc.put(FieldNames.TACK.name(), f.getNewTack().name());
2050
- maneuverDoc.put(FieldNames.POSITION_LAT_RAD.name(), f.getPosition().getLatRad());
2051
- maneuverDoc.put(FieldNames.POSITION_LNG_RAD.name(), f.getPosition().getLngRad());
2052
- maneuverDoc.put(FieldNames.TIMEPOINT.name(), f.getTimePoint().asMillis());
2053
-
2048
+ maneuverDoc.put(FieldNames.TYPE.name(), maneuver.getType().name());
2049
+ maneuverDoc.put(FieldNames.TACK.name(), maneuver.getNewTack().name());
2050
+ maneuverDoc.put(FieldNames.POSITION_LAT_RAD.name(), maneuver.getPosition().getLatRad());
2051
+ maneuverDoc.put(FieldNames.POSITION_LNG_RAD.name(), maneuver.getPosition().getLngRad());
2052
+ maneuverDoc.put(FieldNames.TIMEPOINT.name(), maneuver.getTimePoint().asMillis());
2054 2053
final Document mainCurveBoundariesDoc = new Document();
2055
- maneuverDoc.put(FieldNames.MAIN_CURVE_BOUNDARIES.name(), storeMainCurveBoundaries(f.getMainCurveBoundaries(), mainCurveBoundariesDoc));
2054
+ maneuverDoc.put(FieldNames.MAIN_CURVE_BOUNDARIES.name(), storeMainCurveBoundaries(maneuver.getMainCurveBoundaries(), mainCurveBoundariesDoc));
2056 2055
final Document maeuverCurveWithStableSpeedAndBoundariesDoc = new Document();
2057
- maneuverDoc.put(FieldNames.MANEUVER_CURVE_WITH_STABLE_SPEED_AND_COURSE_BOUNDERIES.name(), storeMainCurveBoundaries(f.getManeuverCurveWithStableSpeedAndCourseBoundaries(), maeuverCurveWithStableSpeedAndBoundariesDoc));
2058
- maneuverDoc.put(FieldNames.MAX_TURNING_RATE_IN_DEGREE_PER_SECOUND.name(), f.getMaxTurningRateInDegreesPerSecond());
2059
-
2060
- // if umschrieben in einzeiler
2061
- if (f.getMarkPassing() != null)
2062
- maneuverDoc.put(FieldNames.INDEX_OF_PASSED_WAYPOINT.name(), course.getIndexOfWaypoint(f.getMarkPassing().getWaypoint()));
2063
- else
2064
- maneuverDoc.put(FieldNames.INDEX_OF_PASSED_WAYPOINT.name(), -1);
2065
- maneuverDoc.put(FieldNames.TIME_AS_MILLIS.name(), f.getDuration().asMillis());
2066
- if (f.getManeuverLoss() != null)
2067
- maneuverDoc.put(FieldNames.MANEUVER_LOSS.name(), storemaneuverLoss(f.getManeuverLoss()));
2068
- else
2069
- maneuverDoc.put(FieldNames.MANEUVER_LOSS.name(), null);
2056
+ maneuverDoc.put(FieldNames.MANEUVER_CURVE_WITH_STABLE_SPEED_AND_COURSE_BOUNDERIES.name(), storeMainCurveBoundaries(maneuver.getManeuverCurveWithStableSpeedAndCourseBoundaries(), maeuverCurveWithStableSpeedAndBoundariesDoc));
2057
+ maneuverDoc.put(FieldNames.MAX_TURNING_RATE_IN_DEGREE_PER_SECOUND.name(), maneuver.getMaxTurningRateInDegreesPerSecond());
2058
+ maneuverDoc.put(FieldNames.INDEX_OF_PASSED_WAYPOINT.name(), maneuver.getMarkPassing() == null ? -1 : course.getIndexOfWaypoint(maneuver.getMarkPassing().getWaypoint()));
2059
+ maneuverDoc.put(FieldNames.TIME_AS_MILLIS.name(), maneuver.getDuration().asMillis());
2060
+ maneuverDoc.put(FieldNames.MANEUVER_LOSS.name(), maneuver.getManeuverLoss() == null ? null : storeManeuverLoss(maneuver.getManeuverLoss()));
2070 2061
maneuverList.add(maneuverDoc);
2071 2062
}
2072
- competitorManeuver.put(FieldNames.MANEUVER.name(), maneuverList);
2063
+ competitorManeuver.put(FieldNames.MANEUVERS.name(), maneuverList);
2073 2064
result.add(competitorManeuver);
2074 2065
}
2075 2066
return result;
2076 2067
}
2077 2068
2078
- private Document storemaneuverLoss(ManeuverLoss maneuverLoss) {
2069
+ private Document storeManeuverLoss(ManeuverLoss maneuverLoss) {
2079 2070
final Document maneuverLossDoc = new Document();
2080
- maneuverLossDoc.put(FieldNames.DISTANCE_SAILED_POMA.name(), maneuverLoss.getDistanceSailedIfNotManeuveringProjectedOnMiddleManeuverAngle().getMeters());
2081
- maneuverLossDoc.put(FieldNames.DISTANCE_SAILED_INMPOMA.name(), maneuverLoss.getDistanceSailedIfNotManeuveringProjectedOnMiddleManeuverAngle().getMeters());
2082
- maneuverLossDoc.put(FieldNames.START_POSITION_LAT_RAD.name(), maneuverLoss.getManeuverStartPosition().getLatRad());
2083
- maneuverLossDoc.put(FieldNames.START_POSITION_LNG_RAD.name(), maneuverLoss.getManeuverStartPosition().getLngRad());
2084
- maneuverLossDoc.put(FieldNames.END_POSITION_LAT_RAD.name(), maneuverLoss.getManeuverStartPosition().getLngRad());
2085
- maneuverLossDoc.put(FieldNames.END_POSITION_LNG_RAD.name(), maneuverLoss.getManeuverStartPosition().getLngRad());
2086
- maneuverLossDoc.put(FieldNames.SPEED_WITH_BEARING_BEFORE_DEGREES.name(), maneuverLoss.getSpeedWithBearingBefore().getBearing().getDegrees());
2087
- maneuverLossDoc.put(FieldNames.SPEED_WITH_BEARING_BEFORE_SPEED.name(), maneuverLoss.getSpeedWithBearingBefore().getKnots());
2088
- maneuverLossDoc.put(FieldNames.DEGREE_BEARING.name(), maneuverLoss.getMiddleManeuverAngle().getDegrees());
2089
- maneuverLossDoc.put(FieldNames.DURATION.name(), maneuverLoss.getManeuverDuration().asMillis());
2071
+ maneuverLossDoc.put(FieldNames.MANEUVER_DISTANCE_SAILED_POMA.name(), maneuverLoss.getDistanceSailedIfNotManeuveringProjectedOnMiddleManeuverAngle().getMeters());
2072
+ maneuverLossDoc.put(FieldNames.MANEUVER_DISTANCE_SAILED_INMPOMA.name(), maneuverLoss.getDistanceSailedIfNotManeuveringProjectedOnMiddleManeuverAngle().getMeters());
2073
+ maneuverLossDoc.put(FieldNames.MANEUVER_START_POSITION_LAT_RAD.name(), maneuverLoss.getManeuverStartPosition().getLatRad());
2074
+ maneuverLossDoc.put(FieldNames.MANEUVER_START_POSITION_LNG_RAD.name(), maneuverLoss.getManeuverStartPosition().getLngRad());
2075
+ maneuverLossDoc.put(FieldNames.MANEUVER_END_POSITION_LAT_RAD.name(), maneuverLoss.getManeuverStartPosition().getLngRad());
2076
+ maneuverLossDoc.put(FieldNames.MANEUVER_END_POSITION_LNG_RAD.name(), maneuverLoss.getManeuverStartPosition().getLngRad());
2077
+ maneuverLossDoc.put(FieldNames.MANEUVER_SPEED_WITH_BEARING_BEFORE_DEGREES.name(), maneuverLoss.getSpeedWithBearingBefore().getBearing().getDegrees());
2078
+ maneuverLossDoc.put(FieldNames.MANEUVER_SPEED_WITH_BEARING_BEFORE_SPEED.name(), maneuverLoss.getSpeedWithBearingBefore().getKnots());
2079
+ maneuverLossDoc.put(FieldNames.MIDDLE_MAEUVER_ANGLE.name(), maneuverLoss.getMiddleManeuverAngle().getDegrees());
2080
+ maneuverLossDoc.put(FieldNames.MANEUVER_LOSS_DURATION.name(), maneuverLoss.getManeuverDuration().asMillis());
2090 2081
return maneuverLossDoc;
2091 2082
}
2092 2083
2093 2084
private Document storeMainCurveBoundaries(ManeuverCurveBoundaries f, Document d) {
2094
- d.put(FieldNames.TIMEPOINT_BEFORE.name(), f.getTimePointBefore().asMillis());
2095
- d.put(FieldNames.TIMEPOINT_AFTER.name(), f.getTimePointAfter().asMillis());
2096
- d.put(FieldNames.SPEED_WITH_BEARING_BEFORE_DEGREES.name(), f.getSpeedWithBearingBefore().getBearing().getDegrees());
2097
- d.put(FieldNames.SPEED_WITH_BEARING_BEFORE_SPEED.name(), f.getSpeedWithBearingBefore().getKnots());
2098
- d.put(FieldNames.SPEED_WITH_BEARING_AFTER_DEGREES.name(), f.getSpeedWithBearingAfter().getBearing().getDegrees());
2099
- d.put(FieldNames.SPEED_WITH_BEARING_AFTER_SPEED.name(), f.getSpeedWithBearingAfter().getKnots());
2100
- d.put(FieldNames.DIRECTION_CHANGE_IN_DEGREES.name(), f.getDirectionChangeInDegrees());
2101
- d.put(FieldNames.LOWEST_SPEED.name(), f.getLowestSpeed().getKnots());
2102
- d.put(FieldNames.HIGHEST_SPEED.name(), f.getHighestSpeed().getKnots());
2085
+ d.put(FieldNames.MANEUVER_TIMEPOINT_BEFORE.name(), f.getTimePointBefore().asMillis());
2086
+ d.put(FieldNames.MANEUVER_TIMEPOINT_AFTER.name(), f.getTimePointAfter().asMillis());
2087
+ d.put(FieldNames.MANEUVER_SPEED_WITH_BEARING_BEFORE_DEGREES.name(), f.getSpeedWithBearingBefore().getBearing().getDegrees());
2088
+ d.put(FieldNames.MANEUVER_SPEED_WITH_BEARING_BEFORE_SPEED.name(), f.getSpeedWithBearingBefore().getKnots());
2089
+ d.put(FieldNames.MANEUVER_SPEED_WITH_BEARING_AFTER_DEGREES.name(), f.getSpeedWithBearingAfter().getBearing().getDegrees());
2090
+ d.put(FieldNames.MANEUVER_SPEED_WITH_BEARING_AFTER_SPEED.name(), f.getSpeedWithBearingAfter().getKnots());
2091
+ d.put(FieldNames.MANEUVER_DIRECTION_CHANGE_IN_DEGREES.name(), f.getDirectionChangeInDegrees());
2092
+ d.put(FieldNames.MANEUVER_LOWEST_SPEED.name(), f.getLowestSpeed().getKnots());
2093
+ d.put(FieldNames.MANEUVER_HIGHEST_SPEED.name(), f.getHighestSpeed().getKnots());
2103 2094
return d;
2104 2095
}
2105 2096
2106 2097
@Override
2107 2098
public void storeManeuvers(RaceIdentifier raceIdentifier, ManeuverRaceFingerprint fingerprint, Course course, Map<Competitor, List<Maneuver>> maneuvers) {
2108
- MongoCollection<Document> maneuverCollection = database.getCollection(CollectionNames.MANEUVER.name());
2099
+ MongoCollection<Document> maneuverCollection = database.getCollection(CollectionNames.MANEUVERS.name());
2109 2100
JSONObject fingerprintjson = fingerprint.toJson();
2110 2101
final Document query = new Document();
2111 2102
DomainObjectFactoryImpl.addRaceIdentifierToQuery(query, raceIdentifier);
... ...
@@ -2114,13 +2105,13 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
2114 2105
result.put(FieldNames.MANEUVER_FINGERPRINT.name(), fingerprintDoc);
2115 2106
storeRaceIdentifier(result, raceIdentifier);
2116 2107
final List<Document> maneuverDoc = storeManeuvers( maneuvers , raceIdentifier, course);
2117
- result.put(FieldNames.MANEUVER.name(), maneuverDoc);
2108
+ result.put(FieldNames.MANEUVERS.name(), maneuverDoc);
2118 2109
maneuverCollection.replaceOne(query, result, new ReplaceOptions().upsert(true));
2119 2110
}
2120 2111
2121 2112
@Override
2122 2113
public void removeManeuvers(RaceIdentifier raceIdentifier) {
2123
- MongoCollection<Document> maneuverCollection = database.getCollection(CollectionNames.MANEUVER.name());
2114
+ MongoCollection<Document> maneuverCollection = database.getCollection(CollectionNames.MANEUVERS.name());
2124 2115
final Document query = new Document();
2125 2116
DomainObjectFactoryImpl.addRaceIdentifierToQuery(query, raceIdentifier);
2126 2117
maneuverCollection.deleteOne(query);
java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogRaceTracker.java
... ...
@@ -110,7 +110,9 @@ public class RaceLogRaceTracker extends AbstractRaceTrackerBaseImpl<RaceLogConne
110 110
111 111
public RaceLogRaceTracker(DynamicTrackedRegatta regatta, RaceLogConnectivityParams params, WindStore windStore,
112 112
RaceLogAndTrackedRaceResolver raceLogResolver, RaceLogConnectivityParams connectivityParams,
113
- TrackedRegattaRegistry trackedRegattaRegistry, RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) {
113
+ TrackedRegattaRegistry trackedRegattaRegistry, RaceTrackingHandler raceTrackingHandler,
114
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
115
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) {
114 116
super(params);
115 117
this.trackedRegattaRegistry = trackedRegattaRegistry;
116 118
this.params = params;
... ...
@@ -358,7 +360,7 @@ public class RaceLogRaceTracker extends AbstractRaceTrackerBaseImpl<RaceLogConne
358 360
boatClass.getApproximateManeuverDurationInMilliseconds(), null, /*useMarkPassingCalculator*/ true, raceLogResolver,
359 361
/* Not needed because the RaceTracker is not active on a replica */ Optional.empty(),
360 362
new TrackingConnectorInfoImpl(RaceLogTrackingAdapter.NAME, RaceLogTrackingAdapter.DEFAULT_URL, /* no webUrl */ null),
361
- markPassingRaceFingerprintRegistry, maneuverRaceFingerprintRegistry );
363
+ markPassingRaceFingerprintRegistry, maneuverRaceFingerprintRegistry);
362 364
notifyRaceCreationListeners();
363 365
logger.info(String.format("Started tracking race-log race (%s)", raceLog));
364 366
// this wakes up all waiting race handles
java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/SwissTimingFactory.java
... ...
@@ -8,6 +8,7 @@ import java.text.ParseException;
8 8
9 9
import com.sap.sailing.domain.base.BoatClass;
10 10
import com.sap.sailing.domain.base.Regatta;
11
+import com.sap.sailing.domain.maneuverhash.ManeuverRaceFingerprintRegistry;
11 12
import com.sap.sailing.domain.markpassinghash.MarkPassingRaceFingerprintRegistry;
12 13
import com.sap.sailing.domain.racelog.RaceLogAndTrackedRaceResolver;
13 14
import com.sap.sailing.domain.racelog.RaceLogStore;
... ...
@@ -63,12 +64,12 @@ public interface SwissTimingFactory {
63 64
64 65
SwissTimingRaceTracker createRaceTracker(RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, WindStore windStore,
65 66
DomainFactory domainFactory, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogAndTrackedRaceResolver raceLogResolver, SwissTimingTrackingConnectivityParameters connectivityParams,
66
- RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry)
67
+ RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry)
67 68
throws InterruptedException, UnknownHostException, IOException, ParseException, URISyntaxException;
68 69
69 70
RaceTracker createRaceTracker(Regatta regatta, WindStore windStore, DomainFactory domainFactory, TrackedRegattaRegistry trackedRegattaRegistry,
70 71
RaceLogAndTrackedRaceResolver raceLogResolver, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, SwissTimingTrackingConnectivityParameters connectivityParams,
71
- RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry)
72
+ RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry)
72 73
throws UnknownHostException, InterruptedException, IOException, ParseException, URISyntaxException;
73 74
74 75
Race createRace(String raceId, String raceName, String description, BoatClass boatClass);
java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingFactoryImpl.java
... ...
@@ -11,6 +11,7 @@ import java.util.logging.Logger;
11 11
12 12
import com.sap.sailing.domain.base.BoatClass;
13 13
import com.sap.sailing.domain.base.Regatta;
14
+import com.sap.sailing.domain.maneuverhash.ManeuverRaceFingerprintRegistry;
14 15
import com.sap.sailing.domain.markpassinghash.MarkPassingRaceFingerprintRegistry;
15 16
import com.sap.sailing.domain.racelog.RaceLogAndTrackedRaceResolver;
16 17
import com.sap.sailing.domain.racelog.RaceLogStore;
... ...
@@ -100,20 +101,24 @@ public class SwissTimingFactoryImpl implements SwissTimingFactory {
100 101
public SwissTimingRaceTracker createRaceTracker(RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
101 102
WindStore windStore, DomainFactory domainFactory, TrackedRegattaRegistry trackedRegattaRegistry,
102 103
RaceLogAndTrackedRaceResolver raceLogResolver, SwissTimingTrackingConnectivityParameters connectivityParams,
103
- RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry)
104
+ RaceTrackingHandler raceTrackingHandler,
105
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry)
104 106
throws InterruptedException, UnknownHostException, IOException, ParseException, URISyntaxException {
105 107
return new SwissTimingRaceTrackerImpl(raceLogStore, regattaLogStore, windStore, domainFactory, this,
106
- trackedRegattaRegistry, raceLogResolver, connectivityParams, raceTrackingHandler, markPassingRaceFingerprintRegistry);
108
+ trackedRegattaRegistry, raceLogResolver, connectivityParams, raceTrackingHandler,
109
+ markPassingRaceFingerprintRegistry, maneuverRaceFingerprintRegistry);
107 110
}
108 111
109 112
@Override
110 113
public RaceTracker createRaceTracker(Regatta regatta, WindStore windStore, DomainFactory domainFactory,
111
- TrackedRegattaRegistry trackedRegattaRegistry, RaceLogAndTrackedRaceResolver raceLogResolver, RaceLogStore raceLogStore,
112
- RegattaLogStore regattaLogStore, SwissTimingTrackingConnectivityParameters connectivityParams,
113
- RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry)
114
+ TrackedRegattaRegistry trackedRegattaRegistry, RaceLogAndTrackedRaceResolver raceLogResolver,
115
+ RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
116
+ SwissTimingTrackingConnectivityParameters connectivityParams, RaceTrackingHandler raceTrackingHandler,
117
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry)
114 118
throws UnknownHostException, InterruptedException, IOException, ParseException, URISyntaxException {
115 119
return new SwissTimingRaceTrackerImpl(regatta, windStore, domainFactory, this, trackedRegattaRegistry,
116
- raceLogStore, regattaLogStore, raceLogResolver, connectivityParams, raceTrackingHandler, markPassingRaceFingerprintRegistry);
120
+ raceLogStore, regattaLogStore, raceLogResolver, connectivityParams, raceTrackingHandler,
121
+ markPassingRaceFingerprintRegistry, maneuverRaceFingerprintRegistry);
117 122
}
118 123
119 124
@Override
java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingRaceTrackerImpl.java
... ...
@@ -37,6 +37,7 @@ import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
37 37
import com.sap.sailing.domain.common.impl.WindImpl;
38 38
import com.sap.sailing.domain.common.impl.WindSourceWithAdditionalID;
39 39
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
40
+import com.sap.sailing.domain.maneuverhash.ManeuverRaceFingerprintRegistry;
40 41
import com.sap.sailing.domain.markpassinghash.MarkPassingRaceFingerprintRegistry;
41 42
import com.sap.sailing.domain.racelog.RaceLogAndTrackedRaceResolver;
42 43
import com.sap.sailing.domain.racelog.RaceLogStore;
... ...
@@ -122,6 +123,8 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl<SwissTim
122 123
private final RaceLogAndTrackedRaceResolver raceLogResolver;
123 124
124 125
private final MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry;
126
+
127
+ private final ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry;
125 128
126 129
/**
127 130
* If set to a non-{@code null}, non-{@link String#isEmpty() empty} value, updates about start time changes, course
... ...
@@ -140,17 +143,18 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl<SwissTim
140 143
WindStore windStore, DomainFactory domainFactory, SwissTimingFactory factory,
141 144
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogAndTrackedRaceResolver raceLogResolver,
142 145
SwissTimingTrackingConnectivityParameters connectivityParams, RaceTrackingHandler raceTrackingHandler,
143
- MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry)
146
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry)
144 147
throws InterruptedException, UnknownHostException, IOException, ParseException, URISyntaxException {
145 148
this(/* regatta */ null, windStore, domainFactory, factory, trackedRegattaRegistry, raceLogStore,
146
- regattaLogStore, raceLogResolver, connectivityParams, raceTrackingHandler, markPassingRaceFingerprintRegistry);
149
+ regattaLogStore, raceLogResolver, connectivityParams, raceTrackingHandler, markPassingRaceFingerprintRegistry,
150
+ maneuverRaceFingerprintRegistry);
147 151
}
148 152
149 153
protected SwissTimingRaceTrackerImpl(Regatta regatta, WindStore windStore, DomainFactory domainFactory,
150 154
SwissTimingFactory factory, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogStore raceLogStore,
151 155
RegattaLogStore regattaLogStore, RaceLogAndTrackedRaceResolver raceLogResolver,
152 156
SwissTimingTrackingConnectivityParameters connectivityParams, RaceTrackingHandler raceTrackingHandler,
153
- MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry)
157
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry)
154 158
throws InterruptedException, UnknownHostException, IOException, ParseException, URISyntaxException {
155 159
super(connectivityParams);
156 160
this.raceLogResolver = raceLogResolver;
... ...
@@ -158,6 +162,7 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl<SwissTim
158 162
this.tmdMessageQueue = new TMDMessageQueue(this);
159 163
this.trackedRegattaRegistry = trackedRegattaRegistry;
160 164
this.markPassingRaceFingerprintRegistry = markPassingRaceFingerprintRegistry;
165
+ this.maneuverRaceFingerprintRegistry = maneuverRaceFingerprintRegistry;
161 166
final Regatta effectiveRegatta;
162 167
// Try to find a pre-associated event based on the Race ID
163 168
if (regatta == null) {
... ...
@@ -543,7 +548,9 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl<SwissTim
543 548
}
544 549
}, useInternalMarkPassingAlgorithm, raceLogResolver,
545 550
/* Not needed because the RaceTracker is not active on a replica */ Optional.empty(),
546
- new TrackingConnectorInfoImpl(SwissTimingAdapter.NAME, SwissTimingAdapter.DEFAULT_URL,/*no api connection to query the webUrl*/ null), markPassingRaceFingerprintRegistry,/*maneuverRaceFingerprintRegistry*/ null);
551
+ new TrackingConnectorInfoImpl(SwissTimingAdapter.NAME, SwissTimingAdapter.DEFAULT_URL,
552
+ /*no api connection to query the webUrl*/ null), markPassingRaceFingerprintRegistry,
553
+ maneuverRaceFingerprintRegistry);
547 554
addUpdateHandlers();
548 555
notifyRaceCreationListeners();
549 556
logger.info("Created SwissTiming RaceDefinition and TrackedRace for "+race.getName());
java/com.sap.sailing.domain.swisstimingadapter/src/com/sap/sailing/domain/swisstimingadapter/impl/SwissTimingTrackingConnectivityParameters.java
... ...
@@ -74,18 +74,25 @@ public class SwissTimingTrackingConnectivityParameters extends AbstractRaceTrack
74 74
75 75
@Override
76 76
public RaceTracker createRaceTracker(TrackedRegattaRegistry trackedRegattaRegistry, WindStore windStore,
77
- RaceLogAndTrackedRaceResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds,
78
- RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) throws Exception {
79
- return swissTimingFactory.createRaceTracker(raceLogStore, regattaLogStore, windStore, domainFactory, trackedRegattaRegistry, raceLogResolver,
80
- this, raceTrackingHandler, markPassingRaceFingerprintRegistry);
77
+ RaceLogAndTrackedRaceResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver,
78
+ long timeoutInMilliseconds, RaceTrackingHandler raceTrackingHandler,
79
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
80
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) throws Exception {
81
+ return swissTimingFactory.createRaceTracker(raceLogStore, regattaLogStore, windStore, domainFactory,
82
+ trackedRegattaRegistry, raceLogResolver, this, raceTrackingHandler, markPassingRaceFingerprintRegistry,
83
+ maneuverRaceFingerprintRegistry);
81 84
}
82 85
83 86
@Override
84 87
public RaceTracker createRaceTracker(Regatta regatta, TrackedRegattaRegistry trackedRegattaRegistry,
85
- WindStore windStore, RaceLogAndTrackedRaceResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds,
86
- RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) throws Exception {
87
- return swissTimingFactory.createRaceTracker(regatta, windStore, domainFactory, trackedRegattaRegistry, raceLogResolver, raceLogStore,
88
- regattaLogStore, this, raceTrackingHandler, markPassingRaceFingerprintRegistry);
88
+ WindStore windStore, RaceLogAndTrackedRaceResolver raceLogResolver,
89
+ LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds,
90
+ RaceTrackingHandler raceTrackingHandler,
91
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
92
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) throws Exception {
93
+ return swissTimingFactory.createRaceTracker(regatta, windStore, domainFactory, trackedRegattaRegistry,
94
+ raceLogResolver, raceLogStore, regattaLogStore, this, raceTrackingHandler,
95
+ markPassingRaceFingerprintRegistry, maneuverRaceFingerprintRegistry);
89 96
}
90 97
91 98
@Override
java/com.sap.sailing.domain.swisstimingreplayadapter/src/com/sap/sailing/domain/swisstimingreplayadapter/impl/SwissTimingReplayConnectivityParameters.java
... ...
@@ -142,7 +142,9 @@ public class SwissTimingReplayConnectivityParameters extends AbstractRaceTrackin
142 142
@Override
143 143
public RaceTracker createRaceTracker(TrackedRegattaRegistry trackedRegattaRegistry, final WindStore windStore,
144 144
RaceLogAndTrackedRaceResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver,
145
- long timeoutInMilliseconds, RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) throws Exception {
145
+ long timeoutInMilliseconds, RaceTrackingHandler raceTrackingHandler,
146
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
147
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) throws Exception {
146 148
SwissTimingReplayToDomainAdapter listener = new SwissTimingReplayToDomainAdapter(/* regatta */ null, raceName,
147 149
raceID, domainFactory.getBaseDomainFactory().getOrCreateBoatClass(boatClassName), domainFactory,
148 150
trackedRegattaRegistry, useInternalMarkPassingAlgorithm, raceLogResolver, raceLogStore,
... ...
@@ -154,8 +156,11 @@ public class SwissTimingReplayConnectivityParameters extends AbstractRaceTrackin
154 156
155 157
@Override
156 158
public RaceTracker createRaceTracker(Regatta regatta, TrackedRegattaRegistry trackedRegattaRegistry,
157
- WindStore windStore, RaceLogAndTrackedRaceResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver,
158
- long timeoutInMilliseconds, RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) throws Exception {
159
+ WindStore windStore, RaceLogAndTrackedRaceResolver raceLogResolver,
160
+ LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds,
161
+ RaceTrackingHandler raceTrackingHandler,
162
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
163
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) throws Exception {
159 164
SwissTimingReplayToDomainAdapter listener = new SwissTimingReplayToDomainAdapter(regatta, raceName,
160 165
raceID, domainFactory.getBaseDomainFactory().getOrCreateBoatClass(boatClassName),
161 166
domainFactory, trackedRegattaRegistry, useInternalMarkPassingAlgorithm, raceLogResolver,
java/com.sap.sailing.domain.swisstimingreplayadapter/src/com/sap/sailing/domain/swisstimingreplayadapter/impl/SwissTimingReplayToDomainAdapter.java
... ...
@@ -187,13 +187,14 @@ public class SwissTimingReplayToDomainAdapter extends SwissTimingReplayAdapter i
187 187
* be obtained from {@link #getTracker()}. This tracker's {@link RaceTracker.RaceCreationListener}s will
188 188
* be {@link SwissTimingReplayRaceTracker#notifyRaceCreationListeners() notified} when this adapter has
189 189
* created the race.
190
- * @param maneuverRaceFingerprintRegistry
191 190
*/
192 191
public SwissTimingReplayToDomainAdapter(Regatta regatta, String raceName, String raceIdForRaceDefinition,
193
- BoatClass boatClass, DomainFactory domainFactory,
194
- TrackedRegattaRegistry trackedRegattaRegistry, boolean useInternalMarkPassingAlgorithm, RaceLogAndTrackedRaceResolver raceLogResolver,
192
+ BoatClass boatClass, DomainFactory domainFactory, TrackedRegattaRegistry trackedRegattaRegistry,
193
+ boolean useInternalMarkPassingAlgorithm, RaceLogAndTrackedRaceResolver raceLogResolver,
195 194
RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, TrackerConstructor trackerConstructor,
196
- RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) {
195
+ RaceTrackingHandler raceTrackingHandler,
196
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
197
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) {
197 198
this.tracker = trackerConstructor == null ? null : trackerConstructor.createTracker(this);
198 199
this.raceLogResolver = raceLogResolver;
199 200
this.markPassingRaceFingerprintRegistry = markPassingRaceFingerprintRegistry;
... ...
@@ -424,7 +425,8 @@ public class SwissTimingReplayToDomainAdapter extends SwissTimingReplayAdapter i
424 425
/* time over which to average speed: */ race.getBoatClass().getApproximateManeuverDurationInMilliseconds(),
425 426
/* raceDefinitionSetToUpdate */ null, useInternalMarkPassingAlgorithm, raceLogResolver,
426 427
/* Not needed because the RaceTracker is not active on a replica */ Optional.empty(),
427
- new TrackingConnectorInfoImpl(SwissTimingAdapter.NAME, SwissTimingAdapter.DEFAULT_URL,/*no api connection to query the webUrl*/ null), markPassingRaceFingerprintRegistry, /*maneuverRaceFingerprintRegistry*/ null);
428
+ new TrackingConnectorInfoImpl(SwissTimingAdapter.NAME, SwissTimingAdapter.DEFAULT_URL,/*no api connection to query the webUrl*/ null), markPassingRaceFingerprintRegistry,
429
+ /*maneuverRaceFingerprintRegistry*/ null);
428 430
trackedRace.onStatusChanged(this, new TrackedRaceStatusImpl(TrackedRaceStatusEnum.LOADING, 0));
429 431
TimePoint bestStartTimeKnownSoFar = bestStartTimePerRaceID.get(currentRaceID);
430 432
if (bestStartTimeKnownSoFar != null) {
java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackedRaceStartTimeUpdateForDependentStartTimeTest.java
... ...
@@ -57,7 +57,6 @@ public class TrackedRaceStartTimeUpdateForDependentStartTimeTest extends TrackBa
57 57
@Override
58 58
public List<Triple<Leaderboard, RaceColumn, Fleet>> getColumnsWithRaceLogForTrackedRace(
59 59
RegattaAndRaceIdentifier trackedRaceIdentifier) {
60
- // TODO Auto-generated method stub
61 60
return null;
62 61
}
63 62
};
java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java
... ...
@@ -691,12 +691,13 @@ public class MockedTrackedRace implements DynamicTrackedRace {
691 691
692 692
@Override
693 693
public DynamicTrackedRace createTrackedRace(RaceDefinition raceDefinition, Iterable<Sideline> sidelines,
694
- WindStore windStore, long delayToLiveInMillis,
695
- long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed,
696
- DynamicRaceDefinitionSet raceDefinitionSetToUpdate, boolean useMarkPassingcalculator,
697
- RaceLogAndTrackedRaceResolver raceLogResolver,
694
+ WindStore windStore, long delayToLiveInMillis, long millisecondsOverWhichToAverageWind,
695
+ long millisecondsOverWhichToAverageSpeed, DynamicRaceDefinitionSet raceDefinitionSetToUpdate,
696
+ boolean useMarkPassingcalculator, RaceLogAndTrackedRaceResolver raceLogResolver,
698 697
Optional<ThreadLocalTransporter> threadLocalTransporter,
699
- TrackingConnectorInfo trackingConnectorInfo, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry ) {
698
+ TrackingConnectorInfo trackingConnectorInfo,
699
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
700
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) {
700 701
return null;
701 702
}
702 703
... ...
@@ -1417,8 +1418,4 @@ public class MockedTrackedRace implements DynamicTrackedRace {
1417 1418
WindLegTypeAndLegBearingAndORCPerformanceCurveCache cache) {
1418 1419
return null;
1419 1420
}
1420
-
1421
- @Override
1422
- public void updateManeuvers(Competitor competitor, Iterable<Maneuver> maneuvers) {
1423
- }
1424 1421
}
... ...
\ No newline at end of file
java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/tracking/TestTracTracRaceAndCompetitorStatusReconciler.java
... ...
@@ -122,7 +122,6 @@ public class TestTracTracRaceAndCompetitorStatusReconciler {
122 122
@Override
123 123
public List<Triple<Leaderboard, RaceColumn, Fleet>> getColumnsWithRaceLogForTrackedRace(
124 124
RegattaAndRaceIdentifier trackedRaceIdentifier) {
125
- // TODO Auto-generated method stub
126 125
return null;
127 126
}
128 127
... ...
@@ -261,7 +260,6 @@ public class TestTracTracRaceAndCompetitorStatusReconciler {
261 260
@Override
262 261
public List<Triple<Leaderboard, RaceColumn, Fleet>> getColumnsWithRaceLogForTrackedRace(
263 262
RegattaAndRaceIdentifier trackedRaceIdentifier) {
264
- // TODO Auto-generated method stub
265 263
return null;
266 264
}
267 265
});
java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/DomainFactory.java
... ...
@@ -152,21 +152,26 @@ public interface DomainFactory {
152 152
* available but loses track of the wind, e.g., during server restarts.
153 153
*/
154 154
TracTracRaceTracker createRaceTracker(RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
155
- WindStore windStore, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogAndTrackedRaceResolver raceLogResolver,
156
- LeaderboardGroupResolver leaderboardGroupResolver,
155
+ WindStore windStore, TrackedRegattaRegistry trackedRegattaRegistry,
156
+ RaceLogAndTrackedRaceResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver,
157 157
RaceTrackingConnectivityParametersImpl connectivityParams, long timeoutInMilliseconds,
158
- RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) throws URISyntaxException, SubscriberInitializationException,
159
- IOException, InterruptedException, CreateModelException, TimeOutException;
158
+ RaceTrackingHandler raceTrackingHandler,
159
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
160
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry)
161
+ throws URISyntaxException, SubscriberInitializationException, IOException, InterruptedException,
162
+ CreateModelException, TimeOutException;
160 163
161 164
/**
162 165
* Same as {@link #createRaceTracker(URL, URI, URI, URI, TimePoint, TimePoint, WindStore, TrackedRegattaRegistry)},
163 166
* only that a predefined {@link Regatta} is used to hold the resulting races.
164 167
*/
165 168
RaceTracker createRaceTracker(Regatta regatta, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
166
- WindStore windStore, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogAndTrackedRaceResolver raceLogResolver,
167
- LeaderboardGroupResolver leaderboardGroupResolver,
169
+ WindStore windStore, TrackedRegattaRegistry trackedRegattaRegistry,
170
+ RaceLogAndTrackedRaceResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver,
168 171
RaceTrackingConnectivityParametersImpl connectivityParams, long timeoutInMilliseconds,
169
- RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry)
172
+ RaceTrackingHandler raceTrackingHandler,
173
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
174
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry)
170 175
throws MalformedURLException, FileNotFoundException, URISyntaxException, CreateModelException,
171 176
SubscriberInitializationException, IOException, InterruptedException, TimeOutException;
172 177
... ...
@@ -188,10 +193,15 @@ public interface DomainFactory {
188 193
* this call
189 194
*/
190 195
Iterable<Receiver> getUpdateReceivers(DynamicTrackedRegatta trackedRegatta, long delayToLiveInMillis,
191
- Simulator simulator, WindStore windStore, DynamicRaceDefinitionSet raceDefinitionSetToUpdate, TrackedRegattaRegistry trackedRegattaRegistry,
192
- RaceLogAndTrackedRaceResolver raceLogResolver, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry, LeaderboardGroupResolver leaderboardGroupResolver,
193
- IRace tractracRace, URI courseDesignUpdateURI, String tracTracApiToken, IEventSubscriber eventSubscriber, IRaceSubscriber raceSubscriber, boolean useInternalMarkPassingAlgorithm,
194
- long timeoutInMilliseconds, RaceTrackingHandler raceTrackingHandler, RaceAndCompetitorStatusWithRaceLogReconciler raceAndCompetitorStatusWithRaceLogReconciler);
196
+ Simulator simulator, WindStore windStore, DynamicRaceDefinitionSet raceDefinitionSetToUpdate,
197
+ TrackedRegattaRegistry trackedRegattaRegistry, RaceLogAndTrackedRaceResolver raceLogResolver,
198
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
199
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry,
200
+ LeaderboardGroupResolver leaderboardGroupResolver, IRace tractracRace, URI courseDesignUpdateURI,
201
+ String tracTracApiToken, IEventSubscriber eventSubscriber, IRaceSubscriber raceSubscriber,
202
+ boolean useInternalMarkPassingAlgorithm, long timeoutInMilliseconds,
203
+ RaceTrackingHandler raceTrackingHandler,
204
+ RaceAndCompetitorStatusWithRaceLogReconciler raceAndCompetitorStatusWithRaceLogReconciler);
195 205
196 206
/**
197 207
* Creates a {@link RaceDefinition} from a TracTrac {@link IRace} and a domain {@link Course} definition. The
... ...
@@ -216,13 +226,15 @@ public interface DomainFactory {
216 226
* the race.
217 227
*/
218 228
DynamicTrackedRace getOrCreateRaceDefinitionAndTrackedRace(DynamicTrackedRegatta trackedRegatta, UUID raceId,
219
- String raceName, BoatClass boatClass, Map<Competitor, Boat> competitorBoats,
220
- Course course, Iterable<Sideline> sidelines, WindStore windStore,
221
- long delayToLiveInMillis, long millisecondsOverWhichToAverageWind,
222
- DynamicRaceDefinitionSet raceDefinitionSetToUpdate, URI courseDesignUpdateURI, UUID tracTracEventUuid,
223
- String tracTracApiToken, boolean ignoreTracTracMarkPassings,
224
- RaceLogAndTrackedRaceResolver raceLogResolver, Consumer<DynamicTrackedRace> runBeforeExposingRace, IRace tractracRace,
225
- RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry);
229
+ String raceName, BoatClass boatClass, Map<Competitor, Boat> competitorBoats, Course course,
230
+ Iterable<Sideline> sidelines, WindStore windStore, long delayToLiveInMillis,
231
+ long millisecondsOverWhichToAverageWind, DynamicRaceDefinitionSet raceDefinitionSetToUpdate,
232
+ URI courseDesignUpdateURI, UUID tracTracEventUuid, String tracTracApiToken,
233
+ boolean ignoreTracTracMarkPassings, RaceLogAndTrackedRaceResolver raceLogResolver,
234
+ Consumer<DynamicTrackedRace> runBeforeExposingRace, IRace tractracRace,
235
+ RaceTrackingHandler raceTrackingHandler,
236
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
237
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry);
226 238
227 239
/**
228 240
* The record may be for a single mark or a gate. If for a gate, the {@link ControlPointPositionData#getIndex()
... ...
@@ -240,10 +252,15 @@ public interface DomainFactory {
240 252
* If the vm argument tractrac.usemarkpassings=false, the RecieverType MARKPASSINGS will not return anything
241 253
*/
242 254
Iterable<Receiver> getUpdateReceivers(DynamicTrackedRegatta trackedRegatta, IRace tractracRace, WindStore windStore,
243
- long delayToLiveInMillis, Simulator simulator, DynamicRaceDefinitionSet raceDefinitionSetToUpdate, TrackedRegattaRegistry trackedRegattaRegistry,
244
- RaceLogAndTrackedRaceResolver raceLogResolver, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry, LeaderboardGroupResolver leaderboardGroupResolver,
245
- URI courseDesignUpdateURI, String tracTracApiToken, IEventSubscriber eventSubscriber, IRaceSubscriber raceSubscriber, boolean ignoreTracTracMarkPassings,
246
- long timeoutInMilliseconds, RaceTrackingHandler raceTrackingHandler, RaceAndCompetitorStatusWithRaceLogReconciler raceAndCompetitorStatusWithRaceLogReconciler, ReceiverType... types);
255
+ long delayToLiveInMillis, Simulator simulator, DynamicRaceDefinitionSet raceDefinitionSetToUpdate,
256
+ TrackedRegattaRegistry trackedRegattaRegistry, RaceLogAndTrackedRaceResolver raceLogResolver,
257
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
258
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry,
259
+ LeaderboardGroupResolver leaderboardGroupResolver, URI courseDesignUpdateURI, String tracTracApiToken,
260
+ IEventSubscriber eventSubscriber, IRaceSubscriber raceSubscriber, boolean ignoreTracTracMarkPassings,
261
+ long timeoutInMilliseconds, RaceTrackingHandler raceTrackingHandler,
262
+ RaceAndCompetitorStatusWithRaceLogReconciler raceAndCompetitorStatusWithRaceLogReconciler,
263
+ ReceiverType... types);
247 264
248 265
JSONService parseJSONURLWithRaceRecords(URL jsonURL, boolean loadClientParams, String tracTracApiToken) throws IOException, ParseException, org.json.simple.parser.ParseException, URISyntaxException;
249 266
java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/DomainFactoryImpl.java
... ...
@@ -536,12 +536,16 @@ public class DomainFactoryImpl implements DomainFactory {
536 536
537 537
@Override
538 538
public Iterable<Receiver> getUpdateReceivers(DynamicTrackedRegatta trackedRegatta, IRace tractracRace,
539
- WindStore windStore, long delayToLiveInMillis, Simulator simulator, DynamicRaceDefinitionSet raceDefinitionSetToUpdate,
540
- TrackedRegattaRegistry trackedRegattaRegistry, RaceLogAndTrackedRaceResolver raceLogResolver, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry,
541
- LeaderboardGroupResolver leaderboardGroupResolver, URI updateURI, String tracTracApiToken, IEventSubscriber eventSubscriber, IRaceSubscriber raceSubscriber,
542
- boolean useInternalMarkPassingAlgorithm, long timeoutInMilliseconds,
543
- RaceTrackingHandler raceTrackingHandler,
544
- RaceAndCompetitorStatusWithRaceLogReconciler raceAndCompetitorStatusWithRaceLogReconciler, ReceiverType... types) {
539
+ WindStore windStore, long delayToLiveInMillis, Simulator simulator,
540
+ DynamicRaceDefinitionSet raceDefinitionSetToUpdate, TrackedRegattaRegistry trackedRegattaRegistry,
541
+ RaceLogAndTrackedRaceResolver raceLogResolver,
542
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
543
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry,
544
+ LeaderboardGroupResolver leaderboardGroupResolver, URI updateURI, String tracTracApiToken,
545
+ IEventSubscriber eventSubscriber, IRaceSubscriber raceSubscriber, boolean useInternalMarkPassingAlgorithm,
546
+ long timeoutInMilliseconds, RaceTrackingHandler raceTrackingHandler,
547
+ RaceAndCompetitorStatusWithRaceLogReconciler raceAndCompetitorStatusWithRaceLogReconciler,
548
+ ReceiverType... types) {
545 549
IEvent tractracEvent = tractracRace.getEvent();
546 550
Collection<Receiver> result = new ArrayList<Receiver>();
547 551
for (ReceiverType type : types) {
... ...
@@ -585,14 +589,16 @@ public class DomainFactoryImpl implements DomainFactory {
585 589
}
586 590
587 591
@Override
588
- public Iterable<Receiver> getUpdateReceivers(DynamicTrackedRegatta trackedRegatta,
589
- long delayToLiveInMillis, Simulator simulator, WindStore windStore,
590
- DynamicRaceDefinitionSet raceDefinitionSetToUpdate, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogAndTrackedRaceResolver raceLogResolver,
591
- MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry, LeaderboardGroupResolver leaderboardGroupResolver, IRace tractracRace,
592
- URI updateURI, String tracTracApiToken,
593
- IEventSubscriber eventSubscriber, IRaceSubscriber raceSubscriber, boolean useInternalMarkPassingAlgorithm,
594
- long timeoutInMilliseconds,
595
- RaceTrackingHandler raceTrackingHandler, RaceAndCompetitorStatusWithRaceLogReconciler raceAndCompetitorStatusWithRaceLogReconciler) {
592
+ public Iterable<Receiver> getUpdateReceivers(DynamicTrackedRegatta trackedRegatta, long delayToLiveInMillis,
593
+ Simulator simulator, WindStore windStore, DynamicRaceDefinitionSet raceDefinitionSetToUpdate,
594
+ TrackedRegattaRegistry trackedRegattaRegistry, RaceLogAndTrackedRaceResolver raceLogResolver,
595
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
596
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry,
597
+ LeaderboardGroupResolver leaderboardGroupResolver, IRace tractracRace, URI updateURI,
598
+ String tracTracApiToken, IEventSubscriber eventSubscriber, IRaceSubscriber raceSubscriber,
599
+ boolean useInternalMarkPassingAlgorithm, long timeoutInMilliseconds,
600
+ RaceTrackingHandler raceTrackingHandler,
601
+ RaceAndCompetitorStatusWithRaceLogReconciler raceAndCompetitorStatusWithRaceLogReconciler) {
596 602
final List<ReceiverType> receiverTypes = new ArrayList<>();
597 603
receiverTypes.addAll(Arrays.asList(ReceiverType.RACECOURSE, ReceiverType.MARKPASSINGS, ReceiverType.MARKPOSITIONS, ReceiverType.RACESTARTFINISH,
598 604
ReceiverType.RAWPOSITIONS, ReceiverType.SENSORDATA));
... ...
@@ -656,10 +662,11 @@ public class DomainFactoryImpl implements DomainFactory {
656 662
String raceName, BoatClass boatClass, Map<Competitor, Boat> competitorsAndBoats, Course course,
657 663
Iterable<Sideline> sidelines, WindStore windStore, long delayToLiveInMillis,
658 664
long millisecondsOverWhichToAverageWind, DynamicRaceDefinitionSet raceDefinitionSetToUpdate,
659
- URI tracTracUpdateURI, UUID tracTracEventUuid, String tracTracApiToken,
660
- boolean ignoreTracTracMarkPassings, RaceLogAndTrackedRaceResolver raceLogResolver,
661
- Consumer<DynamicTrackedRace> runBeforeExposingRace, IRace tractracRace,
662
- RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) {
665
+ URI tracTracUpdateURI, UUID tracTracEventUuid, String tracTracApiToken, boolean ignoreTracTracMarkPassings,
666
+ RaceLogAndTrackedRaceResolver raceLogResolver, Consumer<DynamicTrackedRace> runBeforeExposingRace,
667
+ IRace tractracRace, RaceTrackingHandler raceTrackingHandler,
668
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
669
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) {
663 670
synchronized (raceCache) {
664 671
RaceDefinition raceDefinition = raceCache.get(raceId);
665 672
if (raceDefinition == null) {
... ...
@@ -778,8 +785,11 @@ public class DomainFactoryImpl implements DomainFactory {
778 785
Iterable<Sideline> sidelines, WindStore windStore, long delayToLiveInMillis,
779 786
long millisecondsOverWhichToAverageWind, DynamicRaceDefinitionSet raceDefinitionSetToUpdate,
780 787
boolean useMarkPassingCalculator, RaceLogAndTrackedRaceResolver raceLogResolver,
781
- RaceTrackingHandler raceTrackingHandler, TrackingConnectorInfo trackingConnectorInfo, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) {
782
- return raceTrackingHandler.createTrackedRace(trackedRegatta, race, sidelines,
788
+ RaceTrackingHandler raceTrackingHandler, TrackingConnectorInfo trackingConnectorInfo,
789
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
790
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) {
791
+ return raceTrackingHandler
792
+ .createTrackedRace(trackedRegatta, race, sidelines,
783 793
windStore, delayToLiveInMillis, millisecondsOverWhichToAverageWind,
784 794
/* time over which to average speed: */ race.getBoatClass().getApproximateManeuverDurationInMilliseconds(),
785 795
raceDefinitionSetToUpdate, useMarkPassingCalculator, raceLogResolver, Optional.empty(),
java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/RaceCourseReceiver.java
... ...
@@ -80,12 +80,15 @@ public class RaceCourseReceiver extends AbstractReceiverWithQueue<IControlRoute,
80 80
81 81
public RaceCourseReceiver(DomainFactory domainFactory, DynamicTrackedRegatta trackedRegatta, IEvent tractracEvent,
82 82
IRace tractracRace, WindStore windStore, DynamicRaceDefinitionSet raceDefinitionSetToUpdate,
83
- long delayToLiveInMillis, long millisecondsOverWhichToAverageWind, Simulator simulator,
84
- URI updateURI, String tracTracApiToken,
85
- IEventSubscriber eventSubscriber, IRaceSubscriber raceSubscriber, boolean useInternalMarkPassingAlgorithm,
86
- RaceLogAndTrackedRaceResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds,
87
- RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) {
88
- super(domainFactory, tractracEvent, trackedRegatta, simulator, eventSubscriber, raceSubscriber, timeoutInMilliseconds);
83
+ long delayToLiveInMillis, long millisecondsOverWhichToAverageWind, Simulator simulator, URI updateURI,
84
+ String tracTracApiToken, IEventSubscriber eventSubscriber, IRaceSubscriber raceSubscriber,
85
+ boolean useInternalMarkPassingAlgorithm, RaceLogAndTrackedRaceResolver raceLogResolver,
86
+ LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds,
87
+ RaceTrackingHandler raceTrackingHandler,
88
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
89
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) {
90
+ super(domainFactory, tractracEvent, trackedRegatta, simulator, eventSubscriber,
91
+ raceSubscriber, timeoutInMilliseconds);
89 92
this.tractracRace = tractracRace;
90 93
this.raceLogResolver = raceLogResolver;
91 94
this.markPassingRaceFingerprintRegistry = markPassingRaceFingerprintRegistry;
... ...
@@ -265,7 +268,7 @@ public class RaceCourseReceiver extends AbstractReceiverWithQueue<IControlRoute,
265 268
/* ThreadLocalTransporter not needed because the RaceTracker is not active on a replica */ Optional
266 269
.empty(),
267 270
new TrackingConnectorInfoImpl(TracTracAdapter.NAME, TracTracAdapter.DEFAULT_URL,
268
- webUrlString), markPassingRaceFingerprintRegistry, /* maneuverRaceFingerprintRegistry */ null);
271
+ webUrlString), markPassingRaceFingerprintRegistry, maneuverRaceFingerprintRegistry);
269 272
if (runAfterCreatingTrackedRace != null) {
270 273
runAfterCreatingTrackedRace.accept(trackedRace);
271 274
}
java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/RaceTrackingConnectivityParametersImpl.java
... ...
@@ -132,8 +132,10 @@ public class RaceTrackingConnectivityParametersImpl extends AbstractRaceTracking
132 132
@Override
133 133
public RaceTracker createRaceTracker(TrackedRegattaRegistry trackedRegattaRegistry, WindStore windStore,
134 134
RaceLogAndTrackedRaceResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver,
135
- long timeoutInMilliseconds, RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) throws URISyntaxException,
136
- CreateModelException, SubscriberInitializationException, IOException, InterruptedException, TimeOutException {
135
+ long timeoutInMilliseconds, RaceTrackingHandler raceTrackingHandler,
136
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
137
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry)
138
+ throws URISyntaxException, CreateModelException, SubscriberInitializationException, IOException, InterruptedException, TimeOutException {
137 139
RaceTracker tracker = domainFactory.createRaceTracker(raceLogStore, regattaLogStore, windStore,
138 140
trackedRegattaRegistry, raceLogResolver, leaderboardGroupResolver, this, timeoutInMilliseconds,
139 141
raceTrackingHandler, markPassingRaceFingerprintRegistry, maneuverRaceFingerprintRegistry);
... ...
@@ -142,8 +144,11 @@ public class RaceTrackingConnectivityParametersImpl extends AbstractRaceTracking
142 144
143 145
@Override
144 146
public RaceTracker createRaceTracker(Regatta regatta, TrackedRegattaRegistry trackedRegattaRegistry,
145
- WindStore windStore, RaceLogAndTrackedRaceResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver,
146
- long timeoutInMilliseconds, RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) throws Exception {
147
+ WindStore windStore, RaceLogAndTrackedRaceResolver raceLogResolver,
148
+ LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds,
149
+ RaceTrackingHandler raceTrackingHandler,
150
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
151
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) throws Exception {
147 152
RaceTracker tracker = domainFactory.createRaceTracker(regatta, raceLogStore, regattaLogStore, windStore,
148 153
trackedRegattaRegistry, raceLogResolver, leaderboardGroupResolver, this, timeoutInMilliseconds,
149 154
raceTrackingHandler, markPassingRaceFingerprintRegistry, maneuverRaceFingerprintRegistry);
java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/TracTracRaceTrackerImpl.java
... ...
@@ -277,8 +277,11 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl<RaceTrackin
277 277
WindStore windStore, TrackedRegattaRegistry trackedRegattaRegistry,
278 278
RaceLogAndTrackedRaceResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver,
279 279
RaceTrackingConnectivityParametersImpl connectivityParams, long timeoutInMilliseconds,
280
- RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) throws URISyntaxException, SubscriberInitializationException,
281
- IOException, InterruptedException, CreateModelException, TimeOutException {
280
+ RaceTrackingHandler raceTrackingHandler,
281
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
282
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry)
283
+ throws URISyntaxException, SubscriberInitializationException, IOException, InterruptedException,
284
+ CreateModelException, TimeOutException {
282 285
this(/* regatta */ null, domainFactory, raceLogStore, regattaLogStore, windStore, trackedRegattaRegistry,
283 286
raceLogResolver, leaderboardGroupResolver, connectivityParams, timeoutInMilliseconds,
284 287
raceTrackingHandler, markPassingRaceFingerprintRegistry, maneuverRaceFingerprintRegistry);
... ...
@@ -302,8 +305,11 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl<RaceTrackin
302 305
RegattaLogStore regattaLogStore, WindStore windStore, TrackedRegattaRegistry trackedRegattaRegistry,
303 306
RaceLogAndTrackedRaceResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver,
304 307
RaceTrackingConnectivityParametersImpl connectivityParams, long timeoutInMilliseconds,
305
- RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry)
306
- throws URISyntaxException, SubscriberInitializationException, IOException, InterruptedException, CreateModelException, TimeOutException {
308
+ RaceTrackingHandler raceTrackingHandler,
309
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
310
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry)
311
+ throws URISyntaxException, SubscriberInitializationException,
312
+ IOException, InterruptedException, CreateModelException, TimeOutException {
307 313
super(connectivityParams);
308 314
final URL paramURL = connectivityParams.getParamURL();
309 315
final URI liveURI = connectivityParams.getLiveURI();
java/com.sap.sailing.domain.yellowbrickadapter/src/com/sap/sailing/domain/yellowbrickadapter/YellowBrickRaceTrackingConnectivityParams.java
... ...
@@ -47,20 +47,25 @@ public class YellowBrickRaceTrackingConnectivityParams extends AbstractRaceTrack
47 47
@Override
48 48
public RaceTracker createRaceTracker(TrackedRegattaRegistry trackedRegattaRegistry, WindStore windStore,
49 49
RaceLogAndTrackedRaceResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver,
50
- long timeoutInMilliseconds, RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) throws Exception {
50
+ long timeoutInMilliseconds, RaceTrackingHandler raceTrackingHandler,
51
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
52
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) throws Exception {
51 53
return new YellowBrickRaceTrackerImpl(this, /* regatta */ null, trackedRegattaRegistry, windStore,
52 54
raceLogResolver, leaderboardGroupResolver, timeoutInMilliseconds, raceTrackingHandler, raceLogStore,
53
- regattaLogStore, baseDomainFactory, yellowBrickTrackingAdapter);
55
+ regattaLogStore, baseDomainFactory, yellowBrickTrackingAdapter, markPassingRaceFingerprintRegistry, maneuverRaceFingerprintRegistry);
54 56
}
55 57
56 58
@Override
57 59
public RaceTracker createRaceTracker(Regatta regatta, TrackedRegattaRegistry trackedRegattaRegistry,
58 60
WindStore windStore, RaceLogAndTrackedRaceResolver raceLogResolver,
59 61
LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds,
60
- RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) throws Exception {
61
- return new YellowBrickRaceTrackerImpl(this, regatta, trackedRegattaRegistry, windStore, raceLogResolver,
62
+ RaceTrackingHandler raceTrackingHandler,
63
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
64
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) throws Exception {
65
+ return new YellowBrickRaceTrackerImpl(this, regatta, trackedRegattaRegistry,
66
+ windStore, raceLogResolver,
62 67
leaderboardGroupResolver, timeoutInMilliseconds, raceTrackingHandler, raceLogStore, regattaLogStore,
63
- baseDomainFactory, yellowBrickTrackingAdapter);
68
+ baseDomainFactory, yellowBrickTrackingAdapter, markPassingRaceFingerprintRegistry, maneuverRaceFingerprintRegistry);
64 69
}
65 70
66 71
@Override
java/com.sap.sailing.domain.yellowbrickadapter/src/com/sap/sailing/domain/yellowbrickadapter/impl/YellowBrickRaceTrackerImpl.java
... ...
@@ -44,6 +44,8 @@ import com.sap.sailing.domain.common.TrackedRaceStatusEnum;
44 44
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
45 45
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
46 46
import com.sap.sailing.domain.leaderboard.LeaderboardGroupResolver;
47
+import com.sap.sailing.domain.maneuverhash.ManeuverRaceFingerprintRegistry;
48
+import com.sap.sailing.domain.markpassinghash.MarkPassingRaceFingerprintRegistry;
47 49
import com.sap.sailing.domain.racelog.RaceLogAndTrackedRaceResolver;
48 50
import com.sap.sailing.domain.racelog.RaceLogStore;
49 51
import com.sap.sailing.domain.regattalog.RegattaLogStore;
... ...
@@ -125,7 +127,9 @@ implements TrackingDataLoader {
125 127
RaceLogAndTrackedRaceResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver,
126 128
long timeoutInMilliseconds, RaceTrackingHandler raceTrackingHandler, RaceLogStore raceLogStore,
127 129
RegattaLogStore regattaLogStore, DomainFactory baseDomainFactory,
128
- YellowBrickTrackingAdapter yellowBrickTrackingAdapter) throws IOException, ParseException {
130
+ YellowBrickTrackingAdapter yellowBrickTrackingAdapter,
131
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
132
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) throws IOException, ParseException {
129 133
super(connectivityParams);
130 134
visitors = new HashMap<>();
131 135
this.timePointOfLastFixPerDeviceSerialNumber = new HashMap<>();
... ...
@@ -148,7 +152,8 @@ implements TrackingDataLoader {
148 152
}
149 153
}, /* useInternalMarkPassingAlgorithm */ true, raceLogResolver,
150 154
/* Not needed because the RaceTracker is not active on a replica */ Optional.empty(),
151
- new TrackingConnectorInfoImpl(YellowBrickTrackingAdapter.NAME, "https://www.ybtracking.com/", /* TODO any default YB tracker URL? */ null), /* markPassingRaceFingerprintRegistry */ null, /*maneuverRaceFingerprintRegistry*/ null);
155
+ new TrackingConnectorInfoImpl(YellowBrickTrackingAdapter.NAME, "https://www.ybtracking.com/", /* TODO any default YB tracker URL? */ null),
156
+ markPassingRaceFingerprintRegistry, maneuverRaceFingerprintRegistry);
152 157
addRaceLogListenerForCourseUpdates();
153 158
loadStoredData();
154 159
schedulePeriodicPollingTask();
java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/DomainFactory.java
... ...
@@ -51,14 +51,9 @@ public interface DomainFactory extends SharedDomainFactory<RaceLogAndTrackedRace
51 51
}
52 52
53 53
@Override
54
- public List<Triple<Leaderboard, RaceColumn, Fleet>> getColumnsWithRaceLogForTrackedRace(
55
- RegattaAndRaceIdentifier trackedRaceIdentifier) {
56
- // TODO Auto-generated method stub
54
+ public List<Triple<Leaderboard, RaceColumn, Fleet>> getColumnsWithRaceLogForTrackedRace(RegattaAndRaceIdentifier trackedRaceIdentifier) {
57 55
return null;
58 56
}
59
-
60
-
61
-
62 57
};
63 58
64 59
/**
java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/ManeuverCurveWithUnstableCourseAndSpeedWithEstimationDataImpl.java
... ...
@@ -9,7 +9,7 @@ import com.sap.sse.common.TimePoint;
9 9
10 10
public class ManeuverCurveWithUnstableCourseAndSpeedWithEstimationDataImpl extends ManeuverCurveBoundariesImpl
11 11
implements ManeuverCurveWithUnstableCourseAndSpeedWithEstimationData {
12
-
12
+ private static final long serialVersionUID = 1227678171850468360L;
13 13
private final SpeedWithBearing averageSpeedWithBearingBefore;
14 14
private final Duration durationFromPreviousManeuverEndToManeuverStart;
15 15
private final SpeedWithBearing averageSpeedWithBearingAfter;
java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/ManeuverMainCurveDetailsWithBearingSteps.java
... ...
@@ -15,7 +15,7 @@ import com.sap.sse.common.TimePoint;
15 15
*
16 16
*/
17 17
public class ManeuverMainCurveDetailsWithBearingSteps extends ManeuverCurveBoundariesImpl {
18
-
18
+ private static final long serialVersionUID = 5448900675868938268L;
19 19
private final TimePoint timePoint;
20 20
private final double maxTurningRateInDegreesPerSecond;
21 21
private final SpeedWithBearingStepsIterable speedWithBearingSteps;
java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/ManeuverMainCurveWithEstimationDataImpl.java
... ...
@@ -14,7 +14,7 @@ import com.sap.sse.common.TimePoint;
14 14
*/
15 15
public class ManeuverMainCurveWithEstimationDataImpl extends ManeuverCurveBoundariesImpl
16 16
implements ManeuverMainCurveWithEstimationData {
17
-
17
+ private static final long serialVersionUID = -4524731853320916173L;
18 18
private final TimePoint lowestSpeedTimePoint;
19 19
private final TimePoint highestSpeedTimePoint;
20 20
private final TimePoint timePointOfMaxTurningRate;
java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverhash/ManeuverCache.java
... ...
@@ -1,14 +1,16 @@
1 1
package com.sap.sailing.domain.maneuverhash;
2 2
3
-import com.sap.sse.util.SmartFutureCache.UpdateInterval;
3
+import java.util.List;
4 4
5
-public interface ManeuverCache<K, V, U extends UpdateInterval<U>>{
5
+import com.sap.sailing.domain.base.Competitor;
6
+import com.sap.sailing.domain.tracking.Maneuver;
6 7
8
+public interface ManeuverCache {
7 9
void resume();
8 10
9
- V get(K key, boolean waitForLatest);
11
+ List<Maneuver> get(Competitor key, boolean waitForLatest);
10 12
11 13
void suspend();
12 14
13
- void triggerUpdate(K key, U updateInterval);
15
+ void triggerUpdate(Competitor key);
14 16
}
... ...
\ No newline at end of file
java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverhash/ManeuverRaceFingerprint.java
... ...
@@ -1,24 +1,12 @@
1 1
package com.sap.sailing.domain.maneuverhash;
2 2
3
-
4
-import org.json.simple.JSONObject;
5
-
6
-import com.sap.sailing.domain.tracking.TrackedRace;
7
-
8
-public interface ManeuverRaceFingerprint {
9
-
10
- /**
11
- * Returns a {@link JSONObject} of the hash values.
12
- */
13
- JSONObject toJson();
14
-
15
- /**
16
- * Incrementally computes the composite fingerprint of the {@code trackedRace} and compares to this fingerprint
17
- * component by component. The fingerprint components are computed in ascending order of computational complexity,
18
- * trying to fail early / fast.<p>
19
- *
20
- * @return {@code true} if the {@code trackedRace} produces a fingerprint equal to this one if passed to
21
- * {@link ManeuverRaceFingerprintFactory#createFingerprint(TrackedRace)}
22
- */
23
- boolean matches(TrackedRace trackedRace);
3
+import com.sap.sailing.domain.base.Competitor;
4
+import com.sap.sailing.domain.tracking.Maneuver;
5
+import com.sap.sailing.domain.tracking.RaceFingerprint;
6
+
7
+/**
8
+ * Contains fingerprint data that encodes the state of the race relevant for computing all {@link Maneuver}s
9
+ * for all {@link Competitor}s.
10
+ */
11
+public interface ManeuverRaceFingerprint extends RaceFingerprint {
24 12
}
java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverhash/ManeuverRaceFingerprintFactory.java
... ...
@@ -1,13 +1,8 @@
1 1
package com.sap.sailing.domain.maneuverhash;
2 2
3
-import com.sap.sailing.domain.tracking.TrackedRace;
4 3
import com.sap.sailing.domain.maneuverhash.impl.ManeuverRaceFingerprintFactoryImpl;
5
-import org.json.simple.JSONObject;
4
+import com.sap.sailing.domain.tracking.RaceFingerprintFactory;
6 5
7
-public interface ManeuverRaceFingerprintFactory {
6
+public interface ManeuverRaceFingerprintFactory extends RaceFingerprintFactory<ManeuverRaceFingerprint> {
8 7
ManeuverRaceFingerprintFactory INSTANCE = new ManeuverRaceFingerprintFactoryImpl();
9
-
10
- ManeuverRaceFingerprint createFingerprint (TrackedRace TrackedRace);
11
-
12
- ManeuverRaceFingerprint fromJson (JSONObject json);
13 8
}
java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverhash/MarkPassingProxy.java
... ...
@@ -18,7 +18,7 @@ public class MarkPassingProxy implements MarkPassing {
18 18
private MarkPassing markPassing;
19 19
private final TimePoint timePoint;
20 20
21
- public MarkPassingProxy(TimePoint timePoint, int waypointIndex, Serializable competitorId, TrackedRace trackedRace ) {
21
+ public MarkPassingProxy(TimePoint timePoint, int waypointIndex, Serializable competitorId, TrackedRace trackedRace) {
22 22
super();
23 23
this.timePoint = timePoint;
24 24
this.waypointIndex = waypointIndex;
... ...
@@ -28,30 +28,24 @@ public class MarkPassingProxy implements MarkPassing {
28 28
29 29
@Override
30 30
public TimePoint getTimePoint() {
31
- return timePoint;
31
+ return timePoint;
32 32
}
33 33
34 34
@Override
35 35
public Waypoint getWaypoint() {
36 36
Iterable<Waypoint> waypoints = trackedRace.getRace().getCourse().getWaypoints();
37
- return Util.get(waypoints, waypointIndex);
37
+ return Util.get(waypoints, waypointIndex);
38 38
}
39 39
40 40
@Override
41 41
public Competitor getCompetitor() {
42
- Iterable<Competitor> competitors = trackedRace.getRace().getCompetitors();
43
- for (Competitor c : competitors ) {
44
- if( c.getId() == competitorId) {
45
- return c;
46
- }
47
- }
48
- return null;
42
+ return trackedRace.getRace().getCompetitorById(competitorId);
49 43
}
50 44
51 45
@Override
52 46
public MarkPassing getOriginal() {
53 47
isMarkPassing();
54
- return markPassing.getOriginal();
48
+ return markPassing == null ? null : markPassing.getOriginal();
55 49
}
56 50
57 51
private void isMarkPassing() {
java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverhash/SerializableManeuverCache.java
... ...
@@ -0,0 +1,7 @@
1
+package com.sap.sailing.domain.maneuverhash;
2
+
3
+import java.io.Serializable;
4
+
5
+public interface SerializableManeuverCache extends ManeuverCache, Serializable {
6
+
7
+}
java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverhash/impl/ManeuverCacheDelegate.java
... ...
@@ -1,9 +1,11 @@
1 1
package com.sap.sailing.domain.maneuverhash.impl;
2 2
3
+import java.io.IOException;
4
+import java.io.ObjectInputStream;
5
+import java.io.ObjectOutputStream;
3 6
import java.util.HashMap;
4 7
import java.util.List;
5 8
import java.util.Map;
6
-
7 9
import java.util.logging.Logger;
8 10
9 11
import com.sap.sailing.domain.base.Competitor;
... ...
@@ -11,99 +13,90 @@ import com.sap.sailing.domain.maneuverhash.ManeuverCache;
11 13
import com.sap.sailing.domain.maneuverhash.ManeuverRaceFingerprint;
12 14
import com.sap.sailing.domain.maneuverhash.ManeuverRaceFingerprintFactory;
13 15
import com.sap.sailing.domain.maneuverhash.ManeuverRaceFingerprintRegistry;
16
+import com.sap.sailing.domain.maneuverhash.SerializableManeuverCache;
14 17
import com.sap.sailing.domain.tracking.Maneuver;
15 18
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
16 19
import com.sap.sailing.domain.tracking.impl.TrackedRaceImpl;
17
-import com.sap.sse.util.SmartFutureCache.EmptyUpdateInterval;
18
-
19
-public class ManeuverCacheDelegate implements ManeuverCache<Competitor, List<Maneuver>, EmptyUpdateInterval> {
20 20
21
+public class ManeuverCacheDelegate implements SerializableManeuverCache {
22
+ private static final long serialVersionUID = 19872309587435L;
21 23
private final TrackedRaceImpl race;
22 24
private static final Logger logger = Logger.getLogger(ManeuverCacheDelegate.class.getName());
23 25
private final ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry;
24
- Map<Competitor, List<Maneuver>> maneuvers = new HashMap<>();
25
- private ManeuverCache<Competitor, List<Maneuver>, EmptyUpdateInterval> cacheToUse;
26
+ private volatile transient ManeuverCache cacheToUse;
26 27
27 28
public ManeuverCacheDelegate(TrackedRaceImpl race,
28 29
ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) {
29 30
super();
30 31
this.race = race;
31 32
this.maneuverRaceFingerprintRegistry = maneuverRaceFingerprintRegistry;
32
- this.cacheToUse = new ManeuverFromSmartFutureCache((DynamicTrackedRaceImpl) race);
33
+ this.cacheToUse = new ManeuversFromSmartFutureCache((DynamicTrackedRaceImpl) race);
33 34
}
34 35
36
+ private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
37
+ ois.defaultReadObject();
38
+ this.cacheToUse = (ManeuversFromDatabase) ois.readObject();
39
+ }
40
+
41
+ private void writeObject(ObjectOutputStream oos) throws IOException {
42
+ oos.defaultWriteObject();
43
+ oos.writeObject(new ManeuversFromDatabase(getAllKnownManeuvers()));
44
+ }
45
+
46
+ private Map<Competitor, List<Maneuver>> getAllKnownManeuvers() {
47
+ final Map<Competitor, List<Maneuver>> result = new HashMap<>();
48
+ for (final Competitor competitor : race.getRace().getCompetitors()) {
49
+ final List<Maneuver> maneuversForCompetitor = get(competitor, /* waitForLatest */ false);
50
+ if (maneuversForCompetitor != null) {
51
+ result.put(competitor, maneuversForCompetitor);
52
+ }
53
+ }
54
+ return result;
55
+ }
56
+
35 57
@Override
36 58
public void resume() {
37
- ManeuverRaceFingerprint fingerprint;
38
- race.getRace().getCourse().lockForRead();
39
- try {
40
- synchronized (this) {
59
+ final ManeuverRaceFingerprint fingerprint;
60
+ if (maneuverRaceFingerprintRegistry != null) {
61
+ logger.info("Compare maneuver fingerprints for race "+race.getRaceIdentifier());
62
+ race.waitForAllRaceLogsAttached();
63
+ fingerprint = maneuverRaceFingerprintRegistry.getManeuverRaceFingerprint(race.getRaceIdentifier());
64
+ } else {
65
+ fingerprint = null;
66
+ }
67
+ if (fingerprint != null && fingerprint.matches(race)) {
68
+ logger.info("Maneuver fingerprints match for race "+race.getRaceIdentifier()+"; loading from DB instead of computing");
69
+ cacheToUse = new ManeuversFromDatabase(maneuverRaceFingerprintRegistry.loadManeuvers(race, race.getRace().getCourse()));
70
+ } else {
71
+ new Thread(()->{
72
+ logger.info("Maneuver fingerprints do not match for race "+race.getRaceIdentifier()+"; NOT loading from DB");
73
+ cacheToUse.resume();
41 74
if (maneuverRaceFingerprintRegistry != null) {
42
- logger.info("Compare maneuverfingerprints");
43
- race.waitForAllRaceLogsAttached();
44
- fingerprint = maneuverRaceFingerprintRegistry.getManeuverRaceFingerprint(race.getRaceIdentifier());
45
- } else {
46
- fingerprint = null;
47
- }
48
- if (fingerprint != null && fingerprint.matches(race)) {
49
- logger.info("maneuverfingerprints match");
50
- maneuvers = maneuverRaceFingerprintRegistry.loadManeuvers(race, race.getRace().getCourse());
51
- cacheToUse = new ManeuverFromDatabase( maneuvers);
52
- } else {
53
- new Thread(()->{
54
- logger.info("maneuverfingerprints do not match");
55
- cacheToUse.resume();
56
- for(Competitor competitor : race.getRace().getCompetitors()) {
57
-
58
- maneuvers.put(competitor, (List<Maneuver>) cacheToUse.get(competitor, true));
59
- }
60
- maneuverRaceFingerprintRegistry.storeManeuvers(race.getRaceIdentifier(), ManeuverRaceFingerprintFactory.INSTANCE.createFingerprint(race), maneuvers, race.getRace().getCourse());
61
- }, "Waiting for mark passings for "+race.getName()+" after having resumed to store the results in registry")
62
- .start();
75
+ // wait for maneuvers to be computed by the default cache implementation (SmartFutureCache),
76
+ // then store persistently in registry
77
+ final Map<Competitor, List<Maneuver>> maneuvers = new HashMap<>();
78
+ for (final Competitor competitor : race.getRace().getCompetitors()) {
79
+ maneuvers.put(competitor, (List<Maneuver>) cacheToUse.get(competitor, /* waitForLatest */ true));
80
+ }
81
+ maneuverRaceFingerprintRegistry.storeManeuvers(race.getRaceIdentifier(), ManeuverRaceFingerprintFactory.INSTANCE.createFingerprint(race), maneuvers, race.getRace().getCourse());
63 82
}
64
- }
65
- } finally {
66
- race.getRace().getCourse().unlockAfterRead();
83
+ }, "Waiting for mark passings for "+race.getName()+" after having resumed to store the results in registry")
84
+ .start();
67 85
}
68 86
}
69 87
70 88
@Override
71 89
public List<Maneuver> get(Competitor competitor, boolean waitForLatest) {
72
- race.getRace().getCourse().lockForRead();
73
- try {
74
- synchronized (this) {
75
-
76
- return (List<Maneuver>) cacheToUse.get(competitor, waitForLatest);
77
- }
78
-
79
- } finally {
80
- race.getRace().getCourse().unlockAfterRead();
81
- }
90
+ return cacheToUse.get(competitor, waitForLatest);
82 91
}
83 92
84 93
@Override
85 94
public void suspend() {
86
- race.getRace().getCourse().lockForRead();
87
- try {
88
- synchronized (this) {
89
-
90
- cacheToUse.suspend();
91
- }
92
- } finally {
93
- race.getRace().getCourse().unlockAfterRead();
94
- }
95
+ cacheToUse.suspend();
95 96
}
96 97
97 98
@Override
98
- public void triggerUpdate(Competitor competitor, EmptyUpdateInterval updateInterval) {
99
- race.getRace().getCourse().lockForRead();
100
- try {
101
- synchronized (this) {
102
-
103
- cacheToUse.triggerUpdate(competitor, updateInterval);
104
- }
105
- } finally {
106
- race.getRace().getCourse().unlockAfterRead();
107
- }
99
+ public void triggerUpdate(Competitor competitor) {
100
+ cacheToUse.triggerUpdate(competitor);
108 101
}
109 102
}
... ...
\ No newline at end of file
java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverhash/impl/ManeuverFromDatabase.java
... ...
@@ -1,45 +0,0 @@
1
-package com.sap.sailing.domain.maneuverhash.impl;
2
-
3
-import java.util.List;
4
-import java.util.Map;
5
-import java.util.logging.Level;
6
-import java.util.logging.Logger;
7
-
8
-import com.sap.sailing.domain.base.Competitor;
9
-import com.sap.sailing.domain.maneuverhash.ManeuverCache;
10
-import com.sap.sailing.domain.tracking.Maneuver;
11
-import com.sap.sse.util.SmartFutureCache.EmptyUpdateInterval;
12
-
13
-public class ManeuverFromDatabase implements ManeuverCache<Competitor, List<Maneuver>, EmptyUpdateInterval> {
14
-
15
- public ManeuverFromDatabase(
16
- Map<Competitor, List<Maneuver>> maneuvers) {
17
- super();
18
- this.maneuvers = maneuvers;
19
- }
20
-
21
- boolean suspended;
22
- private static final Logger logger = Logger.getLogger(ManeuverFromDatabase.class.getName());
23
- Map<Competitor, List<Maneuver>> maneuvers;
24
-
25
- public void resume() {
26
- logger.log(Level.WARNING, "Method should never be called");
27
- }
28
-
29
- public void suspend() {
30
- synchronized (this) {
31
- logger.finest("Suspended ManeuverFromDatabase");
32
- suspended = true;
33
- }
34
- }
35
-
36
- public List<Maneuver> get(Competitor competitor, boolean waitForLatest) {
37
- return maneuvers.get(competitor);
38
- }
39
-
40
- @Override
41
- public void triggerUpdate(Competitor key, EmptyUpdateInterval updateInterval) {
42
- logger.log(Level.WARNING, "If Fingerprint matches, no Update should be triggered");
43
- //TODO change to smartFutureCache in Delegate
44
- }
45
-}
... ...
\ No newline at end of file
java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverhash/impl/ManeuverFromSmartFutureCache.java
... ...
@@ -1,68 +0,0 @@
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.impl.DynamicTrackedRaceImpl;
13
-import com.sap.sse.common.Duration;
14
-import com.sap.sse.util.SmartFutureCache;
15
-import com.sap.sse.util.SmartFutureCache.AbstractCacheUpdater;
16
-import com.sap.sse.util.SmartFutureCache.EmptyUpdateInterval;
17
-
18
-public class ManeuverFromSmartFutureCache implements ManeuverCache<Competitor, List<Maneuver>, EmptyUpdateInterval> {
19
-
20
- private final SmartFutureCache<Competitor, List<Maneuver>, EmptyUpdateInterval> smartFutureCache;
21
-
22
- public ManeuverFromSmartFutureCache(DynamicTrackedRaceImpl race) {
23
- this.smartFutureCache= new SmartFutureCache<Competitor, List<Maneuver>, EmptyUpdateInterval>(
24
- new AbstractCacheUpdater<Competitor, List<Maneuver>, EmptyUpdateInterval>() {
25
- @Override
26
- public List<Maneuver> computeCacheUpdate(Competitor competitor, EmptyUpdateInterval updateInterval)
27
- throws NoWindException {
28
- return race.getTrackedRegatta().callWithCPUMeterWithException(()->{
29
- Duration averageIntervalBetweenRawFixes = race.getTrack(competitor).getAverageIntervalBetweenRawFixes();
30
- if (averageIntervalBetweenRawFixes != null) {
31
- ManeuverDetector maneuverDetector;
32
- // 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
33
- // if (averageIntervalBetweenRawFixes.asSeconds() >= 30) {
34
- // maneuverDetector = new LowGPSSamplingRateManeuverDetectorImpl(TrackedRaceImpl.this, competitor);
35
- // } else {
36
- maneuverDetector = race.getManeuverDetectorPerCompetitorCache().getValue(competitor);
37
- // }
38
- List<Maneuver> maneuvers = race.computeManeuvers(competitor, maneuverDetector);
39
- return maneuvers;
40
- } else {
41
- return Collections.emptyList();
42
- }
43
- }, CPUMeteringType.MANEUVER_DETECTION.name());
44
- }
45
- },//.computeCacheUpdate(competitor, null),
46
- /* nameForLocks */ "Maneuver cache for race " + race.getRace().getName());
47
- }
48
-
49
- @Override
50
- public void resume() {
51
- smartFutureCache.resume();
52
- }
53
-
54
- @Override
55
- public List<Maneuver> get(Competitor key, boolean waitForLatest) {
56
- return smartFutureCache.get(key, waitForLatest);
57
- }
58
-
59
- @Override
60
- public void suspend() {
61
- smartFutureCache.suspend();
62
- }
63
-
64
- @Override
65
- public void triggerUpdate(Competitor key, EmptyUpdateInterval updateInterval) {
66
- smartFutureCache.triggerUpdate(key, updateInterval);
67
- }
68
-}
java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverhash/impl/ManeuverRaceFingerprintImpl.java
... ...
@@ -4,248 +4,76 @@ import java.util.Set;
4 4
5 5
import org.json.simple.JSONObject;
6 6
7
-import com.sap.sailing.domain.abstractlog.race.RaceLog;
8
-import com.sap.sailing.domain.abstractlog.race.analyzing.impl.MarkPassingDataFinder;
9
-import com.sap.sailing.domain.base.Competitor;
10
-import com.sap.sailing.domain.base.Mark;
11
-import com.sap.sailing.domain.base.Waypoint;
12 7
import com.sap.sailing.domain.common.Wind;
13 8
import com.sap.sailing.domain.common.WindSource;
14
-import com.sap.sailing.domain.common.tracking.GPSFix;
15
-import com.sap.sailing.domain.common.tracking.GPSFixMoving;
16 9
import com.sap.sailing.domain.maneuverdetection.impl.ManeuverDetectorImpl;
17 10
import com.sap.sailing.domain.maneuverhash.ManeuverRaceFingerprint;
18
-import com.sap.sailing.domain.markpassingcalculation.MarkPassingCalculator;
19
-import com.sap.sailing.domain.tracking.GPSFixTrack;
11
+import com.sap.sailing.domain.markpassinghash.impl.MarkPassingRaceFingerprintImpl;
20 12
import com.sap.sailing.domain.tracking.TrackedRace;
21 13
import com.sap.sailing.domain.tracking.WindTrack;
22
-import com.sap.sse.common.TimePoint;
23 14
import com.sap.sse.common.Util;
24
-import com.sap.sse.common.Util.Pair;
25
-import com.sap.sse.common.Util.Triple;
26 15
27
-public class ManeuverRaceFingerprintImpl implements ManeuverRaceFingerprint {
28
- private final int calculatorVersion;
29
- private final int competitorHash;
30
- private final TimePoint startOfTracking;
31
- private final TimePoint startTimeReceived;
32
- private final TimePoint endOfTracking;
33
- private final TimePoint startTimeFromRaceLog;
34
- private final TimePoint finishTimeFromRaceLog;
35
- private final int fixedAndSuppressedMarkPassingsFromRaceLogHash;
36
- private final int waypointsHash;
37
- private final int numberOfGPSFixes;
38
- private final int gpsFixesHash;
16
+public class ManeuverRaceFingerprintImpl extends MarkPassingRaceFingerprintImpl implements ManeuverRaceFingerprint {
39 17
private final int windHash;
40 18
private final int detectorVersion;
41 19
42 20
private static enum JSON_FIELDS {
43
- COMPETITOR_HASH, START_OF_TRACKING_AS_MILLIS, END_OF_TRACKING_AS_MILLIS, START_TIME_RECEIVED_AS_MILLIS,
44
- START_TIME_FROM_RACE_LOG_AS_MILLIS, FINISH_TIME_FROM_RACE_LOG_AS_MILLIS, WAYPOINTS_HASH, NUMBEROFGPSFIXES,
45
- GPSFIXES_HASH, RACE_ID, CALCULATOR_VERSION, FIXED_AND_SUPPRESSED_MARK_PASSINGS_FROM_RACE_LOG_HASH, WIND_HASH, DETECTOR_VERSION
21
+ WIND_HASH, DETECTOR_VERSION
46 22
};
47 23
48 24
public ManeuverRaceFingerprintImpl(TrackedRace trackedRace) {
25
+ super(trackedRace);
49 26
this.detectorVersion = ManeuverDetectorImpl.DETECTOR_VERSION;
50
- this.calculatorVersion = MarkPassingCalculator.CALCULATOR_VERSION;
51
- this.competitorHash = calculateHashForCompetitors(trackedRace);
52
- this.startOfTracking = trackedRace.getStartOfTracking();
53
- this.endOfTracking = trackedRace.getEndOfTracking();
54
- this.startTimeReceived = trackedRace.getStartTimeReceived();
55
- final Pair<TimePoint, TimePoint> startAndFinishedTimeFromRaceLogs = trackedRace
56
- .getStartAndFinishedTimeFromRaceLogs();
57
- this.startTimeFromRaceLog = startAndFinishedTimeFromRaceLogs == null ? null
58
- : startAndFinishedTimeFromRaceLogs.getA();
59
- this.finishTimeFromRaceLog = startAndFinishedTimeFromRaceLogs == null ? null
60
- : startAndFinishedTimeFromRaceLogs.getB();
61
- this.waypointsHash = calculateHashForWaypoints(trackedRace);
62
- this.numberOfGPSFixes = calculateHashForNumberOfGPSFixes(trackedRace);
63
- this.gpsFixesHash = calculateHashForGPSFixes(trackedRace);
64
- this.fixedAndSuppressedMarkPassingsFromRaceLogHash = calculateFixedAndSuppressedMarkPassingsFromRaceLogHash(trackedRace);
65 27
this.windHash = calculateWindHash(trackedRace);
66 28
}
67 29
68
- private int calculateFixedAndSuppressedMarkPassingsFromRaceLogHash(TrackedRace trackedRace) {
69
- int result = 1023;
70
- for (final RaceLog raceLog : trackedRace.getAttachedRaceLogs()) {
71
- for (final Triple<Competitor, Integer, TimePoint> triple : new MarkPassingDataFinder(raceLog).analyze()) {
72
- result ^= triple.getA().getId().hashCode();
73
- result ^= triple.getB();
74
- if (triple.getC() != null) {
75
- result ^= triple.getC().hashCode();
76
- }
77
- }
78
- }
79
- return result;
80
- }
81
-
82 30
public ManeuverRaceFingerprintImpl(JSONObject json) {
31
+ super(json);
83 32
this.detectorVersion = ((Number) json.get(JSON_FIELDS.DETECTOR_VERSION.name())).intValue();
84
- this.calculatorVersion = ((Number) json.get(JSON_FIELDS.CALCULATOR_VERSION.name())).intValue();
85
- this.competitorHash = ((Number) json.get(JSON_FIELDS.COMPETITOR_HASH.name())).intValue();
86
- this.startOfTracking = TimePoint.of((Long) json.get(JSON_FIELDS.START_OF_TRACKING_AS_MILLIS.name()));
87
- this.endOfTracking = TimePoint.of((Long) json.get(JSON_FIELDS.END_OF_TRACKING_AS_MILLIS.name()));
88
- this.startTimeReceived = TimePoint.of((Long) json.get(JSON_FIELDS.START_TIME_RECEIVED_AS_MILLIS.name()));
89
- this.startTimeFromRaceLog = TimePoint
90
- .of((Long) json.get(JSON_FIELDS.START_TIME_FROM_RACE_LOG_AS_MILLIS.name()));
91
- this.finishTimeFromRaceLog = TimePoint
92
- .of((Long) json.get(JSON_FIELDS.FINISH_TIME_FROM_RACE_LOG_AS_MILLIS.name()));
93
- this.waypointsHash = ((Number) json.get(JSON_FIELDS.WAYPOINTS_HASH.name())).intValue();
94
- this.numberOfGPSFixes = ((Number) json.get(JSON_FIELDS.NUMBEROFGPSFIXES.name())).intValue();
95
- this.gpsFixesHash = ((Number) json.get(JSON_FIELDS.GPSFIXES_HASH.name())).intValue();
96
- this.fixedAndSuppressedMarkPassingsFromRaceLogHash = ((Number) json.get(JSON_FIELDS.FIXED_AND_SUPPRESSED_MARK_PASSINGS_FROM_RACE_LOG_HASH.name())).intValue();
97 33
this.windHash = ((Number) json.get(JSON_FIELDS.WIND_HASH.name())).intValue();
98 34
}
99 35
100 36
@Override
101 37
public JSONObject toJson() {
102
- JSONObject result = new JSONObject();
38
+ final JSONObject result = super.toJson();
103 39
result.put(JSON_FIELDS.DETECTOR_VERSION.name(), detectorVersion);
104
- result.put(JSON_FIELDS.CALCULATOR_VERSION.name(), calculatorVersion);
105
- result.put(JSON_FIELDS.COMPETITOR_HASH.name(), competitorHash);
106
- result.put(JSON_FIELDS.START_OF_TRACKING_AS_MILLIS.name(),
107
- startOfTracking == null ? null : startOfTracking.asMillis());
108
- result.put(JSON_FIELDS.END_OF_TRACKING_AS_MILLIS.name(),
109
- endOfTracking == null ? null : endOfTracking.asMillis());
110
- result.put(JSON_FIELDS.START_TIME_RECEIVED_AS_MILLIS.name(),
111
- startTimeReceived == null ? null : startTimeReceived.asMillis());
112
- result.put(JSON_FIELDS.START_TIME_FROM_RACE_LOG_AS_MILLIS.name(),
113
- startTimeFromRaceLog == null ? null : startTimeFromRaceLog.asMillis());
114
- result.put(JSON_FIELDS.FINISH_TIME_FROM_RACE_LOG_AS_MILLIS.name(),
115
- finishTimeFromRaceLog == null ? null : finishTimeFromRaceLog.asMillis());
116
- result.put(JSON_FIELDS.WAYPOINTS_HASH.name(), waypointsHash);
117
- result.put(JSON_FIELDS.NUMBEROFGPSFIXES.name(), numberOfGPSFixes);
118
- result.put(JSON_FIELDS.GPSFIXES_HASH.name(), gpsFixesHash);
119
- result.put(JSON_FIELDS.FIXED_AND_SUPPRESSED_MARK_PASSINGS_FROM_RACE_LOG_HASH.name(), fixedAndSuppressedMarkPassingsFromRaceLogHash);
120 40
result.put(JSON_FIELDS.WIND_HASH.name(), windHash);
121 41
return result;
122 42
}
123 43
124 44
@Override
125 45
public boolean matches(TrackedRace trackedRace) {
126
- final boolean result;
127
- if (!Util.equalsWithNull(calculatorVersion, MarkPassingCalculator.CALCULATOR_VERSION)) {
128
- result = false;
129
- }else if (!Util.equalsWithNull(detectorVersion, ManeuverDetectorImpl.DETECTOR_VERSION)) {
130
- result = false;
131
- } else if (!Util.equalsWithNull(startOfTracking, trackedRace.getStartOfTracking())) {
132
- result = false;
133
- } else if (!Util.equalsWithNull(endOfTracking, trackedRace.getEndOfTracking())) {
134
- result = false;
135
- } else if (!Util.equalsWithNull(startTimeReceived, trackedRace.getStartTimeReceived())) {
136
- result = false;
137
- } else {
138
- final Pair<TimePoint, TimePoint> startAndFinishedTimeFromRaceLogs = trackedRace
139
- .getStartAndFinishedTimeFromRaceLogs();
140
- if (!Util.equalsWithNull(startTimeFromRaceLog,
141
- startAndFinishedTimeFromRaceLogs == null ? null : startAndFinishedTimeFromRaceLogs.getA())) {
142
- result = false;
143
- } else if (!Util.equalsWithNull(finishTimeFromRaceLog,
144
- startAndFinishedTimeFromRaceLogs == null ? null : startAndFinishedTimeFromRaceLogs.getB())) {
145
- result = false;
146
- } else if (waypointsHash != calculateHashForWaypoints(trackedRace)) {
147
- result = false;
148
- } else if (competitorHash != calculateHashForCompetitors(trackedRace)) {
149
- result = false;
150
- } else if (numberOfGPSFixes != calculateHashForNumberOfGPSFixes(trackedRace)) {
151
- result = false;
152
- } else if (fixedAndSuppressedMarkPassingsFromRaceLogHash != calculateFixedAndSuppressedMarkPassingsFromRaceLogHash(trackedRace)) {
153
- result = false;
154
- } else if (gpsFixesHash != calculateHashForGPSFixes(trackedRace)) {
46
+ boolean result = super.matches(trackedRace);
47
+ if (result) {
48
+ if (!Util.equalsWithNull(detectorVersion, ManeuverDetectorImpl.DETECTOR_VERSION)) {
155 49
result = false;
156 50
} else if (windHash != calculateWindHash(trackedRace)) {
157 51
result = false;
158
- }else {
159
- result = true;
160 52
}
161 53
}
162 54
return result;
163 55
}
164 56
165
- private int calculateHashForCompetitors(TrackedRace trackedRace) {
166
- int hashForCompetitors = 1023;
167
- for (Competitor c : trackedRace.getRace().getCompetitors()) {
168
- hashForCompetitors = hashForCompetitors ^ c.getId().hashCode();
169
- }
170
- return hashForCompetitors;
171
- }
172
-
173
- private int calculateHashForNumberOfGPSFixes(TrackedRace trackedRace) {
174
- int count = 0;
175
- for (Mark m : trackedRace.getMarks()) {
176
- count += trackedRace.getTrack(m).size();
177
- }
178
- for (final Competitor competitor : trackedRace.getRace().getCompetitors()) {
179
- count += trackedRace.getTrack(competitor).size();
180
- }
181
- return count;
182
- }
183
-
184
- private int calculateHashForGPSFixes(TrackedRace trackedRace) {
185
- int res = 511;
186
- for (Mark m : trackedRace.getMarks()) {
187
- final GPSFixTrack<Mark, GPSFix> markTrack = trackedRace.getTrack(m);
188
- markTrack.lockForRead();
189
- try {
190
- for (GPSFix gf : markTrack.getRawFixes()) {
191
- res = res ^ gf.getTimePoint().hashCode();
192
- res = res ^ gf.getPosition().hashCode();
193
- }
194
- } finally {
195
- markTrack.unlockAfterRead();
196
- }
197
- }
198
- for (final Competitor competitor : trackedRace.getRace().getCompetitors()) {
199
- final GPSFixTrack<Competitor, GPSFixMoving> competitorTrack = trackedRace.getTrack(competitor);
200
- competitorTrack.lockForRead();
201
- try {
202
- for (GPSFixMoving gfm : competitorTrack.getRawFixes()) {
203
- res = res ^ gfm.getTimePoint().hashCode();
204
- res = res ^ gfm.getPosition().hashCode();
205
- res = res ^ gfm.getSpeed().getBearing().hashCode();
206
- res = res ^ Double.hashCode(gfm.getSpeed().getKnots());
207
- }
208
- } finally {
209
- competitorTrack.unlockAfterRead();
210
- }
211
- }
212
- return res;
213
- }
214
-
215
- private int calculateHashForWaypoints(TrackedRace trackedRace) {
216
- Iterable<Waypoint> waypoints = trackedRace.getRace().getCourse().getWaypoints();
217
- int res = 0;
218
- for (Waypoint p : waypoints) {
219
- Iterable<Mark> marks = p.getMarks();
220
- for (Mark m : marks) {
221
- res = res ^ m.getId().hashCode();
222
- }
223
- res = res ^ p.getPassingInstructions().name().hashCode();
224
- res = (res << 5) - res; // we want to detect changes in order
225
- }
226
- return res;
227
- }
228
-
229 57
private int calculateWindHash(TrackedRace trackedRace) {
230
- Set<WindSource> windSoures = trackedRace.getWindSources();
58
+ final Set<WindSource> windSoures = trackedRace.getWindSources();
231 59
int res = 0;
232
- Set<WindSource> windSouresToExclude = trackedRace.getWindSourcesToExclude();
233
- for(WindSource w : windSoures) {
234
- if(w.getType().isObserved() && !windSouresToExclude.contains(w)) {
235
- WindTrack windTrack = trackedRace.getOrCreateWindTrack(w);
60
+ final Set<WindSource> windSouresToExclude = trackedRace.getWindSourcesToExclude();
61
+ for (WindSource w : windSoures) {
62
+ if (w.getType().isObserved() && !windSouresToExclude.contains(w)) {
63
+ final WindTrack windTrack = trackedRace.getOrCreateWindTrack(w);
236 64
windTrack.lockForRead();
237 65
try {
238
- int k = w.getId().hashCode();
66
+ int k = w.getId() == null ? 0 : w.getId().hashCode();
239 67
int v = 0;
240
- for(Wind wf : trackedRace.getOrCreateWindTrack(w).getFixes()) {
241
- v = v + (int) ( wf.getPosition().getLatDeg() + wf.getPosition().getLngDeg() + wf.getKilometersPerHour());
68
+ for (Wind wf : trackedRace.getOrCreateWindTrack(w).getFixes()) {
69
+ v = v + (int) (wf.getPosition().getLatDeg() + wf.getPosition().getLngDeg()
70
+ + wf.getKilometersPerHour());
242 71
}
243 72
res = res ^ k;
244
- res = res ^ v;
73
+ res = res ^ v;
245 74
} finally {
246 75
windTrack.unlockAfterRead();
247 76
}
248
-
249 77
}
250 78
}
251 79
return res;
... ...
@@ -254,19 +82,8 @@ public class ManeuverRaceFingerprintImpl implements ManeuverRaceFingerprint {
254 82
@Override
255 83
public int hashCode() {
256 84
final int prime = 31;
257
- int result = 1;
258
- result = prime * result + calculatorVersion;
85
+ int result = super.hashCode();
259 86
result = prime * result + detectorVersion;
260
- result = prime * result + competitorHash;
261
- result = prime * result + ((endOfTracking == null) ? 0 : endOfTracking.hashCode());
262
- result = prime * result + ((finishTimeFromRaceLog == null) ? 0 : finishTimeFromRaceLog.hashCode());
263
- result = prime * result + gpsFixesHash;
264
- result = prime * result + numberOfGPSFixes;
265
- result = prime * result + ((startOfTracking == null) ? 0 : startOfTracking.hashCode());
266
- result = prime * result + ((startTimeFromRaceLog == null) ? 0 : startTimeFromRaceLog.hashCode());
267
- result = prime * result + ((startTimeReceived == null) ? 0 : startTimeReceived.hashCode());
268
- result = prime * result + waypointsHash;
269
- result = prime * result + fixedAndSuppressedMarkPassingsFromRaceLogHash;
270 87
result = prime * result + windHash;
271 88
return result;
272 89
}
... ...
@@ -279,46 +96,11 @@ public class ManeuverRaceFingerprintImpl implements ManeuverRaceFingerprint {
279 96
return false;
280 97
if (getClass() != obj.getClass())
281 98
return false;
282
- ManeuverRaceFingerprintImpl other = (ManeuverRaceFingerprintImpl) obj;
283
- if (calculatorVersion != other.calculatorVersion)
99
+ if (!super.equals(obj))
284 100
return false;
101
+ ManeuverRaceFingerprintImpl other = (ManeuverRaceFingerprintImpl) obj;
285 102
if (detectorVersion != other.detectorVersion)
286 103
return false;
287
- if (competitorHash != other.competitorHash)
288
- return false;
289
- if (endOfTracking == null) {
290
- if (other.endOfTracking != null)
291
- return false;
292
- } else if (!endOfTracking.equals(other.endOfTracking))
293
- return false;
294
- if (finishTimeFromRaceLog == null) {
295
- if (other.finishTimeFromRaceLog != null)
296
- return false;
297
- } else if (!finishTimeFromRaceLog.equals(other.finishTimeFromRaceLog))
298
- return false;
299
- if (gpsFixesHash != other.gpsFixesHash)
300
- return false;
301
- if (numberOfGPSFixes != other.numberOfGPSFixes)
302
- return false;
303
- if (startOfTracking == null) {
304
- if (other.startOfTracking != null)
305
- return false;
306
- } else if (!startOfTracking.equals(other.startOfTracking))
307
- return false;
308
- if (startTimeFromRaceLog == null) {
309
- if (other.startTimeFromRaceLog != null)
310
- return false;
311
- } else if (!startTimeFromRaceLog.equals(other.startTimeFromRaceLog))
312
- return false;
313
- if (startTimeReceived == null) {
314
- if (other.startTimeReceived != null)
315
- return false;
316
- } else if (!startTimeReceived.equals(other.startTimeReceived))
317
- return false;
318
- if (waypointsHash != other.waypointsHash)
319
- return false;
320
- if (fixedAndSuppressedMarkPassingsFromRaceLogHash != other.fixedAndSuppressedMarkPassingsFromRaceLogHash)
321
- return false;
322 104
if (windHash != other.windHash)
323 105
return false;
324 106
return true;
java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverhash/impl/ManeuversFromDatabase.java
... ...
@@ -0,0 +1,49 @@
1
+package com.sap.sailing.domain.maneuverhash.impl;
2
+
3
+import java.util.List;
4
+import java.util.Map;
5
+import java.util.logging.Level;
6
+import java.util.logging.Logger;
7
+
8
+import com.sap.sailing.domain.base.Competitor;
9
+import com.sap.sailing.domain.maneuverhash.SerializableManeuverCache;
10
+import com.sap.sailing.domain.tracking.Maneuver;
11
+import com.sap.sailing.domain.tracking.TrackedRace;
12
+
13
+/**
14
+ * Stores a {@link TrackedRace}'s {@link Maneuver}s after they were loaded successfully from the persistent store.
15
+ * This happens when a race was considered equal regarding its "fingerprint" to a version loaded previously with
16
+ * all maneuvers computed and stored persistently. This saves the computational effort to compute the maneuvers
17
+ * again (persistent caching).<p>
18
+ *
19
+ * This class collaborates with {@link ManeuverCacheDelegate}.
20
+ */
21
+public class ManeuversFromDatabase implements SerializableManeuverCache {
22
+ private static final long serialVersionUID = 1872340928634087L;
23
+ private static final Logger logger = Logger.getLogger(ManeuversFromDatabase.class.getName());
24
+ private final Map<Competitor, List<Maneuver>> maneuvers;
25
+
26
+ public ManeuversFromDatabase(Map<Competitor, List<Maneuver>> maneuvers) {
27
+ super();
28
+ this.maneuvers = maneuvers;
29
+ }
30
+
31
+ public void resume() {
32
+ logger.log(Level.WARNING, "Method should never be called");
33
+ // TODO bug5959: another case where we should revert to a SmartFutureCache?
34
+ }
35
+
36
+ public void suspend() {
37
+ // nothing to suspend here
38
+ }
39
+
40
+ public List<Maneuver> get(Competitor competitor, boolean waitForLatest) {
41
+ return maneuvers.get(competitor);
42
+ }
43
+
44
+ @Override
45
+ public void triggerUpdate(Competitor key) {
46
+ logger.log(Level.WARNING, "If Fingerprint matches, no Update should be triggered");
47
+ // TODO change to smartFutureCache in Delegate
48
+ }
49
+}
... ...
\ No newline at end of file
java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverhash/impl/ManeuversFromSmartFutureCache.java
... ...
@@ -0,0 +1,67 @@
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.impl.DynamicTrackedRaceImpl;
13
+import com.sap.sse.common.Duration;
14
+import com.sap.sse.util.SmartFutureCache;
15
+import com.sap.sse.util.SmartFutureCache.AbstractCacheUpdater;
16
+import com.sap.sse.util.SmartFutureCache.EmptyUpdateInterval;
17
+
18
+public class ManeuversFromSmartFutureCache implements ManeuverCache {
19
+ private final SmartFutureCache<Competitor, List<Maneuver>, EmptyUpdateInterval> smartFutureCache;
20
+
21
+ public ManeuversFromSmartFutureCache(DynamicTrackedRaceImpl race) {
22
+ this.smartFutureCache = new SmartFutureCache<Competitor, List<Maneuver>, EmptyUpdateInterval>(
23
+ new AbstractCacheUpdater<Competitor, List<Maneuver>, EmptyUpdateInterval>() {
24
+ @Override
25
+ public List<Maneuver> computeCacheUpdate(Competitor competitor, EmptyUpdateInterval updateInterval)
26
+ throws NoWindException {
27
+ return race.getTrackedRegatta().callWithCPUMeterWithException(()->{
28
+ Duration averageIntervalBetweenRawFixes = race.getTrack(competitor).getAverageIntervalBetweenRawFixes();
29
+ if (averageIntervalBetweenRawFixes != null) {
30
+ ManeuverDetector maneuverDetector;
31
+ // 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
32
+ // if (averageIntervalBetweenRawFixes.asSeconds() >= 30) {
33
+ // maneuverDetector = new LowGPSSamplingRateManeuverDetectorImpl(TrackedRaceImpl.this, competitor);
34
+ // } else {
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
+ },//.computeCacheUpdate(competitor, null),
45
+ /* nameForLocks */ "Maneuver cache for race " + race.getRace().getName());
46
+ }
47
+
48
+ @Override
49
+ public void resume() {
50
+ smartFutureCache.resume();
51
+ }
52
+
53
+ @Override
54
+ public List<Maneuver> get(Competitor key, boolean waitForLatest) {
55
+ return smartFutureCache.get(key, waitForLatest);
56
+ }
57
+
58
+ @Override
59
+ public void suspend() {
60
+ smartFutureCache.suspend();
61
+ }
62
+
63
+ @Override
64
+ public void triggerUpdate(Competitor key) {
65
+ smartFutureCache.triggerUpdate(key, /* updateInterval */ null);
66
+ }
67
+}
java/com.sap.sailing.domain/src/com/sap/sailing/domain/markpassingcalculation/MarkPassingCalculator.java
... ...
@@ -461,8 +461,7 @@ public class MarkPassingCalculator {
461 461
fixesForCompetitor.addAll(competitorEntry.getValue());
462 462
}
463 463
if (!newMarkFixes.isEmpty()) {
464
- // FIXME bug 2745 use new mark fixes to invalidate chooser's mark position and mutual mark/waypoint
465
- // distance cache
464
+ // FIXME bug 2745 use new mark fixes to invalidate chooser's mark position and mutual mark/waypoint distance cache
466 465
for (Entry<Competitor, List<GPSFixMoving>> fixesAffectedByNewMarkFixes : finder
467 466
.calculateFixesAffectedByNewMarkFixes(newMarkFixes).entrySet()) {
468 467
Collection<GPSFixMoving> fixes = combinedCompetitorFixesFinderConsidersAffected
... ...
@@ -614,7 +613,7 @@ public class MarkPassingCalculator {
614 613
try {
615 614
latchForRunningListenRun.await();
616 615
final Map<Competitor, Map<Waypoint, MarkPassing>> markPassings = race.getMarkPassings(/* waitForLatestUpdates */ true);
617
- // Bei Live-Rennen Speicherung unnötig
616
+ // TODO bug6182: do we need to store when we can assume that the race is still live? How to find out reliably?
618 617
markPassingRaceFingerprintRegistry.storeMarkPassings(race.getRaceIdentifier(),
619 618
MarkPassingRaceFingerprintFactory.INSTANCE.createFingerprint(race),
620 619
markPassings, race.getRace().getCourse());
java/com.sap.sailing.domain/src/com/sap/sailing/domain/markpassinghash/MarkPassingRaceFingerprint.java
... ...
@@ -5,24 +5,28 @@ import org.json.simple.JSONObject;
5 5
import com.sap.sailing.domain.base.Course;
6 6
import com.sap.sailing.domain.markpassingcalculation.MarkPassingCalculator;
7 7
import com.sap.sailing.domain.tracking.MarkPassing;
8
+import com.sap.sailing.domain.tracking.RaceFingerprint;
8 9
import com.sap.sailing.domain.tracking.TrackedRace;
9 10
10 11
/**
11 12
* An instance of this class represents a composite fingerprint of those components of a {@link TrackedRace} that are
12
- * relevant for computing the
13
+ * relevant for computing
13 14
* {@link TrackedRace#getMarkPassing(com.sap.sailing.domain.base.Competitor, com.sap.sailing.domain.base.Waypoint) mark
14
- * passings} in the {@link MarkPassingCalculator}. It can be {@link #matches(TrackedRace) matched} against a {@link TrackedRace}
15
- * instance to see whether the {@link TrackedRace} will produce a set of {@link MarkPassing}s equal to that of the {@link TrackedRace}
16
- * from which this fingerprint was produced.<p>
15
+ * passings} in the {@link MarkPassingCalculator}. It can be {@link #matches(TrackedRace) matched} against a
16
+ * {@link TrackedRace} instance to see whether the {@link TrackedRace} will produce a set of {@link MarkPassing}s equal
17
+ * to that of the {@link TrackedRace} from which this fingerprint was produced.
18
+ * <p>
17 19
*
18
- * To produce a fingerprint from a {@link TrackedRace} or from a JSON representation use {@link MarkPassingRaceFingerprintFactory}.<p>
20
+ * To produce a fingerprint from a {@link TrackedRace} or from a JSON representation use
21
+ * {@link MarkPassingRaceFingerprintFactory}.
22
+ * <p>
19 23
*
20 24
* The {@link #equals(Object)} and {@link #hashCode()} methods are defined based on the contents of this fingerprint.
21 25
*
22 26
* @author Fabian Kallenbach (i550803)
23 27
* @author Axel Uhl (d043530)
24 28
*/
25
-public interface MarkPassingRaceFingerprint {
29
+public interface MarkPassingRaceFingerprint extends RaceFingerprint {
26 30
/**
27 31
* Returns a {@link JSONObject} of the hash values.
28 32
*/
java/com.sap.sailing.domain/src/com/sap/sailing/domain/markpassinghash/MarkPassingRaceFingerprintFactory.java
... ...
@@ -1,26 +1,13 @@
1 1
package com.sap.sailing.domain.markpassinghash;
2 2
3
-import org.json.simple.JSONObject;
4
-
5 3
import com.sap.sailing.domain.markpassinghash.impl.MarkPassingRaceFingerprintFactoryImpl;
6
-import com.sap.sailing.domain.tracking.TrackedRace;
4
+import com.sap.sailing.domain.tracking.RaceFingerprintFactory;
7 5
8 6
/**
9 7
* Factory for the creation of a {@link MarkPassingRaceFingerprint}.
10 8
*
11 9
* @author Fabian Kallenbach (i550803)
12 10
*/
13
-public interface MarkPassingRaceFingerprintFactory {
11
+public interface MarkPassingRaceFingerprintFactory extends RaceFingerprintFactory<MarkPassingRaceFingerprint> {
14 12
MarkPassingRaceFingerprintFactory INSTANCE = new MarkPassingRaceFingerprintFactoryImpl();
15
-
16
- /**
17
- * Creates a {@link MarkPassingRaceFingerprint} out of a given {@link TrackedRace}.
18
- */
19
- MarkPassingRaceFingerprint createFingerprint(TrackedRace trackedRace);
20
-
21
- /**
22
- * Creates a {@link MarkPassingRaceFingerprint} out of a given {@link JSONObject}, as produced by
23
- * {@link MarkPassingRaceFingerprint#toJson()}.
24
- */
25
- MarkPassingRaceFingerprint fromJson(JSONObject json);
26 13
}
... ...
\ No newline at end of file
java/com.sap.sailing.domain/src/com/sap/sailing/domain/racelog/RaceLogAndTrackedRaceResolver.java
... ...
@@ -14,24 +14,30 @@ import com.sap.sailing.domain.tracking.TrackedRace;
14 14
import com.sap.sse.common.Util.Triple;
15 15
16 16
/**
17
- * In addition to being able to resolve a race log from a {@link SimpleRaceLogIdentifier}, this
18
- * specialization can additionally look for a {@link TrackedRace} linked to the "slot" identified
19
- * by a {@link SimpleRaceLogIdentifier}.
17
+ * In addition to being able to resolve a race log from a {@link SimpleRaceLogIdentifier}, this specialization can
18
+ * additionally look for a {@link TrackedRace} linked to the "slot" identified by a {@link SimpleRaceLogIdentifier}.
20 19
*
21 20
* @author Axel Uhl (D043530)
22 21
*
23 22
*/
24 23
public interface RaceLogAndTrackedRaceResolver extends RaceLogResolver {
25 24
/**
26
- * The identifier is assumed to reference a {@link RaceColumn} in a {@link IsRegattaLike} object,
27
- * plus a {@link Fleet} object that can be used as an index into the {@link RaceColumn} object.
28
- * With this, both, the {@link RaceLog} as well as a {@link TrackedRace} can be looked up.
25
+ * The identifier is assumed to reference a {@link RaceColumn} in a {@link IsRegattaLike} object, plus a
26
+ * {@link Fleet} object that can be used as an index into the {@link RaceColumn} object. With this, both, the
27
+ * {@link RaceLog} as well as a {@link TrackedRace} can be looked up.
29 28
*/
30 29
TrackedRace resolveTrackedRace(SimpleRaceLogIdentifier identifier);
31
-
32
- // could be implemtet as dafault
33 30
34
- List<Triple<Leaderboard, RaceColumn, Fleet>> getColumnsWithRaceLogForTrackedRace(
35
- RegattaAndRaceIdentifier trackedRaceIdentifier);
31
+ /**
32
+ * Determines those {@link RaceColumn}/{@link Fleet} combinations ("slots") from all {@link Leaderboard}s managed by
33
+ * this resolver that the tracked race identified by {@code trackedRaceIdentifier} shall be linked to when loaded.
34
+ * This information is relevant, e.g., after having created a {@link TrackedRace} that previously was attached to
35
+ * one or more such "slots" and shall now be re-connected to those same slots again. It is also helpful, e.g., when
36
+ * trying to figure out which race logs will be
37
+ * {@link TrackedRace#attachRegattaLog(com.sap.sailing.domain.abstractlog.regatta.RegattaLog) attached} to that
38
+ * {@link TrackedRace} because usually each "slot" comes with its own {@link RaceLog}, so that attaching to multiple
39
+ * slots will result in multiple race logs being attached to the tracked race.
40
+ */
41
+ List<Triple<Leaderboard, RaceColumn, Fleet>> getColumnsWithRaceLogForTrackedRace(RegattaAndRaceIdentifier trackedRaceIdentifier);
36 42
37 43
}
java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/DynamicTrackedRace.java
... ...
@@ -131,8 +131,6 @@ public interface DynamicTrackedRace extends TrackedRace {
131 131
* for the finish line that are affected will be {@link #updateMarkPassings(Competitor, Iterable) updated}.
132 132
*/
133 133
void updateMarkPassingsAfterRaceLogChanges();
134
-
135
- void updateManeuvers(Competitor competitor, Iterable<Maneuver> maneuvers);
136 134
137 135
/**
138 136
* Sets the start time as received from the tracking infrastructure. This isn't necessarily
java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/ManeuverCurveBoundaries.java
... ...
@@ -1,5 +1,7 @@
1 1
package com.sap.sailing.domain.tracking;
2 2
3
+import java.io.Serializable;
4
+
3 5
import com.sap.sailing.domain.common.SpeedWithBearing;
4 6
import com.sap.sse.common.Bearing;
5 7
import com.sap.sse.common.Duration;
... ...
@@ -15,7 +17,7 @@ import com.sap.sse.common.impl.DegreeBearingImpl;
15 17
* @author Vladislav Chumak (D069712)
16 18
*
17 19
*/
18
-public interface ManeuverCurveBoundaries {
20
+public interface ManeuverCurveBoundaries extends Serializable {
19 21
20 22
/**
21 23
* Gets the computed time point of curve start.
java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/RaceFingerprint.java
... ...
@@ -0,0 +1,47 @@
1
+package com.sap.sailing.domain.tracking;
2
+
3
+import org.json.simple.JSONObject;
4
+
5
+import com.sap.sailing.domain.base.Course;
6
+import com.sap.sailing.domain.markpassingcalculation.MarkPassingCalculator;
7
+import com.sap.sailing.domain.markpassinghash.MarkPassingRaceFingerprintFactory;
8
+
9
+/**
10
+ * An instance of this class represents a composite fingerprint of those components of a {@link TrackedRace} that are
11
+ * relevant for computing some metric or value that causes significant computational effort and hence lends itself well
12
+ * for persistent caching, such as mark passings or maneuvers. It can be {@link #matches(TrackedRace) matched} against a
13
+ * {@link TrackedRace} instance to see whether the {@link TrackedRace} will produce a metric or value equal to that of
14
+ * the {@link TrackedRace} from which this fingerprint was produced.
15
+ * <p>
16
+ *
17
+ * To produce a fingerprint from a {@link TrackedRace} or from a JSON representation use a
18
+ * {@link RaceFingerprintFactory}.
19
+ * <p>
20
+ *
21
+ * The {@link #equals(Object)} and {@link #hashCode()} methods are defined based on the contents of this fingerprint.
22
+ *
23
+ * @author Fabian Kallenbach (i550803)
24
+ * @author Axel Uhl (d043530)
25
+ */
26
+public interface RaceFingerprint {
27
+ /**
28
+ * Returns a {@link JSONObject} of the hash values.
29
+ */
30
+ JSONObject toJson();
31
+
32
+ /**
33
+ * Incrementally computes the composite fingerprint of the {@code trackedRace} and compares to this fingerprint
34
+ * component by component. The fingerprint components are computed in ascending order of computational complexity,
35
+ * trying to fail early / fast.<p>
36
+ *
37
+ * The implementation may require to obtain the race's {@link Course#lockForRead() read lock}. Note that conversely
38
+ * updates to the course that happen under the course's write lock will trigger listeners which may synchronize
39
+ * on certain objects, such as the {@link MarkPassingCalculator}. Therefore, should this method be called
40
+ * while holding an object monitor ("synchronized") that a course update listener may also require, make
41
+ * sure to first obtain at least the course read lock before invoking this method. See also bug 5803.
42
+ *
43
+ * @return {@code true} if the {@code trackedRace} produces a fingerprint equal to this one if passed to
44
+ * {@link MarkPassingRaceFingerprintFactory#createFingerprint(TrackedRace)}
45
+ */
46
+ boolean matches(TrackedRace trackedRace);
47
+}
... ...
\ No newline at end of file
java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/RaceFingerprintFactory.java
... ...
@@ -0,0 +1,23 @@
1
+package com.sap.sailing.domain.tracking;
2
+
3
+import org.json.simple.JSONObject;
4
+
5
+import com.sap.sailing.domain.markpassinghash.MarkPassingRaceFingerprint;
6
+
7
+/**
8
+ * Factory for the creation of a {@link MarkPassingRaceFingerprint}.
9
+ *
10
+ * @author Fabian Kallenbach (i550803)
11
+ */
12
+public interface RaceFingerprintFactory<RFP extends RaceFingerprint> {
13
+ /**
14
+ * Creates a {@link RaceFingerprint} out of a given {@link TrackedRace}.
15
+ */
16
+ RFP createFingerprint(TrackedRace trackedRace);
17
+
18
+ /**
19
+ * Creates a {@link RaceFingerprint} out of a given {@link JSONObject}, as produced by
20
+ * {@link RaceFingerprint#toJson()}.
21
+ */
22
+ RFP fromJson(JSONObject json);
23
+}
... ...
\ No newline at end of file
java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/RaceTrackingConnectivityParameters.java
... ...
@@ -43,9 +43,11 @@ public interface RaceTrackingConnectivityParameters extends Serializable {
43 43
* tracker.
44 44
*/
45 45
RaceTracker createRaceTracker(TrackedRegattaRegistry trackedRegattaRegistry, WindStore windStore,
46
- RaceLogAndTrackedRaceResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds,
47
- RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) throws Exception;
48
-
46
+ RaceLogAndTrackedRaceResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver,
47
+ long timeoutInMilliseconds, RaceTrackingHandler raceTrackingHandler,
48
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
49
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) throws Exception;
50
+
49 51
/**
50 52
* Starts a {@link RaceTracker}, associating the resulting races with the {@link Regatta} passed as argument instead
51 53
* of using the tracker's domain factory to obtain a default {@link Regatta} object for the tracking parameters.
... ...
@@ -58,9 +60,11 @@ public interface RaceTrackingConnectivityParameters extends Serializable {
58 60
* {@link TrackedRegattaRegistry#removeRace(Regatta, com.sap.sailing.domain.base.RaceDefinition)}.
59 61
*/
60 62
RaceTracker createRaceTracker(Regatta regatta, TrackedRegattaRegistry trackedRegattaRegistry, WindStore windStore,
61
- RaceLogAndTrackedRaceResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds,
62
- RaceTrackingHandler raceTrackingHandler, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) throws Exception;
63
-
63
+ RaceLogAndTrackedRaceResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver,
64
+ long timeoutInMilliseconds, RaceTrackingHandler raceTrackingHandler,
65
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
66
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) throws Exception;
67
+
64 68
/**
65 69
* Deliver an ID object equal to that of the {@link RaceTracker#getID()} delivered by the {@link RaceTracker}
66 70
* that will be created from these parameters by calling {@link #createRaceTracker(TrackedRegattaRegistry)}.
java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/RaceTrackingHandler.java
... ...
@@ -39,7 +39,9 @@ public interface RaceTrackingHandler {
39 39
long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed,
40 40
DynamicRaceDefinitionSet raceDefinitionSetToUpdate, boolean useMarkPassingCalculator,
41 41
RaceLogAndTrackedRaceResolver raceLogResolver, Optional<ThreadLocalTransporter> threadLocalTransporter,
42
- TrackingConnectorInfo trackingConnectorInfo, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry);
42
+ TrackingConnectorInfo trackingConnectorInfo,
43
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
44
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry);
43 45
44 46
DynamicCompetitor getOrCreateCompetitor(CompetitorAndBoatStore competitorAndBoatStore, Serializable competitorId,
45 47
String name, String shortName, Color displayColor, String email, URI flagImageURI, DynamicTeam team,
... ...
@@ -63,10 +65,14 @@ public interface RaceTrackingHandler {
63 65
long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed,
64 66
DynamicRaceDefinitionSet raceDefinitionSetToUpdate, boolean useMarkPassingCalculator,
65 67
RaceLogAndTrackedRaceResolver raceLogResolver, Optional<ThreadLocalTransporter> threadLocalTransporter,
66
- TrackingConnectorInfo trackingConnectorInfo, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) {
67
- return trackedRegatta.createTrackedRace(raceDefinition, sidelines, windStore, delayToLiveInMillis,
68
+ TrackingConnectorInfo trackingConnectorInfo,
69
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
70
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) {
71
+ return trackedRegatta.createTrackedRace(raceDefinition, sidelines,
72
+ windStore, delayToLiveInMillis,
68 73
millisecondsOverWhichToAverageWind, millisecondsOverWhichToAverageSpeed, raceDefinitionSetToUpdate,
69
- useMarkPassingCalculator, raceLogResolver, threadLocalTransporter, trackingConnectorInfo, markPassingRaceFingerprintRegistry, maneuverRaceFingerprintRegistry);
74
+ useMarkPassingCalculator, raceLogResolver, threadLocalTransporter, trackingConnectorInfo,
75
+ markPassingRaceFingerprintRegistry, maneuverRaceFingerprintRegistry);
70 76
}
71 77
72 78
@Override
java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceImpl.java
... ...
@@ -58,7 +58,6 @@ import com.sap.sailing.domain.tracking.DynamicTrackedRace;
58 58
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
59 59
import com.sap.sailing.domain.tracking.GPSFixTrack;
60 60
import com.sap.sailing.domain.tracking.GPSTrackListener;
61
-import com.sap.sailing.domain.tracking.Maneuver;
62 61
import com.sap.sailing.domain.tracking.MarkPassing;
63 62
import com.sap.sailing.domain.tracking.RaceAbortedListener;
64 63
import com.sap.sailing.domain.tracking.RaceChangeListener;
... ...
@@ -938,123 +937,6 @@ DynamicTrackedRace, GPSTrackListener<Competitor, GPSFixMoving> {
938 937
}
939 938
}
940 939
941
-
942
- @Override
943
- public void updateManeuvers(Competitor competitor, Iterable<Maneuver> maneuvers) {
944
- final CompetitorResult resultFromRaceLog = competitorResultsFromRaceLog.get(competitor);
945
- updateManeuversConsideringFinishingTimesFromRaceLog(competitor, maneuvers, resultFromRaceLog);
946
- }
947
-
948
-
949
-
950
-
951
-
952
-
953
- private void updateManeuversConsideringFinishingTimesFromRaceLog(Competitor competitor,
954
- Iterable<Maneuver> maneuvers, CompetitorResult resultFromRaceLog) {
955
- LockUtil.lockForRead(getSerializationLock()); // keep serializer from reading the mark passings collections
956
- try {
957
-// List<Maneuver> oldManeuvers = new ArrayList<Maneuver>();
958
-// TimePoint finishTime = resultFromRaceLog.getFinishingTime();
959
-// MarkPassing oldStartMarkPassing = null;
960
-// boolean requiresStartTimeUpdate = true;
961
-// final Iterable<Maneuver> maneuversForCompetitor = getManeuvers(competitor, false);
962
-// lockForRead(maneuversForCompetitor);
963
-// try {
964
-// for (Maneuver oldMarkPassing : maneuversForCompetitor) {
965
-// if (oldStartMarkPassing == null) {
966
-// oldStartMarkPassing = oldMarkPassing;
967
-// }
968
-// oldMarkPassings.put(oldMarkPassing.getWaypoint(), oldMarkPassing);
969
-// }
970
-// } finally {
971
-// unlockAfterRead(maneuversForCompetitor);
972
-// }
973
-// final NamedReentrantReadWriteLock markPassingsLock = getMarkPassingsLock(maneuversForCompetitor);
974
-// TimePoint timePointOfLatestEvent = new MillisecondsTimePoint(0);
975
-// // Make sure that clearMarkPassings and the re-adding of the mark passings are non-interruptible by readers.
976
-// // Note that the write lock for the mark passings in order per waypoint is obtained inside
977
-// // clearMarkPassings(...) as well as inside the subsequent for-loop. It is important to always first obtain the mark passings lock
978
-// // for the competitor mark passings before obtaining the lock for the mark passings in order for the waypoint to avoid
979
-// // deadlocks.
980
-// getRace().getCourse().lockForRead();
981
-// LockUtil.lockForWrite(markPassingsLock);
982
-// try {
983
-// clearMarkPassings(competitor);
984
-// for (MarkPassing markPassing : markPassings) {
985
-// // Now since this caller of this update may not have held the course lock, mark passings
986
-// // may already be obsolete and for waypoints that no longer exist. Check:
987
-// if (getRace().getCourse().getIndexOfWaypoint(markPassing.getWaypoint()) >= 0) {
988
-// // try to find corresponding old start mark passing
989
-// if (oldStartMarkPassing != null
990
-// && markPassing.getWaypoint().equals(oldStartMarkPassing.getWaypoint())) {
991
-// if (markPassing.getTimePoint() != null && oldStartMarkPassing.getTimePoint() != null
992
-// && markPassing.getTimePoint().equals(oldStartMarkPassing.getTimePoint())) {
993
-// requiresStartTimeUpdate = false;
994
-// }
995
-// }
996
-// if (!Util.contains(getRace().getCourse().getWaypoints(), markPassing.getWaypoint())) {
997
-// StringBuilder courseWaypointsWithID = new StringBuilder();
998
-// boolean first = true;
999
-// for (Waypoint courseWaypoint : getRace().getCourse().getWaypoints()) {
1000
-// if (first) {
1001
-// first = false;
1002
-// } else {
1003
-// courseWaypointsWithID.append(" -> ");
1004
-// }
1005
-// courseWaypointsWithID.append(courseWaypoint.toString());
1006
-// courseWaypointsWithID.append(" (ID=");
1007
-// courseWaypointsWithID.append(courseWaypoint.getId());
1008
-// courseWaypointsWithID.append(")");
1009
-// }
1010
-// logger.severe("Received mark passing " + markPassing + " for race " + getRace()
1011
-// + " for waypoint ID" + markPassing.getWaypoint().getId()
1012
-// + " but the waypoint does not exist in course " + courseWaypointsWithID);
1013
-// } else {
1014
-// markPassingsForCompetitor.add(markPassing);
1015
-// }
1016
-// Collection<MarkPassing> markPassingsInOrderForWaypoint = getOrCreateMarkPassingsInOrderAsNavigableSet(markPassing
1017
-// .getWaypoint());
1018
-// final NamedReentrantReadWriteLock markPassingsLock2 = getMarkPassingsLock(markPassingsInOrderForWaypoint);
1019
-// LockUtil.lockForWrite(markPassingsLock2);
1020
-// try {
1021
-// // The mark passings of competitor have been removed by the call to
1022
-// // clearMarkPassings(competitor) above
1023
-// // from both, the collection that holds the mark passings by waypoint and the one that holds the
1024
-// // mark passings per competitor; so we can simply add here:
1025
-// markPassingsInOrderForWaypoint.add(markPassing);
1026
-// } finally {
1027
-// LockUtil.unlockAfterWrite(markPassingsLock2);
1028
-// }
1029
-// if (markPassing.getTimePoint().compareTo(timePointOfLatestEvent) > 0) {
1030
-// timePointOfLatestEvent = markPassing.getTimePoint();
1031
-// }
1032
-// } else {
1033
-// logger.warning("Received mark passing "+markPassing+
1034
-// " for non-existing waypoint "+markPassing.getWaypoint()+
1035
-// " in race "+getRace().getName()+". Ignoring.");
1036
-// }
1037
-// }
1038
-// } finally {
1039
-// LockUtil.unlockAfterWrite(maneuversLock);
1040
-// getRace().getCourse().unlockAfterRead();
1041
-// }
1042
-// updated(timePointOfLatestEvent);
1043
-// triggerManeuverCacheRecalculation(competitor);
1044
-// // update the race times like start, end and the leg times
1045
-// if (requiresStartTimeUpdate) {
1046
-// invalidateStartTime();
1047
-// }
1048
-// invalidateMarkPassingTimes();
1049
-// invalidateEndTime();
1050
-// // notify *after* all mark passings have been re-established; should avoid flicker
1051
-// notifyListeners(competitor, oldMarkPassings, markPassings);
1052
- } finally {
1053
- LockUtil.unlockAfterRead(getSerializationLock());
1054
- }
1055
-
1056
- }
1057
-
1058 940
/**
1059 941
* The {@link CompetitorResults} from the race log as cached in {@link #competitorResultsFromRaceLog} may optionally
1060 942
* set a finishing time for competitors. Also, depending on how the race log has been modified (e.g., a new pass
java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRegattaImpl.java
... ...
@@ -1,19 +1,10 @@
1 1
package com.sap.sailing.domain.tracking.impl;
2 2
3
-//import java.util.Optional;
4
-
5 3
import com.sap.sailing.domain.base.RaceDefinition;
6 4
import com.sap.sailing.domain.base.Regatta;
7
-//import com.sap.sailing.domain.base.Sideline;
8
-//import com.sap.sailing.domain.maneuverhash.ManeuverRaceFingerprintRegistry;
9
-//import com.sap.sailing.domain.markpassinghash.MarkPassingRaceFingerprintRegistry;
10
-//import com.sap.sailing.domain.racelog.RaceLogAndTrackedRaceResolver;
11
-//import com.sap.sailing.domain.shared.tracking.TrackingConnectorInfo;
12
-//import com.sap.sailing.domain.tracking.DynamicRaceDefinitionSet;
13 5
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
14 6
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
15 7
16
-
17 8
public class DynamicTrackedRegattaImpl extends TrackedRegattaImpl implements DynamicTrackedRegatta {
18 9
private static final long serialVersionUID = -90155868534737120L;
19 10
... ...
@@ -36,5 +27,4 @@ public class DynamicTrackedRegattaImpl extends TrackedRegattaImpl implements Dyn
36 27
public DynamicTrackedRace getExistingTrackedRace(RaceDefinition race) {
37 28
return (DynamicTrackedRace) super.getExistingTrackedRace(race);
38 29
}
39
-
40 30
}
java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/ManeuverCurveBoundariesImpl.java
... ...
@@ -10,6 +10,7 @@ import com.sap.sse.common.TimePoint;
10 10
*
11 11
*/
12 12
public class ManeuverCurveBoundariesImpl implements ManeuverCurveBoundaries {
13
+ private static final long serialVersionUID = 1097529837L;
13 14
private final TimePoint timePointBefore;
14 15
private final TimePoint timePointAfter;
15 16
private final SpeedWithBearing speedWithBearingBefore;
java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java
... ...
@@ -32,7 +32,6 @@ 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;
36 35
import java.util.concurrent.ExecutionException;
37 36
import java.util.concurrent.Future;
38 37
import java.util.concurrent.FutureTask;
... ...
@@ -136,8 +135,8 @@ import com.sap.sailing.domain.maneuverdetection.IncrementalManeuverDetector;
136 135
import com.sap.sailing.domain.maneuverdetection.ManeuverDetector;
137 136
import com.sap.sailing.domain.maneuverdetection.ShortTimeAfterLastHitCache;
138 137
import com.sap.sailing.domain.maneuverdetection.impl.IncrementalManeuverDetectorImpl;
139
-import com.sap.sailing.domain.maneuverhash.ManeuverCache;
140 138
import com.sap.sailing.domain.maneuverhash.ManeuverRaceFingerprintRegistry;
139
+import com.sap.sailing.domain.maneuverhash.SerializableManeuverCache;
141 140
import com.sap.sailing.domain.maneuverhash.impl.ManeuverCacheDelegate;
142 141
import com.sap.sailing.domain.markpassingcalculation.MarkPassingCalculator;
143 142
import com.sap.sailing.domain.markpassinghash.MarkPassingRaceFingerprintRegistry;
... ...
@@ -147,13 +146,13 @@ import com.sap.sailing.domain.racelog.RaceLogAndTrackedRaceResolver;
147 146
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
148 147
import com.sap.sailing.domain.ranking.RankingMetric;
149 148
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
149
+import com.sap.sailing.domain.ranking.RankingMetricConstructor;
150 150
import com.sap.sailing.domain.shared.tracking.AddResult;
151 151
import com.sap.sailing.domain.shared.tracking.LineDetails;
152 152
import com.sap.sailing.domain.shared.tracking.Track;
153 153
import com.sap.sailing.domain.shared.tracking.TrackingConnectorInfo;
154 154
import com.sap.sailing.domain.shared.tracking.impl.LineDetailsImpl;
155 155
import com.sap.sailing.domain.shared.tracking.impl.TimedComparator;
156
-import com.sap.sailing.domain.ranking.RankingMetricConstructor;
157 156
import com.sap.sailing.domain.tracking.BravoFixTrack;
158 157
import com.sap.sailing.domain.tracking.DynamicSensorFixTrack;
159 158
import com.sap.sailing.domain.tracking.GPSFixTrack;
... ...
@@ -197,7 +196,6 @@ import com.sap.sse.concurrent.NamedReentrantReadWriteLock;
197 196
import com.sap.sse.shared.util.impl.ApproximateTime;
198 197
import com.sap.sse.shared.util.impl.ArrayListNavigableSet;
199 198
import com.sap.sse.util.IdentityWrapper;
200
-import com.sap.sse.util.SmartFutureCache.EmptyUpdateInterval;
201 199
import com.sap.sse.util.impl.FutureTaskWithTracingGet;
202 200
203 201
import difflib.DiffUtils;
... ...
@@ -345,10 +343,8 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
345 343
* computed. Clients wanting to know maneuvers for the competitor outside of this time interval need to (re-)compute
346 344
* them.
347 345
*/
348
- public transient ManeuverCache<Competitor, List<Maneuver>, EmptyUpdateInterval> maneuverCache;
346
+ private final SerializableManeuverCache maneuverCache;
349 347
350
- private transient ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry;
351
-
352 348
/**
353 349
* The values of this map are used by the {@link #approximate(Competitor, Distance, TimePoint, TimePoint)} method and
354 350
* maintain state to accelerate the {@link #approximate(Competitor, Distance, TimePoint, TimePoint)} method, also in
... ...
@@ -387,7 +383,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
387 383
* Whether during {@link #cachesSuspended suspended caches mode} the maneuver re-calculation was triggered; will lead
388 384
* to triggering the maneuver re-calculation when caches are {@link #resumeAllCachesNotUpdatingWhileLoading() resumed}.
389 385
*/
390
- //private boolean triggerManeuverCacheInvalidationForAllCompetitors;
386
+ private boolean triggerManeuverCacheInvalidationForAllCompetitors;
391 387
392 388
/**
393 389
* Keys are the {@link RaceLog#getId() IDs} of the race logs that are stored as values.
... ...
@@ -502,8 +498,9 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
502 498
public TrackedRaceImpl(final TrackedRegatta trackedRegatta, RaceDefinition race, final Iterable<Sideline> sidelines,
503 499
final WindStore windStore, long delayToLiveInMillis, final long millisecondsOverWhichToAverageWind,
504 500
long millisecondsOverWhichToAverageSpeed, long delayForWindEstimationCacheInvalidation,
505
- boolean useInternalMarkPassingAlgorithm, RaceLogAndTrackedRaceResolver raceLogResolver, TrackingConnectorInfo trackingConnectorInfo,
506
- MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) {
501
+ boolean useInternalMarkPassingAlgorithm, RaceLogAndTrackedRaceResolver raceLogResolver,
502
+ TrackingConnectorInfo trackingConnectorInfo, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
503
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) {
507 504
this(trackedRegatta, race, sidelines, windStore, delayToLiveInMillis, millisecondsOverWhichToAverageWind,
508 505
millisecondsOverWhichToAverageSpeed, delayForWindEstimationCacheInvalidation,
509 506
useInternalMarkPassingAlgorithm, OneDesignRankingMetric::new, raceLogResolver, trackingConnectorInfo,
... ...
@@ -527,7 +524,8 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
527 524
long millisecondsOverWhichToAverageSpeed, long delayForWindEstimationCacheInvalidation,
528 525
boolean useInternalMarkPassingAlgorithm, RankingMetricConstructor rankingMetricConstructor,
529 526
RaceLogAndTrackedRaceResolver raceLogResolver, TrackingConnectorInfo trackingConnectorInfo,
530
- MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) {
527
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
528
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) {
531 529
super(race, trackedRegatta, windStore, millisecondsOverWhichToAverageWind);
532 530
distancesFromStarboardSideOfStartLineProjectedOntoLineCache = new ConcurrentHashMap<>();
533 531
distancesFromStarboardSideOfStartLineProjectedOntoLineCacheLastAccessTimes = new ConcurrentHashMap<>();
... ...
@@ -796,7 +794,6 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
796 794
competitorRankingsLocks = createCompetitorRankingsLockMap();
797 795
directionFromStartToNextMarkCache = new ConcurrentHashMap<>();
798 796
maneuverDetectorPerCompetitorCache = createManeuverDetectorCache();
799
- maneuverCache = createManeuverCache(maneuverRaceFingerprintRegistry);
800 797
logger.info("Deserialized race " + getRace().getName());
801 798
}
802 799
... ...
@@ -1081,10 +1078,6 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
1081 1078
*/
1082 1079
private final String updateStartOfRaceCacheFieldsMonitor = ""+new Random().nextDouble();
1083 1080
1084
- private boolean triggerManeuverCacheInvalidationForAllCompetitors;
1085
-
1086
- protected int attachedRaceLogsCount;
1087
-
1088 1081
protected void updateStartOfRaceCacheFields() {
1089 1082
synchronized (updateStartOfRaceCacheFieldsMonitor) {
1090 1083
TimePoint newStartTime = null;
... ...
@@ -2892,7 +2885,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
2892 2885
if (cachesSuspended) {
2893 2886
triggerManeuverCacheInvalidationForAllCompetitors = true;
2894 2887
} else {
2895
- maneuverCache.triggerUpdate(competitor, /* updateInterval */null);
2888
+ maneuverCache.triggerUpdate(competitor);
2896 2889
}
2897 2890
}
2898 2891
... ...
@@ -2921,8 +2914,8 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
2921 2914
*/
2922 2915
@Override
2923 2916
public Iterable<Maneuver> getManeuvers(Competitor competitor, TimePoint from, TimePoint to, boolean waitForLatest) {
2924
- List<Maneuver> allManeuvers = (List<Maneuver>) maneuverCache.get(competitor, waitForLatest);
2925
- List<Maneuver> result;
2917
+ final List<Maneuver> allManeuvers = maneuverCache.get(competitor, waitForLatest);
2918
+ final List<Maneuver> result;
2926 2919
if (allManeuvers == null) {
2927 2920
result = Collections.emptyList();
2928 2921
} else {
... ...
@@ -2933,8 +2926,8 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
2933 2926
2934 2927
@Override
2935 2928
public Iterable<Maneuver> getManeuvers(Competitor competitor, boolean waitForLatest) {
2936
- List<Maneuver> allManeuvers = (List<Maneuver>) maneuverCache.get(competitor, waitForLatest);
2937
- List<Maneuver> result;
2929
+ final List<Maneuver> allManeuvers = maneuverCache.get(competitor, waitForLatest);
2930
+ final List<Maneuver> result;
2938 2931
if (allManeuvers == null) {
2939 2932
result = Collections.emptyList();
2940 2933
} else {
... ...
@@ -3114,36 +3107,33 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
3114 3107
}
3115 3108
3116 3109
public void waitForAllRaceLogsAttached() {
3117
- final CountDownLatch latchForRaceLogs = new CountDownLatch(1); // Alternatives possible
3118
- final Iterable<Triple<Leaderboard, RaceColumn, Fleet>> ecpextedLinks = TrackedRaceImpl.this.getRaceLogResolver()
3119
- .getColumnsWithRaceLogForTrackedRace(getRaceIdentifier()); //Namen
3120
- final int numberOfExpectedRaceLogs = Util.size(ecpextedLinks);
3121
-
3122
- AbstractRaceChangeListener raceLogAttachedListener = new AbstractRaceChangeListener() {
3123
-
3124
- @Override
3125
- public void raceLogAttached(RaceLog raceLog) {
3126
- int numberOfAttachedRaceLogs = Util.size(getAttachedRaceLogs());
3127
- if(numberOfAttachedRaceLogs >=numberOfExpectedRaceLogs) {
3128
- latchForRaceLogs.countDown();
3129
- }
3130
- }
3131
- };
3132
-
3110
+ final Object latchForRaceLogs = new Object();
3111
+ final Iterable<Triple<Leaderboard, RaceColumn, Fleet>> expectedLinks = TrackedRaceImpl.this.getRaceLogResolver()
3112
+ .getColumnsWithRaceLogForTrackedRace(getRaceIdentifier());
3113
+ final int numberOfExpectedRaceLogs = Util.size(expectedLinks);
3114
+ final AbstractRaceChangeListener raceLogAttachedListener = new AbstractRaceChangeListener() {
3115
+ @Override
3116
+ public void raceLogAttached(RaceLog raceLog) {
3117
+ int numberOfAttachedRaceLogs = Util.size(getAttachedRaceLogs());
3118
+ synchronized (latchForRaceLogs) {
3119
+ if (numberOfAttachedRaceLogs >= numberOfExpectedRaceLogs) {
3120
+ latchForRaceLogs.notifyAll();
3121
+ }
3122
+ }
3123
+ }
3124
+ };
3133 3125
this.addListener(raceLogAttachedListener);
3134
-
3135 3126
final int numberOfAttachedRaceLogs = Util.size(getAttachedRaceLogs());
3136
-
3137 3127
try {
3138
- if (numberOfAttachedRaceLogs < numberOfExpectedRaceLogs) {
3139
- latchForRaceLogs.await();
3140
- }
3128
+ synchronized (latchForRaceLogs) {
3129
+ while (numberOfAttachedRaceLogs < numberOfExpectedRaceLogs) {
3130
+ latchForRaceLogs.wait();
3131
+ }
3132
+ }
3141 3133
} catch (InterruptedException e) {
3142
- // TODO Auto-generated catch block
3143
- //Logging hinzufügen
3144
- e.printStackTrace();
3134
+ logger.warning("Interrupted: "+e.getMessage());
3145 3135
} finally {
3146
- removeListener(raceLogAttachedListener);
3136
+ removeListener(raceLogAttachedListener);
3147 3137
}
3148 3138
}
3149 3139
... ...
@@ -3224,7 +3214,6 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
3224 3214
attachedRaceLogs.put(raceLog.getId(), raceLog);
3225 3215
notifyAll();
3226 3216
invalidateStartTime();
3227
-
3228 3217
}
3229 3218
notifyListenersWhenAttachingRaceLog(raceLog);
3230 3219
}
java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRegattaImpl.java
... ...
@@ -324,7 +324,7 @@ public abstract class TrackedRegattaImpl implements TrackedRegatta {
324 324
long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed,
325 325
DynamicRaceDefinitionSet raceDefinitionSetToUpdate, boolean useInternalMarkPassingAlgorithm, RaceLogAndTrackedRaceResolver raceLogResolver,
326 326
Optional<ThreadLocalTransporter> threadLocalTransporter, TrackingConnectorInfo trackingConnectorInfo,
327
- MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry ) {
327
+ MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry ) {
328 328
logger.log(Level.INFO, "Creating DynamicTrackedRaceImpl for RaceDefinition " + raceDefinition.getName());
329 329
DynamicTrackedRaceImpl result = new DynamicTrackedRaceImpl(this, raceDefinition, sidelines, windStore,
330 330
delayToLiveInMillis, millisecondsOverWhichToAverageWind,
java/com.sap.sailing.gwt.ui/.settings/com.gwtplugins.gwt.eclipse.core.prefs
... ...
@@ -1,9 +1,7 @@
1 1
//gwtVersion_/com.google.gwt.user/lib=2.11.0
2 2
//gwtVersion_/opt/gwt-2.11.0=2.11.0
3 3
//gwtVersion_/opt/gwt-2.11.1=2.11.1
4
-//gwtVersion_/opt/gwt/gwt-2.11.1=2.11.1
5 4
//gwtVersion_/opt/gwt-2.12.2=2.12.2
6
-//gwtVersion_/opt/gwt/gwt-2.12.2=2.12.2
7 5
//gwtVersion_/usr/local/gwt-2.11.0=2.11.0
8 6
//gwtVersion_/usr/local/gwt-2.12.2=2.12.2
9 7
eclipse.preferences.version=1
java/com.sap.sailing.gwt.ui/GWT Sailing DevMode.launch
... ...
@@ -33,7 +33,6 @@
33 33
</listAttribute>
34 34
<booleanAttribute key="org.eclipse.jdt.debug.ui.CONSIDER_INHERITED_MAIN" value="true"/>
35 35
<booleanAttribute key="org.eclipse.jdt.debug.ui.INCLUDE_EXTERNAL_JARS" value="true"/>
36
- <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
37 36
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
38 37
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8&quot; javaProject=&quot;com.sap.sailing.gwt.ui&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
39 38
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.gwt.ui/src/main/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
java/com.sap.sailing.gwt.ui/GWT Sailing SDM ManagementConsole.launch
... ...
@@ -23,7 +23,6 @@
23 23
</listAttribute>
24 24
<booleanAttribute key="org.eclipse.jdt.debug.ui.CONSIDER_INHERITED_MAIN" value="true"/>
25 25
<booleanAttribute key="org.eclipse.jdt.debug.ui.INCLUDE_EXTERNAL_JARS" value="true"/>
26
- <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
27 26
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
28 27
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8&quot; javaProject=&quot;com.sap.sailing.gwt.ui&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
29 28
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.gwt.ui/src/main/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
java/com.sap.sailing.gwt.ui/GWT Sailing SDM.launch
... ...
@@ -39,7 +39,6 @@
39 39
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
40 40
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_SHOW_CODEDETAILS_IN_EXCEPTION_MESSAGES" value="true"/>
41 41
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
42
- <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
43 42
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
44 43
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8&quot; javaProject=&quot;com.sap.sailing.gwt.ui&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
45 44
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.gwt.ui/src/main/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/ManeuverRaceFingerprintConversionTest.java
... ...
@@ -61,23 +61,21 @@ public class ManeuverRaceFingerprintConversionTest extends OnlineTracTracBasedTe
61 61
62 62
@Test
63 63
public void testStoringToAndLoadingFromMongo() throws UnknownHostException, MongoException {
64
- ManeuverRaceFingerprintFactory factory = ManeuverRaceFingerprintFactory.INSTANCE;
65
- ManeuverRaceFingerprint fingerprint = factory.createFingerprint(trackedRace1);
64
+ final ManeuverRaceFingerprintFactory factory = ManeuverRaceFingerprintFactory.INSTANCE;
65
+ final ManeuverRaceFingerprint fingerprint = factory.createFingerprint(trackedRace1);
66 66
assertTrue(fingerprint.matches(trackedRace1));
67
- MongoClient myFirstMongo = newMongo();
68
- MongoDatabase firstDatabase = myFirstMongo.getDatabase(dbConfiguration.getDatabaseName());
69
- RaceIdentifier raceIdentifier = trackedRace1.getRaceIdentifier();
70
- //List<Competitor> competetors = trackedRace1.getCompetitor(null);
67
+ final MongoClient myFirstMongo = newMongo();
68
+ final MongoDatabase firstDatabase = myFirstMongo.getDatabase(dbConfiguration.getDatabaseName());
69
+ final RaceIdentifier raceIdentifier = trackedRace1.getRaceIdentifier();
71 70
final Map<Competitor, List<Maneuver>> maneuvers = new HashMap<>();
72
- for (Competitor competitor : getRace().getCompetitors()) {
73
- List<Maneuver> maneuversForCompetitor = (List<Maneuver>) trackedRace1.getManeuvers(competitor, true);
71
+ for (final Competitor competitor : getRace().getCompetitors()) {
72
+ final List<Maneuver> maneuversForCompetitor = (List<Maneuver>) trackedRace1.getManeuvers(competitor, true);
74 73
maneuvers.put(competitor,maneuversForCompetitor);
75 74
}
76
- //final Map<Competitor, List<Maneuver>> maneuvers = trackedRace1.getManeuvers(null, false);
77 75
new MongoObjectFactoryImpl(firstDatabase).storeManeuvers(raceIdentifier, fingerprint, trackedRace1.getRace().getCourse(), maneuvers);
78
- DomainObjectFactory dF = PersistenceFactory.INSTANCE.getDomainObjectFactory(dbConfiguration.getService(), getDomainFactory().getBaseDomainFactory());
79
- Map<RaceIdentifier, ManeuverRaceFingerprint> fingerprintHashMap = dF.loadFingerprintsForManeuverHashes();
80
- ManeuverRaceFingerprint fingerprintAfterDB = fingerprintHashMap.get(trackedRace1.getRaceIdentifier());
76
+ final DomainObjectFactory dF = PersistenceFactory.INSTANCE.getDomainObjectFactory(dbConfiguration.getService(), getDomainFactory().getBaseDomainFactory());
77
+ final Map<RaceIdentifier, ManeuverRaceFingerprint> fingerprintHashMap = dF.loadFingerprintsForManeuverHashes();
78
+ final ManeuverRaceFingerprint fingerprintAfterDB = fingerprintHashMap.get(trackedRace1.getRaceIdentifier());
81 79
assertTrue(fingerprintAfterDB.matches(trackedRace1), "Original and de-serialized copy are equal");
82 80
final Map<Competitor, List<Maneuver>> maneuversLoaded = dF.loadManeuvers(trackedRace1, trackedRace1.getRace().getCourse());
83 81
assertEquals(maneuvers, maneuversLoaded);
java/com.sap.sailing.polars.datamining.shared/.settings/com.gwtplugins.gwt.eclipse.core.prefs
... ...
@@ -1,8 +1,6 @@
1 1
//gwtVersion_/opt/gwt-2.11.0=2.11.0
2 2
//gwtVersion_/opt/gwt-2.11.1=2.11.1
3
-//gwtVersion_/opt/gwt/gwt-2.11.1=2.11.1
4 3
//gwtVersion_/opt/gwt-2.12.2=2.12.2
5
-//gwtVersion_/opt/gwt/gwt-2.12.2=2.12.2
6 4
//gwtVersion_/usr/local/gwt-2.11.0=2.11.0
7 5
//gwtVersion_/usr/local/gwt-2.12.2=2.12.2
8 6
eclipse.preferences.version=1
java/com.sap.sailing.server.interface/src/com/sap/sailing/server/interfaces/RacingEventService.java
... ...
@@ -157,7 +157,8 @@ import com.sap.sse.shared.media.VideoDescriptor;
157 157
* @author Axel Uhl (d043530)
158 158
*
159 159
*/
160
-public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetcher, RegattaRegistry, MarkPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry,
160
+public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetcher, RegattaRegistry,
161
+ MarkPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry,
161 162
RaceFetcher, LeaderboardRegistry, EventResolver, LeaderboardGroupResolver, TrackerManager,
162 163
Searchable<LeaderboardSearchResult, KeywordQueryWithOptionalEventQualification>,
163 164
ReplicableWithObjectInputStream<RacingEventService, RacingEventServiceOperation<?>>, RaceLogAndTrackedRaceResolver,
java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RacingEventServiceImpl.java
... ...
@@ -474,7 +474,7 @@ Replicator {
474 474
private final ConcurrentHashMap<UUID, LeaderboardGroup> leaderboardGroupsByID;
475 475
476 476
private final ConcurrentHashMap<RaceIdentifier, MarkPassingRaceFingerprint> markPassingRaceFingerprints;
477
-
477
+
478 478
private final ConcurrentHashMap<RaceIdentifier, ManeuverRaceFingerprint> maneuverRaceFingerprints;
479 479
480 480
/**
... ...
@@ -1011,7 +1011,7 @@ Replicator {
1011 1011
1012 1012
@Override
1013 1013
public ManeuverRaceFingerprint getManeuverRaceFingerprint(RaceIdentifier raceIdentifier) {
1014
- logger.log(Level.INFO, "Getting Maneuver fingerprint");
1014
+ logger.fine(()->"Getting Maneuver fingerprint for race "+raceIdentifier);
1015 1015
return maneuverRaceFingerprints.get(raceIdentifier);
1016 1016
}
1017 1017
... ...
@@ -2744,8 +2744,6 @@ Replicator {
2744 2744
}
2745 2745
return trackedRaceLink;
2746 2746
}
2747
-
2748
-
2749 2747
2750 2748
@Override
2751 2749
public void stopTracking(Regatta regatta, boolean willBeRemoved) throws MalformedURLException, IOException, InterruptedException {
java/com.sap.sailing.server/src/com/sap/sailing/server/security/PermissionAwareRaceTrackingHandler.java
... ...
@@ -107,13 +107,14 @@ public class PermissionAwareRaceTrackingHandler extends DefaultRaceTrackingHandl
107 107
long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed,
108 108
DynamicRaceDefinitionSet raceDefinitionSetToUpdate, boolean useMarkPassingCalculator,
109 109
RaceLogAndTrackedRaceResolver raceLogResolver, Optional<ThreadLocalTransporter> threadLocalTransporter,
110
- TrackingConnectorInfo trackingConnectorInfo, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry, ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) {
110
+ TrackingConnectorInfo trackingConnectorInfo, MarkPassingRaceFingerprintRegistry markPassingRaceFingerprintRegistry,
111
+ ManeuverRaceFingerprintRegistry maneuverRaceFingerprintRegistry) {
111 112
return setOwnershipForRace(
112 113
new RegattaNameAndRaceName(trackedRegatta.getRegatta().getName(), raceDefinition.getName()),
113 114
() -> super.createTrackedRace(trackedRegatta, raceDefinition, sidelines, windStore, delayToLiveInMillis,
114 115
millisecondsOverWhichToAverageWind, millisecondsOverWhichToAverageSpeed,
115 116
raceDefinitionSetToUpdate, useMarkPassingCalculator, raceLogResolver, threadLocalTransporter,
116
- trackingConnectorInfo, markPassingRaceFingerprintRegistry,maneuverRaceFingerprintRegistry));
117
+ trackingConnectorInfo, markPassingRaceFingerprintRegistry, maneuverRaceFingerprintRegistry));
117 118
}
118 119
119 120
@Override
java/com.sap.sailing.simulator/.settings/com.gwtplugins.gwt.eclipse.core.prefs
... ...
@@ -1,8 +1,6 @@
1 1
//gwtVersion_/opt/gwt-2.11.0=2.11.0
2 2
//gwtVersion_/opt/gwt-2.11.1=2.11.1
3
-//gwtVersion_/opt/gwt/gwt-2.11.1=2.11.1
4 3
//gwtVersion_/opt/gwt-2.12.2=2.12.2
5
-//gwtVersion_/opt/gwt/gwt-2.12.2=2.12.2
6 4
//gwtVersion_/usr/local/gwt-2.11.0=2.11.0
7 5
//gwtVersion_/usr/local/gwt-2.12.2=2.12.2
8 6
eclipse.preferences.version=1
java/com.sap.sse.common/.settings/com.gwtplugins.gwt.eclipse.core.prefs
... ...
@@ -1,8 +1,6 @@
1 1
//gwtVersion_/opt/gwt-2.11.0=2.11.0
2 2
//gwtVersion_/opt/gwt-2.11.1=2.11.1
3
-//gwtVersion_/opt/gwt/gwt-2.11.1=2.11.1
4 3
//gwtVersion_/opt/gwt-2.12.2=2.12.2
5
-//gwtVersion_/opt/gwt/gwt-2.12.2=2.12.2
6 4
//gwtVersion_/usr/local/gwt-2.11.0=2.11.0
7 5
//gwtVersion_/usr/local/gwt-2.12.2=2.12.2
8 6
eclipse.preferences.version=1
java/com.sap.sse.gwt.adminconsole/.settings/com.gwtplugins.gwt.eclipse.core.prefs
... ...
@@ -1,9 +1,7 @@
1 1
//gwtVersion_/com.google.gwt.user/lib=
2 2
//gwtVersion_/opt/gwt-2.11.0=2.11.0
3 3
//gwtVersion_/opt/gwt-2.11.1=2.11.1
4
-//gwtVersion_/opt/gwt/gwt-2.11.1=2.11.1
5 4
//gwtVersion_/opt/gwt-2.12.2=2.12.2
6
-//gwtVersion_/opt/gwt/gwt-2.12.2=2.12.2
7 5
//gwtVersion_/usr/local/gwt-2.11.0=2.11.0
8 6
//gwtVersion_/usr/local/gwt-2.12.2=2.12.2
9 7
eclipse.preferences.version=1
java/com.sap.sse.gwt.test/.settings/com.gwtplugins.gwt.eclipse.core.prefs
... ...
@@ -1,7 +1,6 @@
1 1
//gwtVersion_/com.google.gwt.user/lib=2.11.1
2 2
//gwtVersion_/opt/gwt-2.11.0=2.11.0
3 3
//gwtVersion_/opt/gwt-2.11.1=2.11.1
4
-//gwtVersion_/opt/gwt/gwt-2.11.1=2.11.1
5 4
//gwtVersion_/opt/gwt-2.12.2=2.12.2
6 5
//gwtVersion_/usr/local/gwt-2.11.0=2.11.0
7 6
//gwtVersion_/usr/local/gwt-2.12.2=2.12.2
java/com.sap.sse.gwt/.settings/com.gwtplugins.gwt.eclipse.core.prefs
... ...
@@ -1,7 +1,6 @@
1 1
//gwtVersion_/com.google.gwt.user/lib=2.11.1
2 2
//gwtVersion_/opt/gwt-2.11.0=2.11.0
3 3
//gwtVersion_/opt/gwt-2.11.1=2.11.1
4
-//gwtVersion_/opt/gwt/gwt-2.11.1=2.11.1
5 4
//gwtVersion_/opt/gwt-2.12.2=2.12.2
6 5
//gwtVersion_/usr/local/gwt-2.11.0=2.11.0
7 6
//gwtVersion_/usr/local/gwt-2.12.2=2.12.2
java/com.sap.sse.gwt/GWT xdStorage Sample SDM.launch
... ...
@@ -23,7 +23,6 @@
23 23
<booleanAttribute key="org.eclipse.jdt.debug.ui.CONSIDER_INHERITED_MAIN" value="true"/>
24 24
<booleanAttribute key="org.eclipse.jdt.debug.ui.INCLUDE_EXTERNAL_JARS" value="true"/>
25 25
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
26
- <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
27 26
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
28 27
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8&quot; javaProject=&quot;com.sap.sse.gwt&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
29 28
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
java/com.sap.sse.security.common/.settings/com.gwtplugins.gwt.eclipse.core.prefs
... ...
@@ -1,6 +1,5 @@
1 1
//gwtVersion_/opt/gwt-2.11.0=2.11.0
2 2
//gwtVersion_/opt/gwt-2.11.1=2.11.1
3
-//gwtVersion_/opt/gwt/gwt-2.11.1=2.11.1
4 3
//gwtVersion_/opt/gwt-2.12.2=2.12.2
5 4
//gwtVersion_/usr/local/gwt-2.11.0=2.11.0
6 5
//gwtVersion_/usr/local/gwt-2.12.2=2.12.2
java/com.sap.sse.security.ui/.settings/com.gwtplugins.gwt.eclipse.core.prefs
... ...
@@ -1,7 +1,6 @@
1 1
//gwtVersion_/com.google.gwt.user/lib=2.11.1
2 2
//gwtVersion_/opt/gwt-2.11.0=2.11.0
3 3
//gwtVersion_/opt/gwt-2.11.1=2.11.1
4
-//gwtVersion_/opt/gwt/gwt-2.11.1=2.11.1
5 4
//gwtVersion_/opt/gwt-2.12.2=2.12.2
6 5
//gwtVersion_/usr/local/gwt-2.11.0=2.11.0
7 6
//gwtVersion_/usr/local/gwt-2.12.2=2.12.2
java/com.sap.sse.security.ui/GWT Security DevMode.launch
... ...
@@ -25,7 +25,6 @@
25 25
</listAttribute>
26 26
<booleanAttribute key="org.eclipse.jdt.debug.ui.CONSIDER_INHERITED_MAIN" value="true"/>
27 27
<booleanAttribute key="org.eclipse.jdt.debug.ui.INCLUDE_EXTERNAL_JARS" value="true"/>
28
- <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
29 28
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
30 29
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8&quot; javaProject=&quot;com.sap.sailing.gwt.ui&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#10;"/>
31 30
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.gwt.ui/src/main/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
java/com.sap.sse.security.ui/GWT Security SDM.launch
... ...
@@ -28,7 +28,6 @@
28 28
<booleanAttribute key="org.eclipse.jdt.debug.ui.CONSIDER_INHERITED_MAIN" value="true"/>
29 29
<booleanAttribute key="org.eclipse.jdt.debug.ui.INCLUDE_EXTERNAL_JARS" value="true"/>
30 30
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
31
- <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
32 31
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
33 32
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8&quot; javaProject=&quot;com.sap.sailing.gwt.ui&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#10;"/>
34 33
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.gwt.ui/src/main/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
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>> {
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
/**
sailing.png
... ...
Binary files a/sailing.png and /dev/null differ
wiki/howto/glossary.md
... ...
@@ -0,0 +1,33 @@
1
+# Key tools and terms...
2
+A basic rundown of *what's what*, so you can dive into the other documentation more easily.
3
+
4
+## The components of the project
5
+### Tools
6
+- Apache: This is the web server technology that acts as the reverse proxy and serves the content. You can serve multiple sites from the same Apache instance. It is configured using the `httpd.conf` file which can be found for this project in `${GIT_HOME}/configuration/httpd/conf`. Sometimes `.htaccess` files are used in a directory to affect the configuration; however, if you have sufficient permissions, try to place these in the main config file. Apache works by using directives, which are commands to control access, security, sources and redirect traffic, to name but a few. Apache is modular and you can view all the modules compiled using `httpd -l`. The extra modules can be configured in conf.d (subdir of the configuration directory). In that directory, you can find the macros used, including those used for archiving.
7
+- EC2: This is the Amazon Web Service that hosts the instances that the servers run on. We use load balancers to direct traffic, specifically Application Load Balancers, which routes at the HTTP/S level, making them very powerful. You might also want to read up on security groups, target groups and VPCs (virtual private clouds).
8
+- Expedition Connector: A software package that allows us to receive wind sensor data and forward it on for processing.
9
+- GWT: This is the product that handles the front end. It was originally Python, but we switched because it allowed for one language across the codebase, one editor (Eclipse) and dynamic sites. It is very modular and the details of each module are defined in the `.gwt.xml` file. Note: I had some trouble getting this working with Eclipse initially. I used a helpful tutorial called *Modern GWT, first steps*.
10
+- Hudson: This is a continuous integration tool, written in Java, that can execute Maven, Ant, Unix and Windows commands. The general community now uses Jenkins and support has stopped.
11
+- MongoDB: A NoSQL database (so there are no tables) that uses a Document model: within each database, you can have multiple collections and within those are documents... Each document has a `_id` which must be unique. You can access MongoDB from the terminal, using Mongosh, or you can use the GUI Compass. MongoDB scales horizontally by sharding (a bit like partitioning) the documents: this is done using a field or fields to order the documents. We use MongoDB for recovery. Note: As of writing, the pacing of their own tutorials is quite slow and they abstract a lot of detail.
12
+- OSGI: A specification for component and module-based programming in Java. Equinox is an implementation of this specification, that we use. There is a MANIFEST.MF for each independent group of classes, known as a bundle, which details the requirements and any exports. These can be added, removed or updated for an application whilst it is running. We use OSGI web bundles which include a `web.xml` descriptor in the target WEB-INF, which can store the static content and any servlets.
13
+- RabbitMQ: This is a message-passing service. Note: Their tutorials are great and there seems to be good documentation. Pika Python is good for getting familiar with the concepts.
14
+- Selenium: It is a project that includes the tool we use for automated testing.
15
+- Shiro: A Java security framework for permissions, authorization and authentication.
16
+### Companies
17
+- SwissTiming: They provide the timing solution at events but ultimately decided to outsource sailing timings to us and TracTrac. They have backup wind sensors if ours fail.
18
+- TracTrac: The tracking gear used and the client used to interact with the backend. The Domain Factory maps the TracTrac domain to ours. The client runs a thread for receiving the race course definition, the list of competitors, the raw competitor GPS fixes, the mark positions, start/finish times and the mark-rounding times.
19
+
20
+
21
+## Some basic sailing terminology
22
+- A **flight** or **fleet** is a subset of all the competitors. The competitors are broken up into fleets if there are too many or if there are special starting and finishing provisions. On the sapsailing.com leaderboard, the fleets are colour-coded.
23
+- A **jibe** or **gybe** is a manoeuvre whereby the boat points downwind (with the wind) during the turn.
24
+- **kt** is knots.
25
+- A **mark** is any position a boat must pass on a required side.
26
+- A **tack** is a manoeuvre where the boat turns into the headwind (pointing into the wind) and then through.
27
+- **Velocity made good** is speed towards or from the wind direction.
28
+- Races, within a regatta, may be **discarded**. This is completely different to a penalty. If there is a discard, then each team's worst score is removed (if a team has two races with identical scores, the leaderboard will remove the earliest score). This typically only happens if there are 4 or more races. In the SAP Admin Console, in the Leaderboards panel, you can choose how many discards are allowed. We allow up to 15 discards! The Administrator types into the box next to the discard number, how many races are required to trigger the discard. This must increase for each discard.
29
+
30
+
31
+## SuperDevMode vs DevMode (for GWT)
32
+Previously there was a browser called Netscape, they developed a technology called Netscape Plugin Application Programming Interface (NPAPI), which was an API, allowing plugin integration. When the browser couldn't handle content, it utilised plugins. In GWT DevMode, we use this feature and have a plugin that acts as an in-between for the JavaScript and Java. However, all requests first make a call to the Java routine, which then does a roundtrip (usually) to set anything in the page, and finally returns. This is quite slow and the NPAPI stuff has been deprecated. Instead, we use SuperDevMode now. You still have a HTTP server which serves the content initially, is the back-end and connects with the AWS instances; this triggers a request for the nocache.js, to the SuperDev server (typically running on port 9876 with Windows), which transpiles the code into "draft" JavaScript (which is unoptimized), utilising source maps, which enable us to map the JavaScript back to readable Java code (as it is often optimised to the point of confusion). The AJAX response is then used to fill the site.
33
+This new method allows debugging on more platforms and is fast; however, it does make debugging more difficult because it can be unclear where the breakpoints map to.
wiki/howto/onboarding-glossary.md
... ...
@@ -1,32 +0,0 @@
1
-# Key tools and terms...
2
-A basic rundown of *what's what*, so you can dive into the other documentation more easily.
3
-
4
-## The components of the project
5
-### Tools
6
-- Apache: This is the web server technology that acts as the reverse proxy and serves the content. You can serve multiple sites from the same Apache instance. It is configured using the `httpd.conf` file which can be found for this project in `${GIT_HOME}/configuration/httpd/conf`. Sometimes `.htaccess` files are used in a directory to affect the configuration; however, if you have sufficient permissions, try to place these in the main config file. Apache works by using directives, which are commands to control access, security, sources and redirect traffic, to name but a few. Apache is modular and you can view all the modules compiled using `httpd -l`. The extra modules can be configured in conf.d (subdir of the configuration directory). In that directory, you can find the macros used, including those used for archiving.
7
-- EC2: This is the Amazon Web Service that hosts the instances that the servers run on. We use load balancers to direct traffic, specifically Application Load Balancers, which routes at the HTTP/S level, making them very powerful. You might also want to read up on security groups, target groups and VPCs (virtual private clouds).
8
-- Expedition Connector: A software package that allows us to receive wind sensor data and forward it on for processing.
9
-- GWT: This is the product that handles the front end. It was originally Python, but we switched because it allowed for one language across the codebase, one editor (Eclipse) and dynamic sites. It is very modular and the details of each module are defined in the `.gwt.xml` file. Note: I had some trouble getting this working with Eclipse initially. I used a helpful tutorial called *Modern GWT, first steps*.
10
-- Hudson: This is a continuous integration tool, written in Java, that can execute Maven, Ant, Unix and Windows commands. The general community now uses Jenkins and support has stopped.
11
-- MongoDB: A NoSQL database (so there are no tables) that uses a Document model: within each database, you can have multiple collections and within those are documents... Each document has a `_id` which must be unique. You can access MongoDB from the terminal, using Mongosh, or you can use the GUI Compass. MongoDB scales horizontally by sharding (a bit like partitioning) the documents: this is done using a field or fields to order the documents. We use MongoDB for recovery. Note: As of writing, the pacing of their own tutorials is quite slow and they abstract a lot of detail.
12
-- OSGI: A specification for component and module-based programming in Java. Equinox is an implementation of this specification, that we use. There is a MANIFEST.MF for each independent group of classes, known as a bundle, which details the requirements and any exports. These can be added, removed or updated for an application whilst it is running. We use OSGI web bundles which include a `web.xml` descriptor in the target WEB-INF, which can store the static content and any servlets.
13
-- RabbitMQ: This is a message-passing service. Note: Their tutorials are great and there seems to be good documentation. Pika Python is good for getting familiar with the concepts.
14
-- Selenium: It is a project that includes the tool we use for automated testing.
15
-### Companies
16
-- SwissTiming: They provide the timing solution at events but ultimately decided to outsource sailing timings to us and TracTrac. They have backup wind sensors if ours fail.
17
-- TracTrac: The tracking gear used and the client used to interact with the backend. The Domain Factory maps the TracTrac domain to ours. The client runs a thread for receiving the race course definition, the list of competitors, the raw competitor GPS fixes, the mark positions, start/finish times and the mark-rounding times.
18
-
19
-
20
-## Some basic sailing terminology
21
-- A **flight** or **fleet** is a subset of all the competitors. The competitors are broken up into fleets if there are too many or if there are special starting and finishing provisions. On the sapsailing.com leaderboard, the fleets are colour-coded.
22
-- A **jibe** or **gybe** is a manoeuvre whereby the boat points downwind (with the wind) during the turn.
23
-- **kt** is of course knots.
24
-- A **mark** is any position a boat must pass on a required side.
25
-- A **tack** is a manoeuvre where the boat turns into the headwind (pointing into the wind) and then through.
26
-- **Velocity made good** is speed towards or from the wind direction.
27
-- Races, within a regatta, may be **discarded**. This is completely different to a penalty. If there is a discard, then each team's worst score is removed (if a team has two races with identical scores, the leaderboard will remove the earliest score). This typically only happens if there are 4 or more races. In the SAP Admin Console, in the Leaderboards panel, you can choose how many discards are allowed. We allow up to 15 discards! The Administrator types into the box next to the discard number, how many races are required to trigger the discard. This must increase for each discard.
28
-
29
-
30
-## SuperDevMode vs DevMode (for GWT)
31
-Previously there was a browser called Netscape, they developed a technology called Netscape Plugin Application Programming Interface (NPAPI), which was an API, allowing plugin integration. When the browser couldn't handle content, it utilised plugins. In GWT DevMode, we use this feature and have a plugin that acts as an in-between for the JavaScript and Java. However, all requests first make a call to the Java routine, which then does a roundtrip (usually) to set anything in the page, and finally returns. This is quite slow and the NPAPI stuff has been deprecated. Instead, we use SuperDevMode now. You still have a HTTP server which serves the content initially, is the back-end and connects with the AWS instances; this triggers a request for the nocache.js, to the SuperDev server (typically running on port 9876 with Windows), which transpiles the code into "draft" JavaScript (which is unoptimized), utilising source maps, which enable us to map the JavaScript back to readable Java code (as it is often optimised to the point of confusion). The AJAX response is then used to fill the site.
32
-This new method allows debugging on more platforms and is fast; however, it does make debugging more difficult because it can be unclear where the breakpoints map to.
wiki/howto/onboarding.md
... ...
@@ -253,4 +253,4 @@ Mac users can install SDKMAN! to manage and install different JDKs.
253 253
254 254
### Extra Reading
255 255
Check out [refactoring patterns](https://refactoring.guru/) as a sort of cheatsheet for the aforementioned design patterns books.
256
-We also have an [onboarding glossary](https://wiki.sapsailing.com/wiki/howto/onboarding-glossary).
256
+We also have an [onboarding glossary](https://wiki.sapsailing.com/wiki/howto/glossary).