added more tests for competitor calculation, bug 3302

This commit is contained in:
Axel Uhl committed 2015-10-01 15:23:08 +02:00
1 parent 4a4fb39f65
commit 73d1928db0
3 files changed
+61 -26

No files matched your search

@@ -262,11 +262,17 @@ public class CompetitorProviderCacheInvalidationTest extends AbstractLeaderboard
for (Competitor c : compLists[1]) {
raceLog.add(RaceLogEventFactory.INSTANCE.createRegisterCompetitorEvent(MillisecondsTimePoint.now(), new LogEventAuthorImpl("Me", 0), 1, c));
}
regattaLeaderboard.setSuppressed(compLists[0].get(compLists[0].size()-1), /* suppressed */ true);
Set<Competitor> expected = new HashSet<>(compLists[0]);
expected.addAll(compLists[1]);
Set<Competitor> expectedWithoutSuppressed = new HashSet<>(expected);
expectedWithoutSuppressed.remove(compLists[0].get(compLists[0].size()-1));
Set<Competitor> actual = new HashSet<>();
Util.addAll(competitorProviderRegattaLeaderboard.getAllCompetitors(), actual);
assertEquals(expected, actual);
Set<Competitor> actualWithoutSuppressed = new HashSet<>();
Util.addAll(regattaLeaderboard.getCompetitors(), actualWithoutSuppressed);
assertEquals(expectedWithoutSuppressed, actualWithoutSuppressed);
Set<Competitor> actualForRaceYellow = new HashSet<>();
Util.addAll(competitorProviderRegattaLeaderboard.getAllCompetitors(
regattaLeaderboard.getRaceColumnByName("R1"), regattaLeaderboard.getFleet("Yellow")), actualForRaceYellow);
@@ -14,6 +14,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.NavigableSet;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
@@ -1096,31 +1097,54 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
@Override
public Iterable<Competitor> getCompetitors() {
// TODO bug 1348: try to cache result; invalidation would have to listen for columns added and suppression changing;
// for meta-leaderbaords, transitive listening to those events would be necessary.
Set<Competitor> result = new HashSet<>();
for (Competitor competitor : getAllCompetitors()) {
if (!isSuppressed(competitor)) {
result.add(competitor);
}
final Iterable<Competitor> result;
// mostly the set of suppressed competitors is empty; in this case, avoid having to loop over the
// potentially large set of competitors
if (Util.isEmpty(getSuppressedCompetitors())) {
result = getAllCompetitors();
} else {
final Iterable<Competitor> allCompetitors = getAllCompetitors();
final Set<Competitor> suppressed = new HashSet<>();
Util.addAll(getSuppressedCompetitors(), suppressed);
result = new Iterable<Competitor>() {
@Override
public Iterator<Competitor> iterator() {
return new Iterator<Competitor>() {
private final Iterator<Competitor> allIter = allCompetitors.iterator();
private Competitor next = advance();
private Competitor advance() {
next = null;
while (allIter.hasNext() && next == null) {
next = allIter.next();
if (suppressed.contains(next)) {
next = null;
}
}
return next;
}
@Override
public boolean hasNext() {
return next != null;
}
@Override
public Competitor next() {
if (next == null) {
throw new NoSuchElementException();
}
final Competitor result = next;
advance();
return result;
}
};
}
};
}
return result;
}
/**
* Defines the difference between {@link #getCompetitors} and {@link #getAllCompetitors}. If a competitor is suppressed,
* it won't participate in the scoring process, particularly because it isn't considered by {@link #getCompetitorsFromBestToWorst(TimePoint)}
* nor {@link #getCompetitorsFromBestToWorst(RaceColumn, TimePoint)}.
*/
private boolean isSuppressed(Competitor competitor) {
LockUtil.lockForRead(suppressedCompetitorsLock);
try {
return suppressedCompetitors.contains(competitor);
} finally {
LockUtil.unlockAfterRead(suppressedCompetitorsLock);
}
}
@Override
public Iterable<Competitor> getSuppressedCompetitors() {
LockUtil.lockForRead(suppressedCompetitorsLock);
@@ -147,9 +147,8 @@ public class CompetitorProviderFromRaceColumnsAndRegattaLike {
}
provider.addRaceColumnListener(raceColumnListener);
// consider {@link RegattaLog}
Set<Competitor> viaLog = new RegisteredCompetitorsAnalyzer<>(provider.getRegattaLike().getRegattaLog()).analyze();
Set<Competitor> viaLog = getCompetitorsFromRegattaLogAndRegisterAsRegattaLogListener();
result.addAll(viaLog);
provider.getRegattaLike().getRegattaLog().addListener(regattaLogCompetitorsCacheInvalidationListener);
allCompetitorsCache = result;
}
return allCompetitorsCache;
@@ -168,17 +167,23 @@ public class CompetitorProviderFromRaceColumnsAndRegattaLike {
Util.addAll(raceColumn.getAllCompetitors(fleet), resultSet);
// note: adding listeners is idempotent; at most one occurrence of this listener exists in the race log's listeners set
raceColumn.getRaceLog(fleet).addListener(raceLogCompetitorsCacheInvalidationListener);
provider.addRaceColumnListener(raceColumnListener);
// consider {@link RegattaLog}
Set<Competitor> viaLog = new RegisteredCompetitorsAnalyzer<>(provider.getRegattaLike().getRegattaLog()).analyze();
Set<Competitor> viaLog = getCompetitorsFromRegattaLogAndRegisterAsRegattaLogListener();
resultSet.addAll(viaLog);
// note: adding listeners is idempotent; at most one occurrence of this listener exists in the regatta log's listeners set
provider.getRegattaLike().getRegattaLog().addListener(regattaLogCompetitorsCacheInvalidationListener);
result = resultSet;
allCompetitorsCacheByRace.put(key, result);
}
return result;
}
private Set<Competitor> getCompetitorsFromRegattaLogAndRegisterAsRegattaLogListener() {
Set<Competitor> viaLog = new RegisteredCompetitorsAnalyzer<>(provider.getRegattaLike().getRegattaLog()).analyze();
// note: adding listeners is idempotent; at most one occurrence of this listener exists in the regatta log's listeners set
provider.getRegattaLike().getRegattaLog().addListener(regattaLogCompetitorsCacheInvalidationListener);
return viaLog;
}
private void invalidateAllCompetitorsCaches() {
allCompetitorsCache = null;
// note: adding listeners was idempotent; at most one occurrence of this listener exists in the regatta log's listeners set