trying to fix bug 875 by using the same MarkPassings to decide hasFinished and grab the time points

This commit is contained in:
Axel Uhl committed 2012-07-24 10:37:15 +02:00
1 parent 45cb1db0f5
commit 2ba1dc3151
4 files changed
+20 -10

No files matched your search

@@ -44,7 +44,7 @@ public class CourseImpl extends NamedImpl implements Course {
public CourseImpl(String name, Iterable<Waypoint> waypoints) {
super(name);
lock = new ReentrantReadWriteLock();
lock = new ReentrantReadWriteLock(/* fair */ true); // if non-fair, course update may need to wait forever for many concurrent readers
listeners = new HashSet<CourseListener>();
this.waypoints = new ArrayList<Waypoint>();
waypointIndexes = new HashMap<Waypoint, Integer>();
@@ -378,7 +378,7 @@ public class DynamicTrackedRaceImpl extends TrackedRaceImpl implements
NavigableSet<MarkPassing> markPassingsForCompetitor = getMarkPassings(competitor);
synchronized (markPassingsForCompetitor) {
for (MarkPassing oldMarkPassing : markPassingsForCompetitor) {
if(oldStartMarkPassing == null) {
if (oldStartMarkPassing == null) {
oldStartMarkPassing = oldMarkPassing;
}
oldMarkPassings.put(oldMarkPassing.getWaypoint(), oldMarkPassing);
@@ -856,9 +856,11 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
public MarkPassing getMarkPassing(Competitor competitor, Waypoint waypoint) {
final NavigableSet<MarkPassing> markPassings = getMarkPassings(competitor);
if (markPassings != null) {
for (MarkPassing markPassing : markPassings) {
if (markPassing.getWaypoint() == waypoint) {
return markPassing;
synchronized (markPassings) {
for (MarkPassing markPassing : markPassings) {
if (markPassing.getWaypoint() == waypoint) {
return markPassing;
}
}
}
}
@@ -10,6 +10,7 @@ import com.sap.sailing.domain.common.Distance;
import com.sap.sailing.domain.common.NoWindError;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.tracking.MarkPassing;
import com.sap.sailing.domain.tracking.TrackedLeg;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
@@ -36,14 +37,21 @@ public class WindwardToGoComparator implements Comparator<TrackedLegOfCompetitor
assert o1.getLeg() == o2.getLeg();
try {
int result;
if (o1.hasFinishedLeg(timePoint)) {
if (o2.hasFinishedLeg(timePoint)) {
result = trackedLeg.getTrackedRace().getMarkPassing(o1.getCompetitor(), trackedLeg.getLeg().getTo()).getTimePoint().compareTo(
trackedLeg.getTrackedRace().getMarkPassing(o2.getCompetitor(), trackedLeg.getLeg().getTo()).getTimePoint());
// To avoid having to synchronize on the competitors' mark passings, grab the decisive mark passings up front and
// derive hasStarted / hasFinished from them; this is redundant to TrackedLegOfCompetitor.hasStarted/hasFinished but
// avoids the heavy-weight synchronization-based "locking". It shall help avoid NPEs in case the mark passings
// for a competitor change after deciding hasFinished and grabbing the mark passing (see bug 875).
final MarkPassing o1MarkPassingForLegEnd = trackedLeg.getTrackedRace().getMarkPassing(o1.getCompetitor(), trackedLeg.getLeg().getTo());
final MarkPassing o2MarkPassingForLegEnd = trackedLeg.getTrackedRace().getMarkPassing(o2.getCompetitor(), trackedLeg.getLeg().getTo());
final boolean o1HasFinishedLeg = o1MarkPassingForLegEnd != null && o1MarkPassingForLegEnd.getTimePoint().compareTo(timePoint) <= 0;
final boolean o2HasFinishedLeg = o2MarkPassingForLegEnd != null && o2MarkPassingForLegEnd.getTimePoint().compareTo(timePoint) <= 0;
if (o1HasFinishedLeg) {
if (o2HasFinishedLeg) {
result = o1MarkPassingForLegEnd.getTimePoint().compareTo(o2MarkPassingForLegEnd.getTimePoint());
} else {
result = -1; // o1 < o2 because o1 already finished the leg but o2 didn't
}
} else if (o2.hasFinishedLeg(timePoint)) {
} else if (o2HasFinishedLeg) {
result = 1; // o1 > o2 because o2 already finished the leg but o1 didn't
} else {
// both didn't finish the leg yet; check which one has started: