diff --git a/java/com.sap.sailing.dashboards.gwt/GWT Dashboards DevMode.launch b/java/com.sap.sailing.dashboards.gwt/GWT Dashboards DevMode.launch index 5f6bb31e343..a5d93d85fd1 100644 --- a/java/com.sap.sailing.dashboards.gwt/GWT Dashboards DevMode.launch +++ b/java/com.sap.sailing.dashboards.gwt/GWT Dashboards DevMode.launch @@ -1,51 +1,51 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/com.sap.sailing.dashboards.gwt/GWT Dashboards SDM.launch b/java/com.sap.sailing.dashboards.gwt/GWT Dashboards SDM.launch index 4763ab7a0dc..bdcd731ab96 100644 --- a/java/com.sap.sailing.dashboards.gwt/GWT Dashboards SDM.launch +++ b/java/com.sap.sailing.dashboards.gwt/GWT Dashboards SDM.launch @@ -1,52 +1,52 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/com.sap.sailing.domain.test/resources/MoevensteinCompetitorPositions.json.gz b/java/com.sap.sailing.domain.test/resources/MoevensteinCompetitorPositions.json.gz new file mode 100644 index 00000000000..3b9370d152c Binary files /dev/null and b/java/com.sap.sailing.domain.test/resources/MoevensteinCompetitorPositions.json.gz differ diff --git a/java/com.sap.sailing.domain.test/resources/MoevensteinMarkPositions.json.gz b/java/com.sap.sailing.domain.test/resources/MoevensteinMarkPositions.json.gz new file mode 100755 index 00000000000..759c9bc233f Binary files /dev/null and b/java/com.sap.sailing.domain.test/resources/MoevensteinMarkPositions.json.gz differ diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/markpassing/AbstractExportedPositionsBasedTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/markpassing/AbstractExportedPositionsBasedTest.java new file mode 100755 index 00000000000..8bb1a003e7e --- /dev/null +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/markpassing/AbstractExportedPositionsBasedTest.java @@ -0,0 +1,187 @@ +package com.sap.sailing.domain.test.markpassing; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; +import java.util.zip.GZIPInputStream; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import com.sap.sailing.domain.base.Boat; +import com.sap.sailing.domain.base.BoatClass; +import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.base.CompetitorWithBoat; +import com.sap.sailing.domain.base.ControlPoint; +import com.sap.sailing.domain.base.Course; +import com.sap.sailing.domain.base.Mark; +import com.sap.sailing.domain.base.Regatta; +import com.sap.sailing.domain.base.Waypoint; +import com.sap.sailing.domain.base.impl.BoatImpl; +import com.sap.sailing.domain.base.impl.CompetitorWithBoatImpl; +import com.sap.sailing.domain.base.impl.CourseAreaImpl; +import com.sap.sailing.domain.base.impl.CourseImpl; +import com.sap.sailing.domain.base.impl.FleetImpl; +import com.sap.sailing.domain.base.impl.MarkImpl; +import com.sap.sailing.domain.base.impl.NationalityImpl; +import com.sap.sailing.domain.base.impl.PersonImpl; +import com.sap.sailing.domain.base.impl.RaceDefinitionImpl; +import com.sap.sailing.domain.base.impl.RegattaImpl; +import com.sap.sailing.domain.base.impl.SeriesImpl; +import com.sap.sailing.domain.base.impl.TeamImpl; +import com.sap.sailing.domain.base.impl.WaypointImpl; +import com.sap.sailing.domain.common.PassingInstruction; +import com.sap.sailing.domain.common.TrackedRaceStatusEnum; +import com.sap.sailing.domain.common.impl.DegreePosition; +import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl; +import com.sap.sailing.domain.common.tracking.GPSFix; +import com.sap.sailing.domain.common.tracking.GPSFixMoving; +import com.sap.sailing.domain.common.tracking.impl.GPSFixImpl; +import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl; +import com.sap.sailing.domain.leaderboard.impl.LowPoint; +import com.sap.sailing.domain.ranking.OneDesignRankingMetric; +import com.sap.sailing.domain.tracking.DynamicGPSFixTrack; +import com.sap.sailing.domain.tracking.DynamicTrackedRegatta; +import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl; +import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl; +import com.sap.sailing.domain.tracking.impl.EmptyWindStore; +import com.sap.sailing.domain.tracking.impl.TrackedRaceStatusImpl; +import com.sap.sse.common.Color; +import com.sap.sse.common.impl.AbstractColor; +import com.sap.sse.common.impl.DegreeBearingImpl; +import com.sap.sse.common.impl.MillisecondsTimePoint; + +/** + * Can read JSON files exported through the + * /sailingserver/api/v1/regattas/{regattaname}/races/{racename}/competitors/positions and + * /sailingserver/api/v1/regattas/{regattaname}/races/{racename}/marks/positions. + * + * REST end point. + * + * @author Axel Uhl (D043530) + * + */ +public abstract class AbstractExportedPositionsBasedTest { + protected DynamicTrackedRaceImpl readRace(String gzippedJsonCompetitorPositionsResourceName, + String gzippedJsonMarkPositionsResourceName, BoatClass boatClass) throws IOException, ParseException { + final JSONParser parser = new JSONParser(); + final JSONObject competitorPositionsJson = (JSONObject) parser.parse(new InputStreamReader(new GZIPInputStream(getClass().getResourceAsStream(gzippedJsonCompetitorPositionsResourceName)))); + final JSONObject markPositionsJson = (JSONObject) parser.parse(new InputStreamReader(new GZIPInputStream(getClass().getResourceAsStream(gzippedJsonMarkPositionsResourceName)))); + assertEquals(competitorPositionsJson.get("name"), markPositionsJson.get("name")); + assertEquals(competitorPositionsJson.get("regatta"), markPositionsJson.get("regatta")); + final Map> markTracks = createMarkTracks(markPositionsJson); + final Map marksByName = new HashMap<>(); + for (final Mark mark : markTracks.keySet()) { + marksByName.put(mark.getName(), mark); + } + final Course course = createCourse(marksByName); + final Regatta regatta = new RegattaImpl((String) competitorPositionsJson.get("regatta"), boatClass, + /* canBoatsOfCompetitorsChangePerRace */ false, /* startDate */ null, /* endDate */ null, + Collections.singleton(new SeriesImpl("Default", /* isMedal */ false, + /* isFleetsCanRunInParallel */ true, Collections.singleton(new FleetImpl("Default")), + /* raceColumnNames */ Collections.singleton("R1"), /* trackedRegattaRegistry */ null)), + /* persistent */ false, new LowPoint(), UUID.randomUUID(), + new CourseAreaImpl("CourseArea", UUID.randomUUID()), OneDesignRankingMetric::new); + final DynamicTrackedRegatta trackedRegatta = new DynamicTrackedRegattaImpl(regatta); + final Map> competitorsAndTheirTracks = createCompetitorsAndTheirTracks(competitorPositionsJson, boatClass); + final Map competitorsAndBoats = new HashMap<>(); + for (final CompetitorWithBoat cwb : competitorsAndTheirTracks.keySet()) { + competitorsAndBoats.put(cwb, cwb.getBoat()); + } + final DynamicTrackedRaceImpl result = new DynamicTrackedRaceImpl(trackedRegatta, + new RaceDefinitionImpl((String) competitorPositionsJson.get("name"), course, boatClass, + competitorsAndBoats, UUID.randomUUID()), + /* sidelines */ Collections.emptySet(), + EmptyWindStore.INSTANCE, + /* delayToLiveInMillis */ 3000, /* millisecondsOverWhichToAverageWind */ 15000, /* millisecondsOverWhichToAverageSpeed */ 10000, + /* useInternalMarkPassingAlgorithm */ true, OneDesignRankingMetric::new, /* raceLogResolver */ null); + result.setStatus(new TrackedRaceStatusImpl(TrackedRaceStatusEnum.LOADING, 0.0)); + for (final Entry> e : competitorsAndTheirTracks.entrySet()) { + final DynamicGPSFixTrack track = result.getTrack(e.getKey()); + for (final GPSFixMoving fix : e.getValue()) { + track.add(fix); + } + } + for (final Entry> e : markTracks.entrySet()) { + final DynamicGPSFixTrack markTrack = result.getOrCreateTrack(e.getKey()); + for (final GPSFix fix : e.getValue()) { + markTrack.add(fix); + } + } + result.setStatus(new TrackedRaceStatusImpl(TrackedRaceStatusEnum.LOADING, 1.0)); + result.setStatus(new TrackedRaceStatusImpl(TrackedRaceStatusEnum.TRACKING, 1.0)); + return result; + } + + protected Course createCourse(Map controlPoints, Waypoint... waypoints) { + return new CourseImpl("Course", Arrays.asList(waypoints)); + } + + protected Waypoint wp(Map controlPoints, String controlPointName, PassingInstruction passingInstruction) { + return new WaypointImpl(controlPoints.get(controlPointName), passingInstruction); + } + + private Map> createCompetitorsAndTheirTracks(JSONObject competitorPositionsJson, BoatClass boatClass) { + final JSONArray competitorsJson = (JSONArray) competitorPositionsJson.get("competitors"); + final Map> result = new HashMap<>(); + for (final Object competitorJsonObject : competitorsJson) { + final JSONObject competitorJson = (JSONObject) competitorJsonObject; + final UUID id = UUID.fromString((String) competitorJson.get("id")); + final String name = (String) competitorJson.get("name"); + final Color color = AbstractColor.getCssColor((String) competitorJson.get("color")); + final String sailNumber = (String) competitorJson.get("sailNumber"); + final CompetitorWithBoat competitor = new CompetitorWithBoatImpl(id, name, name, color, /* email */ null, /* flagImage */ null, + new TeamImpl(name, + Collections.singleton(new PersonImpl(name, new NationalityImpl("GER"), + /* dateOfBirth */ null, /* description */ null)), + /* coach */ null), + /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, /* searchTag */ null, + new BoatImpl(UUID.randomUUID(), name, boatClass, sailNumber)); + final List fixes = new ArrayList<>(); + final JSONArray fixesAsJson = (JSONArray) competitorJson.get("track"); + for (final Object fixAsJsonObject : fixesAsJson) { + final JSONObject fixAsJson = (JSONObject) fixAsJsonObject; + GPSFixMoving fix = new GPSFixMovingImpl(new DegreePosition((Double) fixAsJson.get("lat-deg"), (Double) fixAsJson.get("lng-deg")), + new MillisecondsTimePoint((Long) fixAsJson.get("timepoint-ms")), + new KnotSpeedWithBearingImpl((Double) fixAsJson.get("speed-kts"), + new DegreeBearingImpl((Double) fixAsJson.get("truebearing-deg")))); + fixes.add(fix); + } + result.put(competitor, fixes); + } + return result; + } + + protected abstract Course createCourse(Map marksByName); + + private Map> createMarkTracks(JSONObject markPositionsJson) { + final Map> result = new HashMap<>(); + final JSONArray marksJson = (JSONArray) markPositionsJson.get("marks"); + for (final Object markJsonObject : marksJson) { + final JSONObject markJson = (JSONObject) markJsonObject; + final String name = (String) markJson.get("name"); + final UUID id = UUID.fromString((String) markJson.get("id")); + final JSONArray track = (JSONArray) markJson.get("track"); + final List fixes = new ArrayList<>(); + for (final Object fixJsonObject : track) { + final JSONObject fixAsJson = (JSONObject) fixJsonObject; + final GPSFix fix = new GPSFixImpl(new DegreePosition((Double) fixAsJson.get("lat-deg"), (Double) fixAsJson.get("lng-deg")), + new MillisecondsTimePoint((Long) fixAsJson.get("timepoint-ms"))); + fixes.add(fix); + } + result.put(new MarkImpl(id, name), fixes); + } + return result; + } +} diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/markpassing/MarkPassingCalculatorWithTrackersOnStartBoatTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/markpassing/MarkPassingCalculatorWithTrackersOnStartBoatTest.java new file mode 100755 index 00000000000..da62c8142f0 --- /dev/null +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/markpassing/MarkPassingCalculatorWithTrackersOnStartBoatTest.java @@ -0,0 +1,122 @@ +package com.sap.sailing.domain.test.markpassing; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.json.simple.parser.ParseException; +import org.junit.Before; +import org.junit.Test; + +import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.base.ControlPoint; +import com.sap.sailing.domain.base.Course; +import com.sap.sailing.domain.base.Mark; +import com.sap.sailing.domain.base.impl.BoatClassImpl; +import com.sap.sailing.domain.base.impl.ControlPointWithTwoMarksImpl; +import com.sap.sailing.domain.common.BoatClassMasterdata; +import com.sap.sailing.domain.common.PassingInstruction; +import com.sap.sailing.domain.markpassingcalculation.MarkPassingCalculator; +import com.sap.sailing.domain.markpassingcalculation.impl.CandidateChooserImpl; +import com.sap.sailing.domain.markpassingcalculation.impl.CandidateChooserImpl.Stats; +import com.sap.sailing.domain.markpassingcalculation.impl.CandidateChooserImpl.Stats.CompetitorStats; +import com.sap.sailing.domain.test.measurements.Measurement; +import com.sap.sailing.domain.test.measurements.MeasurementCase; +import com.sap.sailing.domain.test.measurements.MeasurementXMLFile; +import com.sap.sailing.domain.tracking.MarkPassing; +import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl; +import com.sap.sailing.domain.tracking.impl.TrackedRaceImpl; +import com.sap.sse.common.Duration; +import com.sap.sse.common.TimePoint; +import com.sap.sse.common.Util; +import com.sap.sse.common.impl.MillisecondsTimePoint; + +public class MarkPassingCalculatorWithTrackersOnStartBoatTest extends AbstractExportedPositionsBasedTest { + private DynamicTrackedRaceImpl trackedRace; + private Map> markPassings; + private CandidateChooserImpl candidateChooser; + private TimePoint startOfSetup; + + @Before + public void setUp() throws IOException, ParseException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { + startOfSetup = MillisecondsTimePoint.now(); + trackedRace = readRace("/MoevensteinCompetitorPositions.json.gz", "/MoevensteinMarkPositions.json.gz", new BoatClassImpl("J/70", BoatClassMasterdata.J70)); + markPassings = new HashMap<>(); + for (final Competitor competitor : trackedRace.getRace().getCompetitors()) { + markPassings.put(competitor, trackedRace.getMarkPassings(competitor, /* waitForLatest */ true)); + } + final Field markPassingCalculatorField = TrackedRaceImpl.class.getDeclaredField("markPassingCalculator"); + markPassingCalculatorField.setAccessible(true); + final Object markPassingCalculator = markPassingCalculatorField.get(trackedRace); + Field candidateChooserField = MarkPassingCalculator.class.getDeclaredField("chooser"); + candidateChooserField.setAccessible(true); + candidateChooser = (CandidateChooserImpl) candidateChooserField.get(markPassingCalculator); + } + + @Override + protected Course createCourse(Map marksByName) { + final Map controlPoints = new HashMap<>(marksByName); + controlPoints.put("Start/Ziel", new ControlPointWithTwoMarksImpl(marksByName.get("G2"), marksByName.get("MEU"), "Start/Ziel")); + controlPoints.put("Gate", new ControlPointWithTwoMarksImpl(marksByName.get("G1"), marksByName.get("G2"), "Gate")); + return createCourse(controlPoints, + wp(controlPoints, "Start/Ziel", PassingInstruction.Line), + wp(controlPoints, "LUV", PassingInstruction.Port), + wp(controlPoints, "Gate", PassingInstruction.Gate), + wp(controlPoints, "LUV", PassingInstruction.Port), + wp(controlPoints, "Gate", PassingInstruction.Gate), + wp(controlPoints, "LUV", PassingInstruction.Port), + wp(controlPoints, "Start/Ziel", PassingInstruction.Line), + wp(controlPoints, "LUV", PassingInstruction.Port), + wp(controlPoints, "Gate", PassingInstruction.Gate), + wp(controlPoints, "LUV", PassingInstruction.Port), + wp(controlPoints, "Gate", PassingInstruction.Gate), + wp(controlPoints, "LUV", PassingInstruction.Port), + wp(controlPoints, "Start/Ziel", PassingInstruction.Line), + wp(controlPoints, "LUV", PassingInstruction.Port), + wp(controlPoints, "Gate", PassingInstruction.Gate), + wp(controlPoints, "LUV", PassingInstruction.Port), + wp(controlPoints, "Gate", PassingInstruction.Gate), + wp(controlPoints, "LUV", PassingInstruction.Port), + wp(controlPoints, "Start/Ziel", PassingInstruction.Line)); + } + + @Test + public void testRaceCreation() throws IOException { + final Duration timeSinceStartOfSetup = startOfSetup.until(MillisecondsTimePoint.now()); + assertNotNull(trackedRace); + assertEquals(5, Util.size(trackedRace.getRace().getCompetitors())); + assertEquals(5, markPassings.size()); + final Stats stats = candidateChooser.getStats(); + final MeasurementXMLFile performanceReport = new MeasurementXMLFile(this.getClass()); + final MeasurementCase performanceReportCase = performanceReport.addCase(getClass().getSimpleName()); + performanceReportCase.addMeasurement(new Measurement("TimeForSetupInMillis", timeSinceStartOfSetup.asMillis())); + performanceReportCase.addMeasurement(new Measurement("TotalNumberOfCandidates", stats.getTotalNumberOfCandidates())); + performanceReportCase.addMeasurement(new Measurement("TotalNumberOfCandidatesAfterHighestProbabilityInShortTimeFilter", stats.getTotalNumberOfCandidatesAfterHighestProbabilityInShortTimeFilter())); + performanceReportCase.addMeasurement(new Measurement("TotalFilterRatioStage1", + (double) stats.getTotalNumberOfCandidatesAfterHighestProbabilityInShortTimeFilter() / (double) stats.getTotalNumberOfCandidates())); + performanceReportCase.addMeasurement(new Measurement("TotalNumberOfCandidatesAfterBoundingBoxFilter", stats.getTotalNumberOfCandidatesAfterBoundingBoxFilter())); + performanceReportCase.addMeasurement(new Measurement("TotalFilterRatioStage2", + (double) stats.getTotalNumberOfCandidatesAfterBoundingBoxFilter() / (double) stats.getTotalNumberOfCandidatesAfterHighestProbabilityInShortTimeFilter())); + performanceReportCase.addMeasurement(new Measurement("TotalFilterRatio", + (double) stats.getTotalNumberOfCandidatesAfterBoundingBoxFilter() / (double) stats.getTotalNumberOfCandidates())); + performanceReportCase.addMeasurement(new Measurement("TotalNumberOfEdges", stats.getTotalNumberOfEdges())); + for (final Entry competitorStats : stats.getPerCompetitorStats().entrySet()) { + performanceReportCase.addMeasurement(new Measurement(competitorStats.getKey().getName()+"-Candidates", competitorStats.getValue().getCandidates())); + performanceReportCase.addMeasurement(new Measurement(competitorStats.getKey().getName()+"-CandidatesAfterHighestProbabilityInShortTimeFilter", competitorStats.getValue().getCandidatesAfterHighestProbabilityInShortTimeFilter())); + performanceReportCase.addMeasurement(new Measurement(competitorStats.getKey().getName()+"-FilterRatioStage1", + (double) competitorStats.getValue().getCandidatesAfterHighestProbabilityInShortTimeFilter() / (double) competitorStats.getValue().getCandidates())); + performanceReportCase.addMeasurement(new Measurement(competitorStats.getKey().getName()+"-CandidatesAfterBoundingBoxFilter", competitorStats.getValue().getCandidatesAfterBoundingBoxFilter())); + performanceReportCase.addMeasurement(new Measurement(competitorStats.getKey().getName()+"-FilterRatioStage2", + (double) competitorStats.getValue().getCandidatesAfterBoundingBoxFilter() / (double) competitorStats.getValue().getCandidatesAfterHighestProbabilityInShortTimeFilter())); + performanceReportCase.addMeasurement(new Measurement(competitorStats.getKey().getName()+"-FilterRatio", + (double) competitorStats.getValue().getCandidatesAfterBoundingBoxFilter() / (double) competitorStats.getValue().getCandidates())); + performanceReportCase.addMeasurement(new Measurement(competitorStats.getKey().getName()+"-Edges", competitorStats.getValue().getEdges())); + } + performanceReport.write(); + } +} diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/measurements/MeasurementCase.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/measurements/MeasurementCase.java index 6e8b7577c22..31d9168b2c5 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/measurements/MeasurementCase.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/measurements/MeasurementCase.java @@ -1,6 +1,6 @@ package com.sap.sailing.domain.test.measurements; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Set; /** @@ -17,7 +17,7 @@ public class MeasurementCase { MeasurementCase(String name) { super(); this.name = name; - measurements = new HashSet<>(); + measurements = new LinkedHashSet<>(); } String getName() { diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/measurements/MeasurementXMLFile.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/measurements/MeasurementXMLFile.java index 240b021f9f2..3ca03566673 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/measurements/MeasurementXMLFile.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/measurements/MeasurementXMLFile.java @@ -21,7 +21,7 @@ import com.sap.sse.common.Util; *
  *       MeasurementXMLFile performanceReport = new MeasurementXMLFile(this.getClass());
  *       MeasurementCase performanceReportCase = performanceReport.addCase(getClass().getSimpleName());
- *       performanceReportCase.addMeasurement(new Measurement("This is a measurement name", 12345); // 12345 is the value to be recorded
+ *       performanceReportCase.addMeasurement(new Measurement("This is a measurement name", 12345)); // 12345 is the value to be recorded
  *       performanceReport.write();
  * 
* diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/markpassingcalculation/impl/CandidateChooserImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/markpassingcalculation/impl/CandidateChooserImpl.java index 8eacde8a691..cd4a7caa47f 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/markpassingcalculation/impl/CandidateChooserImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/markpassingcalculation/impl/CandidateChooserImpl.java @@ -9,6 +9,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.NavigableSet; import java.util.Set; import java.util.SortedSet; @@ -149,6 +150,88 @@ public class CandidateChooserImpl implements CandidateChooser { * mode, so no synchronization is necessary. */ private final HashMap perCompetitorLocks; + + /** + * Captures statistics about this candidate chooser. + * + * @author Axel Uhl (D043530) + * + */ + public class Stats { + public class CompetitorStats { + private final int candidates; + private final int candidatesAfterHighestProbabilityInShortTimeFilter; + private final int candidatesAfterBoundingBoxFilter; + private final int edges; + public CompetitorStats(int candidates, int candidatesAfterHighestProbabilityInShortTimeFilter, + int candidatesAfterBoundingBoxFilter, int edges) { + super(); + this.candidates = candidates; + this.candidatesAfterHighestProbabilityInShortTimeFilter = candidatesAfterHighestProbabilityInShortTimeFilter; + this.candidatesAfterBoundingBoxFilter = candidatesAfterBoundingBoxFilter; + this.edges = edges; + } + public int getCandidates() { + return candidates; + } + public int getCandidatesAfterHighestProbabilityInShortTimeFilter() { + return candidatesAfterHighestProbabilityInShortTimeFilter; + } + public int getCandidatesAfterBoundingBoxFilter() { + return candidatesAfterBoundingBoxFilter; + } + public int getEdges() { + return edges; + } + } + + public int getTotalNumberOfCandidates() { + int result = 0; + for (final Set competitorCandidates : candidates.values()) { + result += competitorCandidates.size(); + } + return result; + } + + public int getTotalNumberOfCandidatesAfterHighestProbabilityInShortTimeFilter() { + int result = 0; + // TODO bug4221 implement + return result; + } + + public int getTotalNumberOfCandidatesAfterBoundingBoxFilter() { + int result = 0; + // TODO bug4221 implement + return result; + } + + public int getTotalNumberOfEdges() { + int result = 0; + for (final Map> edgesPerCandidate : allEdges.values()) { + for (final Set edges : edgesPerCandidate.values()) { + result += edges.size(); + } + } + return result; + } + + public Map getPerCompetitorStats() { + final Map result = new HashMap<>(); + for (final Entry> competitorAndCandidates : candidates.entrySet()) { + result.put(competitorAndCandidates.getKey(), new CompetitorStats( + competitorAndCandidates.getValue().size(), 0, 0, getNumberOfEdges(competitorAndCandidates.getKey()))); // TODO bug4221 populate with filter stage results + } + return result; + } + + private int getNumberOfEdges(Competitor competitor) { + int result = 0; + for (final Set edgeSet : allEdges.get(competitor).values()) { + result += edgeSet.size(); + } + return result; + } + } public CandidateChooserImpl(DynamicTrackedRace race) { this.perCompetitorLocks = new HashMap<>(); @@ -199,6 +282,10 @@ public class CandidateChooserImpl implements CandidateChooser { addCandidates(c, startAndEnd); } } + + public Stats getStats() { + return new Stats(); + } private NamedReentrantReadWriteLock createCompetitorLock(Competitor c) { return new NamedReentrantReadWriteLock("Competitor lock for "+c+" in candidate chooser "+this, /* fair */ false); diff --git a/java/com.sap.sailing.feature.p2build/scripts/analyzeProduct.sh b/java/com.sap.sailing.feature.p2build/scripts/analyzeProduct.sh index d3ab87e0542..1712f28b0d5 100755 --- a/java/com.sap.sailing.feature.p2build/scripts/analyzeProduct.sh +++ b/java/com.sap.sailing.feature.p2build/scripts/analyzeProduct.sh @@ -5,6 +5,9 @@ # # If one or more launch configuration files are provided as the remaining arguments, they will be patched in-place by # replacing the workspace_bundles and target_bundles string attributes by those generated by this script. +# If the launch configuration's name contains the sub-string winddbTest, the additional bundle +# ,com.sap.sailing.server.gateway.test.support@default:default +# is added to the workspace-bundles string. # The product consists of the features and plugins it lists. Its section overrides # the startLevel and autoStart defaults (4 / false) for a subset of the bundle list obtained from @@ -66,7 +69,12 @@ echo " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/com.sap.sailing.gwt.ui/GWT Sailing SDM.launch b/java/com.sap.sailing.gwt.ui/GWT Sailing SDM.launch index ee47fd9be8a..05821f7f895 100644 --- a/java/com.sap.sailing.gwt.ui/GWT Sailing SDM.launch +++ b/java/com.sap.sailing.gwt.ui/GWT Sailing SDM.launch @@ -1,123 +1,123 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889).launch old mode 100644 new mode 100755 diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, Cached MTB).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, Cached MTB).launch old mode 100644 new mode 100755 diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate dev).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate dev).launch old mode 100644 new mode 100755 diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8890).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8890).launch old mode 100644 new mode 100755 diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch old mode 100644 new mode 100755 index 53bc8054909..f2980a9076d --- a/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch +++ b/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch @@ -29,7 +29,7 @@ - + diff --git a/java/com.sap.sailing.server/SailingServer (Proxy, winddbTest).launch b/java/com.sap.sailing.server/SailingServer (Proxy, winddbTest).launch old mode 100644 new mode 100755 index 3fe5799ede1..7a56af3a36c --- a/java/com.sap.sailing.server/SailingServer (Proxy, winddbTest).launch +++ b/java/com.sap.sailing.server/SailingServer (Proxy, winddbTest).launch @@ -24,7 +24,7 @@ - + diff --git a/java/com.sap.sse.feature/feature.xml b/java/com.sap.sse.feature/feature.xml index c26ffd7b1cd..57a10d01e16 100644 --- a/java/com.sap.sse.feature/feature.xml +++ b/java/com.sap.sse.feature/feature.xml @@ -213,4 +213,12 @@ Computes leaderboard information for sailing races and offers RESTful APIs to al version="0.0.0" unpack="false"/> + + diff --git a/java/com.sap.sse.jettyextensions/.classpath b/java/com.sap.sse.jettyextensions/.classpath new file mode 100755 index 00000000000..eca7bdba8f0 --- /dev/null +++ b/java/com.sap.sse.jettyextensions/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/java/com.sap.sse.jettyextensions/.project b/java/com.sap.sse.jettyextensions/.project new file mode 100755 index 00000000000..a895d460939 --- /dev/null +++ b/java/com.sap.sse.jettyextensions/.project @@ -0,0 +1,28 @@ + + + com.sap.sse.jettyextensions + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/java/com.sap.sse.jettyextensions/.settings/org.eclipse.jdt.core.prefs b/java/com.sap.sse.jettyextensions/.settings/org.eclipse.jdt.core.prefs new file mode 100755 index 00000000000..0c68a61dca8 --- /dev/null +++ b/java/com.sap.sse.jettyextensions/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/java/com.sap.sse.jettyextensions/.settings/org.eclipse.pde.core.prefs b/java/com.sap.sse.jettyextensions/.settings/org.eclipse.pde.core.prefs new file mode 100755 index 00000000000..f29e940a005 --- /dev/null +++ b/java/com.sap.sse.jettyextensions/.settings/org.eclipse.pde.core.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +pluginProject.extensions=false +resolve.requirebundle=false diff --git a/java/com.sap.sse.jettyextensions/META-INF/MANIFEST.MF b/java/com.sap.sse.jettyextensions/META-INF/MANIFEST.MF new file mode 100755 index 00000000000..80c86d3b80d --- /dev/null +++ b/java/com.sap.sse.jettyextensions/META-INF/MANIFEST.MF @@ -0,0 +1,9 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Jettyextensions +Bundle-SymbolicName: com.sap.sse.jettyextensions +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: SAP +Fragment-Host: org.eclipse.jetty.osgi.boot +Automatic-Module-Name: com.sap.sse.jettyextensions +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 diff --git a/java/com.sap.sse.jettyextensions/build.properties b/java/com.sap.sse.jettyextensions/build.properties new file mode 100755 index 00000000000..34d2e4d2dad --- /dev/null +++ b/java/com.sap.sse.jettyextensions/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/java/com.sap.sse.jettyextensions/pom.xml b/java/com.sap.sse.jettyextensions/pom.xml new file mode 100755 index 00000000000..68862c9ec80 --- /dev/null +++ b/java/com.sap.sse.jettyextensions/pom.xml @@ -0,0 +1,12 @@ + + + 4.0.0 + + root + com.sap.sailing + 1.0.0-SNAPSHOT + + com.sap.sse.jettyextensions + eclipse-plugin + diff --git a/java/com.sap.sse.jettyextensions/src/com/sap/sse/jettyextensions/SynchronizedContextHandlerCollection.java b/java/com.sap.sse.jettyextensions/src/com/sap/sse/jettyextensions/SynchronizedContextHandlerCollection.java new file mode 100755 index 00000000000..da671bda20c --- /dev/null +++ b/java/com.sap.sse.jettyextensions/src/com/sap/sse/jettyextensions/SynchronizedContextHandlerCollection.java @@ -0,0 +1,30 @@ +package com.sap.sse.jettyextensions; + +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.handler.ContextHandlerCollection; + +public class SynchronizedContextHandlerCollection extends ContextHandlerCollection { + public SynchronizedContextHandlerCollection() { + super(); + } + + @Override + public synchronized void setHandlers(Handler[] handlers) { + super.setHandlers(handlers); + } + + @Override + public synchronized void addHandler(Handler handler) { + super.addHandler(handler); + } + + @Override + public synchronized void prependHandler(Handler handler) { + super.prependHandler(handler); + } + + @Override + public synchronized void removeHandler(Handler handler) { + super.removeHandler(handler); + } +} diff --git a/java/com.sap.sse.jettyextensions/src/com/sap/sse/jettyextensions/SynchronizedHandlerCollection.java b/java/com.sap.sse.jettyextensions/src/com/sap/sse/jettyextensions/SynchronizedHandlerCollection.java new file mode 100755 index 00000000000..d233df78530 --- /dev/null +++ b/java/com.sap.sse.jettyextensions/src/com/sap/sse/jettyextensions/SynchronizedHandlerCollection.java @@ -0,0 +1,30 @@ +package com.sap.sse.jettyextensions; + +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.handler.HandlerCollection; + +public class SynchronizedHandlerCollection extends HandlerCollection { + public SynchronizedHandlerCollection() { + super(); + } + + @Override + public synchronized void setHandlers(Handler[] handlers) { + super.setHandlers(handlers); + } + + @Override + public synchronized void addHandler(Handler handler) { + super.addHandler(handler); + } + + @Override + public synchronized void prependHandler(Handler handler) { + super.prependHandler(handler); + } + + @Override + public synchronized void removeHandler(Handler handler) { + super.removeHandler(handler); + } +} diff --git a/java/com.sap.sse.security.ui/GWT Security DevMode.launch b/java/com.sap.sse.security.ui/GWT Security DevMode.launch index 8154a68dd9d..18e9479fd03 100644 --- a/java/com.sap.sse.security.ui/GWT Security DevMode.launch +++ b/java/com.sap.sse.security.ui/GWT Security DevMode.launch @@ -1,111 +1,111 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/com.sap.sse.security.ui/GWT Security SDM.launch b/java/com.sap.sse.security.ui/GWT Security SDM.launch index ff427d4bdfb..9f8f649e5d0 100644 --- a/java/com.sap.sse.security.ui/GWT Security SDM.launch +++ b/java/com.sap.sse.security.ui/GWT Security SDM.launch @@ -1,111 +1,111 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/pom.xml b/java/pom.xml index 35188b5e848..7a25e9c63bd 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -45,7 +45,7 @@ -Dfile.encoding=cp1252 -Dmongo.dbName=winddbTest -DspatialWind=true - -ea -Xmx1024m -XX:+UseG1GC + -ea -Xmx8096m -XX:+UseG1GC -Dtractrac.tunnel=true -Dtractrac.tunnel.host=localhost @@ -80,6 +80,7 @@ com.sap.sse com.sap.sse.test com.sap.sse.jersey.jaxbdependencyfragment + com.sap.sse.jettyextensions com.sap.sailing.routeconverterjava11extension com.sap.sse.mail com.sap.sse.mail.replication.test diff --git a/java/target/configuration/jetty/etc/jetty.xml b/java/target/configuration/jetty/etc/jetty.xml index dd974933547..e6cbb54fd8b 100644 --- a/java/target/configuration/jetty/etc/jetty.xml +++ b/java/target/configuration/jetty/etc/jetty.xml @@ -91,11 +91,17 @@ + + - + +