ignore SwissTiming-provided mark passings if useInternalMarkPassingAlgorithm is selected

This commit is contained in:
Axel Uhl
2015-03-31 18:07:08 +02:00
parent 228219ec3b
commit dcd4af2ce2
2 changed files with 65 additions and 57 deletions
@@ -330,69 +330,77 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl implemen
public void receivedTimingData(String raceID, String boatID,
List<com.sap.sse.common.Util.Triple<Integer, Integer, Long>> markIndicesRanksAndTimesSinceStartInMilliseconds) {
assert this.raceID.equals(raceID);
if (isTrackedRaceStillReachable()) {
Competitor competitor = getCompetitorByBoatIDAndRaceIDOrBoatClass(boatID, raceID, boatClass);
if (competitor == null) {
logger.info("Received timing data for boat ID " + boatID + " in race " + raceID
+ " but couldn't find a competitor with that boat ID in this race. Ignoring.");
} else {
// the list of mark indices and time stamps is partial and usually only shows the last mark passing;
// we need to use this to *update* the competitor's mark passings list, not *replace* it
TreeMap<Integer, MarkPassing> markPassingsByMarkIndex = new TreeMap<Integer, MarkPassing>();
// now fill with the already existing mark passings for the competitor identified by boatID...
NavigableSet<MarkPassing> markPassings = trackedRace.getMarkPassings(competitor);
trackedRace.lockForRead(markPassings);
try {
for (MarkPassing markPassing : markPassings) {
markPassingsByMarkIndex.put(
trackedRace.getRace().getCourse().getIndexOfWaypoint(markPassing.getWaypoint()),
markPassing);
}
} finally {
trackedRace.unlockAfterRead(markPassings);
}
// ...and then overwrite those for which we received "new evidence"
for (com.sap.sse.common.Util.Triple<Integer, Integer, Long> markIndexRankAndTimeSinceStartInMilliseconds : markIndicesRanksAndTimesSinceStartInMilliseconds) {
Waypoint waypoint = Util.get(trackedRace.getRace().getCourse().getWaypoints(),
markIndexRankAndTimeSinceStartInMilliseconds.getA());
// If the rank and time information is empty, we interpret this by clearing the mark rounding if any
// (see
// also bug 1911):
if (markIndexRankAndTimeSinceStartInMilliseconds.getC() == null) {
markPassingsByMarkIndex.remove(markIndexRankAndTimeSinceStartInMilliseconds.getA());
} else {
// update mark passing only if we have a start time; guessed start times don't make sense and
// for the start line would lead subsequent calls to getStartOfRace() return that guessed start
// time
// which then cannot be identified as "guessed" anymore...
if (trackedRace.getStartOfRace() != null) {
final TimePoint startTime = trackedRace.getStartOfRace();
MillisecondsTimePoint timePoint = new MillisecondsTimePoint(startTime.asMillis()
+ markIndexRankAndTimeSinceStartInMilliseconds.getC());
MarkPassing markPassing = domainFactory.createMarkPassing(timePoint, waypoint,
getCompetitorByBoatIDAndRaceIDOrBoatClass(boatID, raceID, boatClass));
markPassingsByMarkIndex.put(markIndexRankAndTimeSinceStartInMilliseconds.getA(),
if (!useInternalMarkPassingAlgorithm) {
if (isTrackedRaceStillReachable()) {
Competitor competitor = getCompetitorByBoatIDAndRaceIDOrBoatClass(boatID, raceID, boatClass);
if (competitor == null) {
logger.info("Received timing data for boat ID " + boatID + " in race " + raceID
+ " but couldn't find a competitor with that boat ID in this race. Ignoring.");
} else {
// the list of mark indices and time stamps is partial and usually only shows the last mark passing;
// we need to use this to *update* the competitor's mark passings list, not *replace* it
TreeMap<Integer, MarkPassing> markPassingsByMarkIndex = new TreeMap<Integer, MarkPassing>();
// now fill with the already existing mark passings for the competitor identified by boatID...
NavigableSet<MarkPassing> markPassings = trackedRace.getMarkPassings(competitor);
trackedRace.lockForRead(markPassings);
try {
for (MarkPassing markPassing : markPassings) {
markPassingsByMarkIndex.put(
trackedRace.getRace().getCourse().getIndexOfWaypoint(markPassing.getWaypoint()),
markPassing);
}
} finally {
trackedRace.unlockAfterRead(markPassings);
}
// ...and then overwrite those for which we received "new evidence"
for (com.sap.sse.common.Util.Triple<Integer, Integer, Long> markIndexRankAndTimeSinceStartInMilliseconds : markIndicesRanksAndTimesSinceStartInMilliseconds) {
Waypoint waypoint = Util.get(trackedRace.getRace().getCourse().getWaypoints(),
markIndexRankAndTimeSinceStartInMilliseconds.getA());
// If the rank and time information is empty, we interpret this by clearing the mark rounding if
// any
// (see also bug 1911):
if (markIndexRankAndTimeSinceStartInMilliseconds.getC() == null) {
markPassingsByMarkIndex.remove(markIndexRankAndTimeSinceStartInMilliseconds.getA());
} else {
//
logger.warning("Received mark passing with time relative to start of race "
+ trackedRace.getRace().getName() + " before having received a race start time."
+ " Queueing message for re-application when a start time has been received.");
tmdMessageQueue.enqueue(raceID, boatID, markIndicesRanksAndTimesSinceStartInMilliseconds);
// update mark passing only if we have a start time; guessed start times don't make sense
// and
// for the start line would lead subsequent calls to getStartOfRace() return that guessed
// start
// time
// which then cannot be identified as "guessed" anymore...
if (trackedRace.getStartOfRace() != null) {
final TimePoint startTime = trackedRace.getStartOfRace();
MillisecondsTimePoint timePoint = new MillisecondsTimePoint(startTime.asMillis()
+ markIndexRankAndTimeSinceStartInMilliseconds.getC());
MarkPassing markPassing = domainFactory.createMarkPassing(timePoint, waypoint,
getCompetitorByBoatIDAndRaceIDOrBoatClass(boatID, raceID, boatClass));
markPassingsByMarkIndex.put(markIndexRankAndTimeSinceStartInMilliseconds.getA(),
markPassing);
} else {
//
logger.warning("Received mark passing with time relative to start of race "
+ trackedRace.getRace().getName()
+ " before having received a race start time."
+ " Queueing message for re-application when a start time has been received.");
tmdMessageQueue.enqueue(raceID, boatID,
markIndicesRanksAndTimesSinceStartInMilliseconds);
}
}
}
trackedRace.updateMarkPassings(competitor, markPassingsByMarkIndex.values());
}
} else {
if (!loggedIgnore) {
logger.info("Ignoring timing data "
+ markIndicesRanksAndTimesSinceStartInMilliseconds
+ " for SwissTiming race "
+ raceID
+ " because tracked race is no longer reachable. Was the race removed but is still tracked? "
+ "(Future occurrences of this message will be suppressed)");
loggedIgnore = true;
}
trackedRace.updateMarkPassings(competitor, markPassingsByMarkIndex.values());
}
} else {
if (!loggedIgnore) {
logger.info("Ignoring timing data " + markIndicesRanksAndTimesSinceStartInMilliseconds + " for SwissTiming race " + raceID
+ " because tracked race is no longer reachable. Was the race removed but is still tracked? "+
"(Future occurrences of this message will be suppressed)");
loggedIgnore = true;
}
}
}
@Override
@@ -354,7 +354,7 @@ public class SwissTimingReplayToDomainAdapter extends SwissTimingReplayAdapter {
trackedRace.recordFix(competitor, fix);
Course course = trackedRace.getRace().getCourse();
// record a mark passing, but not if the mark passing has happened longer than 30s before the race start
if (bestStartTimePerRaceID.get(currentRaceID) != null &&
if (!useInternalMarkPassingAlgorithm && bestStartTimePerRaceID.get(currentRaceID) != null &&
!bestStartTimePerRaceID.get(currentRaceID).after(
raceTimePoint.plus(THRESHOLD_FOR_EARLIEST_MARK_PASSING_BEFORE_START_IN_MILLIS)) &&
(!lastNextMark.containsKey(competitor) || lastNextMark.get(competitor) != nextMark) && nextMark > 0) {