mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-05 11:53:53 +00:00
caching competitor results in leaderboard competitor so that for one time point all scores only need to be computed once
This commit is contained in:
1 parent
fc41de7a51
commit
957cb5738a
4 files changed
+65
-61
No files matched your search
+4
-4
@@ -42,7 +42,7 @@ public class LeaderboardScoringAndRankingTest extends AbstractLeaderboardTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneStartedRaceWithDifferentScores() {
|
||||
public void testOneStartedRaceWithDifferentScores() throws NoWindException {
|
||||
List<Competitor> competitors = createCompetitors(10);
|
||||
Regatta regatta = createRegatta(/* qualifying */0, new String[] { "Default" }, /* final */1,
|
||||
new String[] { "Default" },
|
||||
@@ -97,7 +97,7 @@ public class LeaderboardScoringAndRankingTest extends AbstractLeaderboardTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDistributionAcrossQualifyingFleetsWithDifferentScores() {
|
||||
public void testDistributionAcrossQualifyingFleetsWithDifferentScores() throws NoWindException {
|
||||
List<Competitor> competitors = createCompetitors(10);
|
||||
List<Competitor> yellow = new ArrayList<Competitor>();
|
||||
List<Competitor> blue = new ArrayList<Competitor>();
|
||||
@@ -127,7 +127,7 @@ public class LeaderboardScoringAndRankingTest extends AbstractLeaderboardTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDistributionAcrossFinalFleetsWithDifferentScores() {
|
||||
public void testDistributionAcrossFinalFleetsWithDifferentScores() throws NoWindException {
|
||||
List<Competitor> competitors = createCompetitors(10);
|
||||
List<Competitor> gold = new ArrayList<Competitor>();
|
||||
List<Competitor> silver = new ArrayList<Competitor>();
|
||||
@@ -155,7 +155,7 @@ public class LeaderboardScoringAndRankingTest extends AbstractLeaderboardTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMedalTakesPrecedence() {
|
||||
public void testMedalTakesPrecedence() throws NoWindException {
|
||||
final int firstMedalCompetitorIndex = 3;
|
||||
List<Competitor> competitors = createCompetitors(20);
|
||||
List<Competitor> medal = competitors.subList(firstMedalCompetitorIndex, firstMedalCompetitorIndex+10);
|
||||
|
||||
@@ -159,8 +159,9 @@ public interface Leaderboard extends Named {
|
||||
/**
|
||||
* Sorts the competitors according to the overall regatta standings, considering the sorting rules for
|
||||
* {@link Series}, {@link Fleet}s, medal races, discarding rules and score corrections.
|
||||
* @throws NoWindException
|
||||
*/
|
||||
List<Competitor> getCompetitorsFromBestToWorst(TimePoint timePoint);
|
||||
List<Competitor> getCompetitorsFromBestToWorst(TimePoint timePoint) throws NoWindException;
|
||||
|
||||
/**
|
||||
* Fetches all entries for all competitors of all races tracked by this leaderboard in one sweep. This saves some
|
||||
|
||||
+2
-2
@@ -459,7 +459,7 @@ public abstract class AbstractLeaderboardImpl implements Leaderboard, RaceColumn
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Competitor> getCompetitorsFromBestToWorst(TimePoint timePoint) {
|
||||
public List<Competitor> getCompetitorsFromBestToWorst(TimePoint timePoint) throws NoWindException {
|
||||
List<Competitor> result = new ArrayList<Competitor>();
|
||||
for (Competitor competitor : getCompetitors()) {
|
||||
result.add(competitor);
|
||||
@@ -468,7 +468,7 @@ public abstract class AbstractLeaderboardImpl implements Leaderboard, RaceColumn
|
||||
return result;
|
||||
}
|
||||
|
||||
protected Comparator<? super Competitor> getTotalRankComparator(TimePoint timePoint) {
|
||||
protected Comparator<? super Competitor> getTotalRankComparator(TimePoint timePoint) throws NoWindException {
|
||||
return new LeaderboardTotalRankComparator(this, timePoint, scoreComparator);
|
||||
}
|
||||
|
||||
|
||||
+57
-54
@@ -3,15 +3,17 @@ package com.sap.sailing.domain.leaderboard.impl;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
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.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
|
||||
/**
|
||||
@@ -45,75 +47,76 @@ import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
*/
|
||||
public class LeaderboardTotalRankComparator implements Comparator<Competitor> {
|
||||
private final Leaderboard leaderboard;
|
||||
private final TimePoint timePoint;
|
||||
private final Comparator<Integer> scoreComparator;
|
||||
private final Map<Pair<Competitor, RaceColumn>, Integer> totalPointsCache;
|
||||
|
||||
public LeaderboardTotalRankComparator(Leaderboard leaderboard, TimePoint timePoint, Comparator<Integer> scoreComparator) {
|
||||
public LeaderboardTotalRankComparator(Leaderboard leaderboard, TimePoint timePoint, Comparator<Integer> scoreComparator) throws NoWindException {
|
||||
super();
|
||||
this.leaderboard = leaderboard;
|
||||
this.timePoint = timePoint;
|
||||
this.scoreComparator = scoreComparator;
|
||||
totalPointsCache = new HashMap<Pair<Competitor, RaceColumn>, Integer>();
|
||||
for (Competitor competitor : leaderboard.getCompetitors()) {
|
||||
for (RaceColumn raceColumn : leaderboard.getRaceColumns()) {
|
||||
totalPointsCache.put(new Pair<Competitor, RaceColumn>(competitor, raceColumn),
|
||||
leaderboard.getTotalPoints(competitor, raceColumn, timePoint));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Leaderboard getLeaderboard() {
|
||||
return leaderboard;
|
||||
}
|
||||
|
||||
protected TimePoint getTimePoint() {
|
||||
return timePoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(Competitor o1, Competitor o2) {
|
||||
try {
|
||||
List<Integer> o1Scores = new ArrayList<Integer>();
|
||||
List<Integer> o2Scores = new ArrayList<Integer>();
|
||||
int o1ScoreSum = 0;
|
||||
int o2ScoreSum = 0;
|
||||
int o1MedalRaceScore = 0;
|
||||
int o2MedalRaceScore = 0;
|
||||
for (RaceColumn raceColumn : getLeaderboard().getRaceColumns()) {
|
||||
int preemptiveColumnResult = 0;
|
||||
final int o1Score = getLeaderboard().getTotalPoints(o1, raceColumn, timePoint);
|
||||
if (o1Score != 0) {
|
||||
o1Scores.add(o1Score);
|
||||
o1ScoreSum += o1Score;
|
||||
}
|
||||
final int o2Score = getLeaderboard().getTotalPoints(o2, raceColumn, timePoint);
|
||||
if (o2Score != 0) {
|
||||
o2Scores.add(o2Score);
|
||||
o2ScoreSum += o2Score;
|
||||
}
|
||||
if (raceColumn.isMedalRace()) {
|
||||
o1MedalRaceScore = o1Score;
|
||||
o2MedalRaceScore = o2Score;
|
||||
// similar to compareByFleet, however, tracking is not required; having medal race column points (tracked or manual) is sufficient
|
||||
preemptiveColumnResult = compareByMedalRaceParticipation(o1Score, o2Score);
|
||||
}
|
||||
if (preemptiveColumnResult == 0) {
|
||||
preemptiveColumnResult = compareByFleet(raceColumn, o1, o2);
|
||||
}
|
||||
if (preemptiveColumnResult != 0) {
|
||||
return preemptiveColumnResult;
|
||||
}
|
||||
List<Integer> o1Scores = new ArrayList<Integer>();
|
||||
List<Integer> o2Scores = new ArrayList<Integer>();
|
||||
int o1ScoreSum = 0;
|
||||
int o2ScoreSum = 0;
|
||||
int o1MedalRaceScore = 0;
|
||||
int o2MedalRaceScore = 0;
|
||||
for (RaceColumn raceColumn : getLeaderboard().getRaceColumns()) {
|
||||
int preemptiveColumnResult = 0;
|
||||
final int o1Score = totalPointsCache.get(new Pair<Competitor, RaceColumn>(o1, raceColumn));
|
||||
if (o1Score != 0) {
|
||||
o1Scores.add(o1Score);
|
||||
o1ScoreSum += o1Score;
|
||||
}
|
||||
// now count the races in which they scored; if they scored in a different number of races, prefer the competitor
|
||||
// who scored more often; otherwise, prefer the competitor who has a better score sum; if score sums are equal, break
|
||||
// tie by sorting scores and looking for the first score difference.
|
||||
int result = compareByNumberOfRacesScored(o1Scores.size(), o2Scores.size());
|
||||
if (result == 0) {
|
||||
result = compareByScoreSum(o1ScoreSum, o2ScoreSum);
|
||||
if (result == 0) {
|
||||
result = compareByMedalRaceScore(o1MedalRaceScore, o2MedalRaceScore);
|
||||
if (result == 0) {
|
||||
result = compareByBetterScore(o1Scores, o2Scores);
|
||||
}
|
||||
}
|
||||
final int o2Score = totalPointsCache.get(new Pair<Competitor, RaceColumn>(o2, raceColumn));
|
||||
if (o2Score != 0) {
|
||||
o2Scores.add(o2Score);
|
||||
o2ScoreSum += o2Score;
|
||||
}
|
||||
if (raceColumn.isMedalRace()) {
|
||||
o1MedalRaceScore = o1Score;
|
||||
o2MedalRaceScore = o2Score;
|
||||
// similar to compareByFleet, however, tracking is not required; having medal race column points
|
||||
// (tracked or manual) is sufficient
|
||||
preemptiveColumnResult = compareByMedalRaceParticipation(o1Score, o2Score);
|
||||
}
|
||||
if (preemptiveColumnResult == 0) {
|
||||
preemptiveColumnResult = compareByFleet(raceColumn, o1, o2);
|
||||
}
|
||||
if (preemptiveColumnResult != 0) {
|
||||
return preemptiveColumnResult;
|
||||
}
|
||||
return result;
|
||||
} catch (NoWindException e) {
|
||||
throw new NoWindError(e);
|
||||
}
|
||||
// now count the races in which they scored; if they scored in a different number of races, prefer the
|
||||
// competitor
|
||||
// who scored more often; otherwise, prefer the competitor who has a better score sum; if score sums are equal,
|
||||
// break
|
||||
// tie by sorting scores and looking for the first score difference.
|
||||
int result = compareByNumberOfRacesScored(o1Scores.size(), o2Scores.size());
|
||||
if (result == 0) {
|
||||
result = compareByScoreSum(o1ScoreSum, o2ScoreSum);
|
||||
if (result == 0) {
|
||||
result = compareByMedalRaceScore(o1MedalRaceScore, o2MedalRaceScore);
|
||||
if (result == 0) {
|
||||
result = compareByBetterScore(o1Scores, o2Scores);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user