mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-17 11:19:15 +00:00
bug5217: represent waypoints in DB as index into waypoint list of course
This commit is contained in:
+3
-1
@@ -15,6 +15,7 @@ import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.anniversary.DetailedRaceInfo;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CompetitorWithBoat;
|
||||
import com.sap.sailing.domain.base.Course;
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.RaceDefinition;
|
||||
@@ -232,6 +233,7 @@ public interface DomainObjectFactory {
|
||||
/**
|
||||
* For races that have a {@link MarkPassingRaceFingerprint} stored in the database (see {@link #loadFingerprintsForMarkPassingHashes()})
|
||||
* a caller can load the corresponding mark passings with this method.
|
||||
* @param course TODO
|
||||
*/
|
||||
Map<Competitor, Map<Waypoint, MarkPassing>> loadMarkPassings(RaceIdentifier raceIdentifier);
|
||||
Map<Competitor, Map<Waypoint, MarkPassing>> loadMarkPassings(RaceIdentifier raceIdentifier, Course course);
|
||||
}
|
||||
|
||||
+3
-1
@@ -15,6 +15,7 @@ import com.mongodb.client.MongoDatabase;
|
||||
import com.sap.sailing.domain.anniversary.DetailedRaceInfo;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Course;
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
@@ -241,6 +242,7 @@ public interface MongoObjectFactory {
|
||||
* identifies the race to which the mark passings belong
|
||||
* @param fingerprint
|
||||
* a composite fingerprint of the race in the state at which the mark passings were captured
|
||||
* @param course TODO
|
||||
*/
|
||||
void storeMarkPassings(RaceIdentifier raceIdentifier, MarkPassingRaceFingerprint fingerprint, Map<Competitor, Map<Waypoint, MarkPassing>> markPassings);
|
||||
void storeMarkPassings(RaceIdentifier raceIdentifier, MarkPassingRaceFingerprint fingerprint, Map<Competitor, Map<Waypoint, MarkPassing>> markPassings, Course course);
|
||||
}
|
||||
|
||||
+6
-5
@@ -158,6 +158,7 @@ import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CompetitorWithBoat;
|
||||
import com.sap.sailing.domain.base.ControlPoint;
|
||||
import com.sap.sailing.domain.base.ControlPointWithTwoMarks;
|
||||
import com.sap.sailing.domain.base.Course;
|
||||
import com.sap.sailing.domain.base.CourseArea;
|
||||
import com.sap.sailing.domain.base.CourseBase;
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
@@ -3206,7 +3207,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Competitor, Map<Waypoint, MarkPassing>> loadMarkPassings(RaceIdentifier raceIdentifier) {
|
||||
public Map<Competitor, Map<Waypoint, MarkPassing>> loadMarkPassings(RaceIdentifier raceIdentifier, Course course) {
|
||||
final Map<Competitor, Map<Waypoint, MarkPassing>> result;
|
||||
final Document query = new Document();
|
||||
addRaceIdentifierToQuery(query, raceIdentifier);
|
||||
@@ -3219,7 +3220,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
||||
final Serializable competitorId = markPassingsForOneCompetitorDoc.get(FieldNames.COMPETITOR_ID.name(), Serializable.class);
|
||||
final Competitor competitor = baseDomainFactory.getExistingCompetitorById(competitorId);
|
||||
for (final Document markPassingForWaypoint : markPassingsForOneCompetitorDoc.getList(FieldNames.MARK_PASSINGS.name(), Document.class)) {
|
||||
final Pair<Waypoint, MarkPassing> waypointAndMarkPassing = loadWaypointAndMarkPassing(competitor, markPassingForWaypoint);
|
||||
final Pair<Waypoint, MarkPassing> waypointAndMarkPassing = loadWaypointAndMarkPassing(competitor, markPassingForWaypoint, course);
|
||||
result.computeIfAbsent(competitor, c->new HashMap<>()).put(waypointAndMarkPassing.getA(), waypointAndMarkPassing.getB());
|
||||
}
|
||||
}
|
||||
@@ -3229,9 +3230,9 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
||||
return result;
|
||||
}
|
||||
|
||||
private Pair<Waypoint, MarkPassing> loadWaypointAndMarkPassing(Competitor competitor, Document markPassingForWaypoint) {
|
||||
final Serializable waypointId = markPassingForWaypoint.get(FieldNames.WAYPOINT_ID.name(), Serializable.class);
|
||||
final Waypoint waypoint = baseDomainFactory.getExistingWaypointById(waypointId);
|
||||
private Pair<Waypoint, MarkPassing> loadWaypointAndMarkPassing(Competitor competitor, Document markPassingForWaypoint, Course course) {
|
||||
final int waypointIndex = markPassingForWaypoint.getInteger(FieldNames.INDEX_OF_PASSED_WAYPOINT.name());
|
||||
final Waypoint waypoint = Util.get(course.getWaypoints(), waypointIndex);
|
||||
final TimePoint timePoint = TimePoint.of(markPassingForWaypoint.getLong(FieldNames.TIME_AS_MILLIS.name()));
|
||||
final MarkPassing markPassing = new MarkPassingImpl(timePoint, waypoint, competitor);
|
||||
return new Pair<>(waypoint, markPassing);
|
||||
|
||||
+7
-4
@@ -91,6 +91,7 @@ import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CompetitorWithBoat;
|
||||
import com.sap.sailing.domain.base.ControlPoint;
|
||||
import com.sap.sailing.domain.base.ControlPointWithTwoMarks;
|
||||
import com.sap.sailing.domain.base.Course;
|
||||
import com.sap.sailing.domain.base.CourseArea;
|
||||
import com.sap.sailing.domain.base.CourseBase;
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
@@ -1967,7 +1968,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
return storeRegattaLogEvent(regattaLikeIdentifier, document);
|
||||
}
|
||||
|
||||
private List<Document> storeMarkPassings(Map<Competitor, Map<Waypoint, MarkPassing>> markPassings) {
|
||||
private List<Document> storeMarkPassings(Map<Competitor, Map<Waypoint, MarkPassing>> markPassings, Course course) {
|
||||
final List<Document> result = new ArrayList<>();
|
||||
for (final Entry<Competitor, Map<Waypoint, MarkPassing>> e : markPassings.entrySet()) {
|
||||
final Document competitorMarkPassings = new Document();
|
||||
@@ -1975,7 +1976,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
final List<Document> markPassingsList = new ArrayList<>();
|
||||
for (final Entry<Waypoint, MarkPassing> f : e.getValue().entrySet()) {
|
||||
final Document markPassingDoc = new Document();
|
||||
markPassingDoc.put(FieldNames.WAYPOINT_ID.name(), f.getKey().getId());
|
||||
markPassingDoc.put(FieldNames.INDEX_OF_PASSED_WAYPOINT.name(), course.getIndexOfWaypoint(f.getKey()));
|
||||
markPassingDoc.put(FieldNames.TIME_AS_MILLIS.name(), f.getValue().getTimePoint().asMillis());
|
||||
markPassingsList.add(markPassingDoc);
|
||||
}
|
||||
@@ -1985,7 +1986,9 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void storeMarkPassings(RaceIdentifier raceIdentifier, MarkPassingRaceFingerprint fingerprint, Map<Competitor, Map<Waypoint, MarkPassing>> markPassings) {
|
||||
@Override
|
||||
public void storeMarkPassings(RaceIdentifier raceIdentifier, MarkPassingRaceFingerprint fingerprint,
|
||||
Map<Competitor, Map<Waypoint, MarkPassing>> markPassings, Course course) {
|
||||
MongoCollection<Document> markPassingCollection = database.getCollection(CollectionNames.MARKPASSINGS.name());
|
||||
JSONObject fingerprintjson = fingerprint.toJson();
|
||||
final Document query = new Document();
|
||||
@@ -1994,7 +1997,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
final Document fingerprintDoc = Document.parse(fingerprintjson.toString());
|
||||
result.put(FieldNames.MARK_PASSINGS_FINGERPRINT.name(), fingerprintDoc);
|
||||
storeRaceIdentifier(result, raceIdentifier);
|
||||
final List<Document> markPassingsDoc = storeMarkPassings(markPassings);
|
||||
final List<Document> markPassingsDoc = storeMarkPassings(markPassings, course);
|
||||
result.put(FieldNames.MARK_PASSINGS.name(), markPassingsDoc);
|
||||
markPassingCollection.replaceOne(query, result, new ReplaceOptions().upsert(true));
|
||||
}
|
||||
|
||||
+6
-4
@@ -15,6 +15,7 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Course;
|
||||
@@ -115,7 +116,7 @@ public class MarkPassingCalculator {
|
||||
* If not {@code null} then upon {@link #resume()} this mark passing calculator will look for a stored set of mark
|
||||
* passings for the {@link #race} using this registry. When such a set is found, the race's fingerprint is tried to
|
||||
* match against the {@link #race}. If it's a match then the mark passings are
|
||||
* {@link MarkPassingRaceFingerprintRegistry#loadMarkPassings(com.sap.sailing.domain.common.RaceIdentifier) loaded}
|
||||
* {@link MarkPassingRaceFingerprintRegistry#loadMarkPassings(com.sap.sailing.domain.common.RaceIdentifier, Course) loaded}
|
||||
* from the registry and all update events queued in the {@link #queue} are cleared. Otherwise, or if this is
|
||||
* {@code null}, the mark passings are calculated normally.
|
||||
*/
|
||||
@@ -594,7 +595,7 @@ public class MarkPassingCalculator {
|
||||
final Map<Competitor, Map<Waypoint, MarkPassing>> markPassings = race.getMarkPassings(/* waitForLatestUpdates */ true);
|
||||
markPassingRaceFingerprintRegistry.storeMarkPassings(race.getRaceIdentifier(),
|
||||
MarkPassingRaceFingerprintFactory.INSTANCE.createFingerprint(race),
|
||||
markPassings);
|
||||
markPassings, race.getRace().getCourse());
|
||||
}, "Waiting for mark passings for "+race.getName()+" after having resumed to store the results in registry")
|
||||
.start();
|
||||
}
|
||||
@@ -603,8 +604,9 @@ public class MarkPassingCalculator {
|
||||
}
|
||||
|
||||
private void updateMarkPassingsFromRegistry() {
|
||||
for (final Entry<Competitor, Map<Waypoint, MarkPassing>> e : markPassingRaceFingerprintRegistry.loadMarkPassings(race.getRaceIdentifier()).entrySet()) {
|
||||
race.updateMarkPassings(e.getKey(), e.getValue().values().stream().sorted(TimedComparator.INSTANCE)::iterator);
|
||||
for (final Entry<Competitor, Map<Waypoint, MarkPassing>> e : markPassingRaceFingerprintRegistry.loadMarkPassings(
|
||||
race.getRaceIdentifier(), race.getRace().getCourse()).entrySet()) {
|
||||
race.updateMarkPassings(e.getKey(), e.getValue().values().stream().sorted(TimedComparator.INSTANCE).collect(Collectors.toList()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-4
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.markpassinghash;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Course;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.TrackedRaceStatusEnum;
|
||||
@@ -18,20 +19,20 @@ import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
* that identifier; the result is a {@link MarkPassingRaceFingerprint} which can may or may not be
|
||||
* {@link MarkPassingRaceFingerprint#matches(com.sap.sailing.domain.tracking.TrackedRace) matched} by a
|
||||
* {@link TrackedRace}</li>
|
||||
* <li>If a matching fingerprint is stored in this registry for a race then {@link #loadMarkPassings(RaceIdentifier)
|
||||
* <li>If a matching fingerprint is stored in this registry for a race then {@link #loadMarkPassings(RaceIdentifier, Course)
|
||||
* loading the mark passings} for that race and {@link DynamicTrackedRace#updateMarkPassings(Competitor, Iterable)
|
||||
* updating it to the tracked race} is the logical next step.</li>
|
||||
* <li>When a tracked race has reached a "stable" state, e.g., because it's {@link TrackedRace#getEndOfTracking()
|
||||
* end-of-tracking} time point has passed or its {@link TrackedRace#getStatus() status} has changed to
|
||||
* {@link TrackedRaceStatusEnum#FINISHED} then the latest mark passing calculation results can be
|
||||
* {@link #storeMarkPassings(RaceIdentifier, MarkPassingRaceFingerprint, Map) stored} together with the fingerprint
|
||||
* {@link #storeMarkPassings(RaceIdentifier, MarkPassingRaceFingerprint, Map, Course) stored} together with the fingerprint
|
||||
* computed from the tracked race.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Fabian Kallenbach (i550803)
|
||||
*/
|
||||
public interface MarkPassingRaceFingerprintRegistry {
|
||||
void storeMarkPassings(RaceIdentifier raceIdentifier, MarkPassingRaceFingerprint fingerprint, Map<Competitor, Map<Waypoint, MarkPassing>> markPassings);
|
||||
void storeMarkPassings(RaceIdentifier raceIdentifier, MarkPassingRaceFingerprint fingerprint, Map<Competitor, Map<Waypoint, MarkPassing>> markPassings, Course course);
|
||||
|
||||
/**
|
||||
* Looks for a fingerprint for which mark passings have been stored for the race identified by
|
||||
@@ -48,6 +49,7 @@ public interface MarkPassingRaceFingerprintRegistry {
|
||||
* {@code (}{@link #getMarkPassingRaceFingerprint(RaceIdentifier) getMarkPassingRaceFingerprint(raceIdentifier)}{@code )}<p>
|
||||
*
|
||||
* If a mark passing race fingerprint is known for {@code raceIdentifier} in this registry and the
|
||||
* @param course TODO
|
||||
*/
|
||||
Map<Competitor, Map<Waypoint, MarkPassing>> loadMarkPassings(RaceIdentifier raceIdentifier);
|
||||
Map<Competitor, Map<Waypoint, MarkPassing>> loadMarkPassings(RaceIdentifier raceIdentifier, Course course);
|
||||
}
|
||||
+2
-2
@@ -67,12 +67,12 @@ public class MarkPassingRaceFingerprintConversionTest extends OnlineTracTracBase
|
||||
MongoDatabase firstDatabase = myFirstMongo.getDatabase(dbConfiguration.getDatabaseName());
|
||||
RaceIdentifier raceIdentifier = trackedRace1.getRaceIdentifier();
|
||||
final Map<Competitor, Map<Waypoint, MarkPassing>> markPassings = trackedRace1.getMarkPassings(/* waitForLatestUpdates */ true);
|
||||
new MongoObjectFactoryImpl(firstDatabase).storeMarkPassings(raceIdentifier, fingerprint, markPassings);
|
||||
new MongoObjectFactoryImpl(firstDatabase).storeMarkPassings(raceIdentifier, fingerprint, markPassings, trackedRace1.getRace().getCourse());
|
||||
DomainObjectFactory dF = PersistenceFactory.INSTANCE.getDomainObjectFactory(dbConfiguration.getService(), getDomainFactory().getBaseDomainFactory());
|
||||
Map<RaceIdentifier, MarkPassingRaceFingerprint> fingerprintHashMap = dF.loadFingerprintsForMarkPassingHashes();
|
||||
MarkPassingRaceFingerprint fingerprintAfterDB = fingerprintHashMap.get(trackedRace1.getRaceIdentifier());
|
||||
assertTrue("Original and de-serialized copy are equal", fingerprintAfterDB.matches(trackedRace1));
|
||||
final Map<Competitor, Map<Waypoint, MarkPassing>> markPassingsLoaded = dF.loadMarkPassings(trackedRace1.getRaceIdentifier());
|
||||
final Map<Competitor, Map<Waypoint, MarkPassing>> markPassingsLoaded = dF.loadMarkPassings(trackedRace1.getRaceIdentifier(), trackedRace1.getRace().getCourse());
|
||||
assertEquals(markPassings, markPassingsLoaded);
|
||||
}
|
||||
}
|
||||
+5
-4
@@ -100,6 +100,7 @@ import com.sap.sailing.domain.base.CompetitorAndBoatStore.BoatUpdateListener;
|
||||
import com.sap.sailing.domain.base.CompetitorAndBoatStore.CompetitorUpdateListener;
|
||||
import com.sap.sailing.domain.base.CompetitorWithBoat;
|
||||
import com.sap.sailing.domain.base.ControlPoint;
|
||||
import com.sap.sailing.domain.base.Course;
|
||||
import com.sap.sailing.domain.base.CourseArea;
|
||||
import com.sap.sailing.domain.base.CourseBase;
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
@@ -945,9 +946,9 @@ Replicator {
|
||||
|
||||
@Override
|
||||
public void storeMarkPassings(RaceIdentifier raceIdentifier, MarkPassingRaceFingerprint fingerprint,
|
||||
Map<Competitor, Map<Waypoint, MarkPassing>> markPassings) {
|
||||
Map<Competitor, Map<Waypoint, MarkPassing>> markPassings, Course course) {
|
||||
markPassingRaceFingerprints.put(raceIdentifier, fingerprint);
|
||||
mongoObjectFactory.storeMarkPassings(raceIdentifier, fingerprint, markPassings);
|
||||
mongoObjectFactory.storeMarkPassings(raceIdentifier, fingerprint, markPassings, course);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -956,10 +957,10 @@ Replicator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Competitor, Map<Waypoint, MarkPassing>> loadMarkPassings(RaceIdentifier raceIdentifier) {
|
||||
public Map<Competitor, Map<Waypoint, MarkPassing>> loadMarkPassings(RaceIdentifier raceIdentifier, Course course) {
|
||||
final Map<Competitor, Map<Waypoint, MarkPassing>> result;
|
||||
if (markPassingRaceFingerprints.containsKey(raceIdentifier)) {
|
||||
result = domainObjectFactory.loadMarkPassings(raceIdentifier);
|
||||
result = domainObjectFactory.loadMarkPassings(raceIdentifier, course);
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user