mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-24 06:28:41 +00:00
Bug 2059: Moved parts of statistics calculation to sailing server for
reusability in RacingEventService
This commit is contained in:
+2
-1
@@ -35,6 +35,7 @@ import com.sap.sailing.gwt.home.communication.regatta.RegattaWithProgressDTO;
|
||||
import com.sap.sailing.gwt.home.server.EventActionUtil.RaceCallback;
|
||||
import com.sap.sailing.gwt.server.HomeServiceUtil;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sailing.server.util.LeaderboardUtil;
|
||||
import com.sap.sailing.util.RegattaUtil;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
@@ -237,7 +238,7 @@ public class LeaderboardContext {
|
||||
}
|
||||
}
|
||||
regattaDTO.setCompetitorsCount(HomeServiceUtil.calculateCompetitorsCount(leaderboard));
|
||||
regattaDTO.setRaceCount(HomeServiceUtil.calculateRaceCount(leaderboard));
|
||||
regattaDTO.setRaceCount(LeaderboardUtil.calculateRaceCount(leaderboard));
|
||||
regattaDTO.setBoatClass(HomeServiceUtil.getBoatClassName(leaderboard));
|
||||
if (leaderboard instanceof RegattaLeaderboard) {
|
||||
regattaDTO.setStartDate(getStartDateWithEventFallback());
|
||||
|
||||
+13
-126
@@ -1,33 +1,9 @@
|
||||
package com.sap.sailing.gwt.home.server;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.NavigableSet;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sailing.domain.common.WindSource;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.GPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.WindTrack;
|
||||
import com.sap.sailing.gwt.home.communication.event.statistics.EventStatisticsDTO;
|
||||
import com.sap.sailing.gwt.home.server.EventActionUtil.LeaderboardCallback;
|
||||
import com.sap.sailing.gwt.server.HomeServiceUtil;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
import com.sap.sse.common.Util.Triple;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.gwt.dispatch.shared.commands.ResultWithTTL;
|
||||
|
||||
/**
|
||||
@@ -40,120 +16,31 @@ import com.sap.sse.gwt.dispatch.shared.commands.ResultWithTTL;
|
||||
* <li>Information from tracked races - by environment variable <code>DISABLE_STATS</code></li>
|
||||
* </ul>
|
||||
*/
|
||||
public class StatisticsCalculator implements LeaderboardCallback {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(StatisticsCalculator.class.getName());
|
||||
public class StatisticsCalculator extends com.sap.sailing.server.statistics.StatisticsCalculator
|
||||
implements LeaderboardCallback {
|
||||
|
||||
private static final boolean CALCULATE_MAX_SPEED = false;
|
||||
private static final boolean CALCULATE_SAILED_MILES = true;
|
||||
|
||||
private Set<Competitor> competitors = new HashSet<>();
|
||||
private int races, trackedRaces, regattas;
|
||||
private long numberOfGPSFixes, numberOfWindFixes;
|
||||
private Distance totalDistanceTraveled = Distance.NULL;
|
||||
private Triple<Competitor, Speed, TimePoint> maxSpeed = null;
|
||||
private final TimePoint now = MillisecondsTimePoint.now();
|
||||
public StatisticsCalculator() {
|
||||
super(CALCULATE_MAX_SPEED, CALCULATE_SAILED_MILES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doForLeaderboard(LeaderboardContext context) {
|
||||
races += HomeServiceUtil.calculateRaceCount(context.getLeaderboard());
|
||||
trackedRaces += HomeServiceUtil.calculateTrackedRaceCount(context.getLeaderboard());
|
||||
regattas++;
|
||||
String disableStats = System.getenv("DISABLE_STATS");
|
||||
if (disableStats == null || "false".equals(disableStats)) {
|
||||
try {
|
||||
for (TrackedRace trackedRace : context.getLeaderboard().getTrackedRaces()) {
|
||||
doForTrackedRace(trackedRace);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Exception during calculation of event statistics", e);
|
||||
}
|
||||
}
|
||||
addLeaderboard(context.getLeaderboard());
|
||||
}
|
||||
|
||||
private void doForTrackedRace(TrackedRace trackedRace) {
|
||||
for (Competitor competitor : trackedRace.getRace().getCompetitors()) {
|
||||
competitors.add(competitor);
|
||||
doForCompetitor(trackedRace, competitor);
|
||||
}
|
||||
for (Mark mark : trackedRace.getMarks()) {
|
||||
doForMark(trackedRace, mark);
|
||||
}
|
||||
for (WindSource windSource : trackedRace.getWindSources()) {
|
||||
doForWindSource(trackedRace, windSource);
|
||||
}
|
||||
}
|
||||
|
||||
private void doForCompetitor(TrackedRace trackedRace, Competitor competitor) {
|
||||
GPSFixTrack<Competitor, GPSFixMoving> competitorTrack = trackedRace.getTrack(competitor);
|
||||
competitorTrack.lockForRead();
|
||||
try {
|
||||
numberOfGPSFixes += Util.size(competitorTrack.getRawFixes());
|
||||
} finally {
|
||||
competitorTrack.unlockAfterRead();
|
||||
}
|
||||
if (trackedRace.hasStarted(now)) {
|
||||
final NavigableSet<MarkPassing> competitorMarkPassings = trackedRace.getMarkPassings(competitor);
|
||||
MarkPassing lastMarkPassingBeforeNow = null;
|
||||
trackedRace.lockForRead(competitorMarkPassings);
|
||||
try {
|
||||
MarkPassing next = null;
|
||||
Iterator<MarkPassing> i = competitorMarkPassings.descendingIterator();
|
||||
while (i.hasNext() && (next = i.next()).getTimePoint().after(now));
|
||||
if (next != null) {
|
||||
lastMarkPassingBeforeNow = next;
|
||||
}
|
||||
} finally {
|
||||
trackedRace.unlockAfterRead(competitorMarkPassings);
|
||||
}
|
||||
if (lastMarkPassingBeforeNow != null) {
|
||||
// competitor has started and has at least one mark passing before now; compute distance traveled up to that
|
||||
// mark passing, increasing likelihood of cache hits as compared to using "now" as the query time point
|
||||
TimePoint from = trackedRace.getStartOfRace(), to = lastMarkPassingBeforeNow.getTimePoint();
|
||||
if (CALCULATE_SAILED_MILES) {
|
||||
totalDistanceTraveled = totalDistanceTraveled.add(competitorTrack.getDistanceTraveled(from, to));
|
||||
}
|
||||
if (CALCULATE_MAX_SPEED) {
|
||||
Pair<GPSFixMoving, Speed> competitorMaxSpeed = competitorTrack.getMaximumSpeedOverGround(from, to);
|
||||
if (competitorMaxSpeed != null && (maxSpeed == null || competitorMaxSpeed.getB().compareTo( maxSpeed.getB()) > 0)
|
||||
// only accept "reasonable" max speeds
|
||||
&& competitorMaxSpeed.getB().compareTo( GPSFixTrack.DEFAULT_MAX_SPEED_FOR_SMOOTHING) <= 0) {
|
||||
maxSpeed = new Triple<>(competitor, competitorMaxSpeed.getB(), competitorMaxSpeed.getA().getTimePoint());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void doForMark(TrackedRace trackedRace, Mark mark) {
|
||||
GPSFixTrack<Mark, GPSFix> markTrack = trackedRace.getOrCreateTrack(mark);
|
||||
markTrack.lockForRead();
|
||||
try {
|
||||
numberOfGPSFixes += Util.size(markTrack.getRawFixes());
|
||||
} finally {
|
||||
markTrack.unlockAfterRead();
|
||||
}
|
||||
}
|
||||
|
||||
private void doForWindSource(TrackedRace trackedRace, WindSource windSource) {
|
||||
// don't count the "virtual" wind sources
|
||||
if (windSource.canBeStored() || windSource.getType() == WindSourceType.RACECOMMITTEE) {
|
||||
WindTrack windTrack = trackedRace.getOrCreateWindTrack(windSource);
|
||||
windTrack.lockForRead();
|
||||
try {
|
||||
numberOfWindFixes += Util.size(windTrack.getRawFixes());
|
||||
} finally {
|
||||
windTrack.unlockAfterRead();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the {@link ResultWithTTL} containing the calculated statistics.
|
||||
*/
|
||||
public ResultWithTTL<EventStatisticsDTO> getResult() {
|
||||
Distance totalDistanceTraveled = getTotalDistanceTraveled();
|
||||
totalDistanceTraveled = totalDistanceTraveled == Distance.NULL ? null : totalDistanceTraveled;
|
||||
return new ResultWithTTL<EventStatisticsDTO>(Duration.ONE_MINUTE.times(5), new EventStatisticsDTO(regattas,
|
||||
competitors.size(), races, trackedRaces, numberOfGPSFixes, numberOfWindFixes, maxSpeed, totalDistanceTraveled));
|
||||
return new ResultWithTTL<EventStatisticsDTO>(Duration.ONE_MINUTE.times(5),
|
||||
new EventStatisticsDTO(getNumberOfRegattas(), getNumberOfCompetitors(), getNumberOfRaces(),
|
||||
getNumberOfTrackedRaces(), getNumberOfGPSFixes(), getNumberOfWindFixes(), getMaxSpeed(),
|
||||
totalDistanceTraveled));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-47
@@ -20,9 +20,7 @@ import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.CourseArea;
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.EventBase;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.LeaderboardGroupBase;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.base.RemoteSailingServerReference;
|
||||
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
|
||||
@@ -179,51 +177,6 @@ public final class HomeServiceUtil {
|
||||
return Util.size(sl.getCompetitors());
|
||||
}
|
||||
|
||||
public static int calculateRaceCount(Leaderboard sl) {
|
||||
int nonCarryForwardRacesCount = 0;
|
||||
for (RaceColumn column : sl.getRaceColumns()) {
|
||||
if (!column.isCarryForward()) {
|
||||
nonCarryForwardRacesCount += Util.size(column.getFleets());
|
||||
}
|
||||
}
|
||||
return nonCarryForwardRacesCount;
|
||||
}
|
||||
|
||||
public static int calculateRaceColumnCount(Leaderboard sl) {
|
||||
int nonCarryForwardRacesCount = 0;
|
||||
for (RaceColumn rc : sl.getRaceColumns()) {
|
||||
nonCarryForwardRacesCount += rc.isCarryForward() ? 0 : 1;
|
||||
}
|
||||
return nonCarryForwardRacesCount;
|
||||
}
|
||||
|
||||
public static int calculateTrackedRaceCount(Leaderboard sl) {
|
||||
int count=0;
|
||||
for (RaceColumn column : sl.getRaceColumns()) {
|
||||
for (Fleet fleet : column.getFleets()) {
|
||||
TrackedRace trackedRace = column.getTrackedRace(fleet);
|
||||
if(trackedRace != null && trackedRace.hasGPSData() && trackedRace.hasWindData()) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public static int calculateTrackedRaceColumnCount(Leaderboard sl) {
|
||||
int count=0;
|
||||
for (RaceColumn column : sl.getRaceColumns()) {
|
||||
for (Fleet fleet : column.getFleets()) {
|
||||
TrackedRace trackedRace = column.getTrackedRace(fleet);
|
||||
if(trackedRace != null && trackedRace.hasGPSData() && trackedRace.hasWindData()) {
|
||||
count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public static String getBoatClassName(Leaderboard leaderboard) {
|
||||
BoatClass boatClass = getBoatClass(leaderboard);
|
||||
return boatClass == null ? null : boatClass.getName();
|
||||
|
||||
@@ -54,4 +54,6 @@ Export-Package: com.sap.sailing.server,
|
||||
com.sap.sailing.server.operationaltransformation,
|
||||
com.sap.sailing.server.operationaltransformation.racelog,
|
||||
com.sap.sailing.server.security,
|
||||
com.sap.sailing.server.simulation
|
||||
com.sap.sailing.server.simulation,
|
||||
com.sap.sailing.server.statistics,
|
||||
com.sap.sailing.server.util
|
||||
|
||||
+194
@@ -0,0 +1,194 @@
|
||||
package com.sap.sailing.server.statistics;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.NavigableSet;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sailing.domain.common.WindSource;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.tracking.GPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.WindTrack;
|
||||
import com.sap.sailing.server.util.LeaderboardUtil;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
import com.sap.sse.common.Util.Triple;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
|
||||
/**
|
||||
* Calculates the statistics for the regatta(s) passed to the {@link #addLeaderboard(Leaderboard)} method. Because this
|
||||
* calculations can be costly and time consuming, several information can be disabled/enabled:
|
||||
* <ul>
|
||||
* <li>Maximum speed (of a competitor) - by constructor parameter {@link #calculateMaxSpeed} within this class</li>
|
||||
* <li>Total of sailed miles - by constructor parameter {@link #calculateDistanceTravelled} within this class</li>
|
||||
* </ul>
|
||||
*/
|
||||
public class StatisticsCalculator {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(StatisticsCalculator.class.getName());
|
||||
|
||||
private final boolean calculateMaxSpeed;
|
||||
private final boolean calculateDistanceTravelled;
|
||||
|
||||
private Set<Competitor> competitors = new HashSet<>();
|
||||
private int races, trackedRaces, regattas;
|
||||
private long numberOfGPSFixes, numberOfWindFixes;
|
||||
private Distance totalDistanceTraveled = Distance.NULL;
|
||||
private Triple<Competitor, Speed, TimePoint> maxSpeed = null;
|
||||
private final TimePoint now = MillisecondsTimePoint.now();
|
||||
|
||||
public StatisticsCalculator() {
|
||||
this(false, true);
|
||||
}
|
||||
|
||||
public StatisticsCalculator(boolean calculateMaxSpeed, boolean calculateDistanceTravelled) {
|
||||
this.calculateMaxSpeed = calculateMaxSpeed;
|
||||
this.calculateDistanceTravelled = calculateDistanceTravelled;
|
||||
}
|
||||
|
||||
public void addLeaderboard(Leaderboard leaderboard) {
|
||||
races += LeaderboardUtil.calculateRaceCount(leaderboard);
|
||||
trackedRaces += LeaderboardUtil.calculateTrackedRaceCount(leaderboard);
|
||||
regattas++;
|
||||
String disableStats = System.getenv("DISABLE_STATS");
|
||||
if (disableStats == null || "false".equals(disableStats)) {
|
||||
try {
|
||||
for (TrackedRace trackedRace : leaderboard.getTrackedRaces()) {
|
||||
doForTrackedRace(trackedRace);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Exception during calculation of event statistics", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void doForTrackedRace(TrackedRace trackedRace) {
|
||||
for (Competitor competitor : trackedRace.getRace().getCompetitors()) {
|
||||
competitors.add(competitor);
|
||||
doForCompetitor(trackedRace, competitor);
|
||||
}
|
||||
for (Mark mark : trackedRace.getMarks()) {
|
||||
doForMark(trackedRace, mark);
|
||||
}
|
||||
for (WindSource windSource : trackedRace.getWindSources()) {
|
||||
doForWindSource(trackedRace, windSource);
|
||||
}
|
||||
}
|
||||
|
||||
private void doForCompetitor(TrackedRace trackedRace, Competitor competitor) {
|
||||
GPSFixTrack<Competitor, GPSFixMoving> competitorTrack = trackedRace.getTrack(competitor);
|
||||
competitorTrack.lockForRead();
|
||||
try {
|
||||
numberOfGPSFixes += Util.size(competitorTrack.getRawFixes());
|
||||
} finally {
|
||||
competitorTrack.unlockAfterRead();
|
||||
}
|
||||
if (trackedRace.hasStarted(now)) {
|
||||
final NavigableSet<MarkPassing> competitorMarkPassings = trackedRace.getMarkPassings(competitor);
|
||||
MarkPassing lastMarkPassingBeforeNow = null;
|
||||
trackedRace.lockForRead(competitorMarkPassings);
|
||||
try {
|
||||
MarkPassing next = null;
|
||||
Iterator<MarkPassing> i = competitorMarkPassings.descendingIterator();
|
||||
while (i.hasNext() && (next = i.next()).getTimePoint().after(now))
|
||||
;
|
||||
if (next != null) {
|
||||
lastMarkPassingBeforeNow = next;
|
||||
}
|
||||
} finally {
|
||||
trackedRace.unlockAfterRead(competitorMarkPassings);
|
||||
}
|
||||
if (lastMarkPassingBeforeNow != null) {
|
||||
// competitor has started and has at least one mark passing before now; compute distance traveled up to
|
||||
// that
|
||||
// mark passing, increasing likelihood of cache hits as compared to using "now" as the query time point
|
||||
TimePoint from = trackedRace.getStartOfRace(), to = lastMarkPassingBeforeNow.getTimePoint();
|
||||
doForCompetitorTrackAndTimeRange(competitor, competitorTrack, from, to);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void doForCompetitorTrackAndTimeRange(Competitor competitor,
|
||||
GPSFixTrack<Competitor, GPSFixMoving> competitorTrack, TimePoint from, TimePoint to) {
|
||||
if (calculateDistanceTravelled) {
|
||||
totalDistanceTraveled = totalDistanceTraveled.add(competitorTrack.getDistanceTraveled(from, to));
|
||||
}
|
||||
if (calculateMaxSpeed) {
|
||||
Pair<GPSFixMoving, Speed> competitorMaxSpeed = competitorTrack.getMaximumSpeedOverGround(from, to);
|
||||
if (competitorMaxSpeed != null
|
||||
&& (maxSpeed == null || competitorMaxSpeed.getB().compareTo(maxSpeed.getB()) > 0)
|
||||
// only accept "reasonable" max speeds
|
||||
&& competitorMaxSpeed.getB().compareTo(GPSFixTrack.DEFAULT_MAX_SPEED_FOR_SMOOTHING) <= 0) {
|
||||
maxSpeed = new Triple<>(competitor, competitorMaxSpeed.getB(),
|
||||
competitorMaxSpeed.getA().getTimePoint());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void doForMark(TrackedRace trackedRace, Mark mark) {
|
||||
GPSFixTrack<Mark, GPSFix> markTrack = trackedRace.getOrCreateTrack(mark);
|
||||
markTrack.lockForRead();
|
||||
try {
|
||||
numberOfGPSFixes += Util.size(markTrack.getRawFixes());
|
||||
} finally {
|
||||
markTrack.unlockAfterRead();
|
||||
}
|
||||
}
|
||||
|
||||
private void doForWindSource(TrackedRace trackedRace, WindSource windSource) {
|
||||
// don't count the "virtual" wind sources
|
||||
if (windSource.canBeStored() || windSource.getType() == WindSourceType.RACECOMMITTEE) {
|
||||
WindTrack windTrack = trackedRace.getOrCreateWindTrack(windSource);
|
||||
windTrack.lockForRead();
|
||||
try {
|
||||
numberOfWindFixes += Util.size(windTrack.getRawFixes());
|
||||
} finally {
|
||||
windTrack.unlockAfterRead();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getNumberOfRaces() {
|
||||
return races;
|
||||
}
|
||||
|
||||
public int getNumberOfTrackedRaces() {
|
||||
return trackedRaces;
|
||||
}
|
||||
|
||||
public int getNumberOfRegattas() {
|
||||
return regattas;
|
||||
}
|
||||
|
||||
public long getNumberOfGPSFixes() {
|
||||
return numberOfGPSFixes;
|
||||
}
|
||||
|
||||
public long getNumberOfWindFixes() {
|
||||
return numberOfWindFixes;
|
||||
}
|
||||
|
||||
public Distance getTotalDistanceTraveled() {
|
||||
return totalDistanceTraveled;
|
||||
}
|
||||
|
||||
public Triple<Competitor, Speed, TimePoint> getMaxSpeed() {
|
||||
return maxSpeed;
|
||||
}
|
||||
|
||||
public int getNumberOfCompetitors() {
|
||||
return competitors.size();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.sap.sailing.server.util;
|
||||
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
public interface LeaderboardUtil {
|
||||
|
||||
public static int calculateRaceCount(Leaderboard sl) {
|
||||
int nonCarryForwardRacesCount = 0;
|
||||
for (RaceColumn column : sl.getRaceColumns()) {
|
||||
if (!column.isCarryForward()) {
|
||||
nonCarryForwardRacesCount += Util.size(column.getFleets());
|
||||
}
|
||||
}
|
||||
return nonCarryForwardRacesCount;
|
||||
}
|
||||
|
||||
public static int calculateTrackedRaceCount(Leaderboard sl) {
|
||||
int count=0;
|
||||
for (RaceColumn column : sl.getRaceColumns()) {
|
||||
for (Fleet fleet : column.getFleets()) {
|
||||
TrackedRace trackedRace = column.getTrackedRace(fleet);
|
||||
if(trackedRace != null && trackedRace.hasGPSData() && trackedRace.hasWindData()) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user