Merge branch 'main' into hyperspace

This commit is contained in:
Axel Uhl committed 2024-08-28 13:23:14 +02:00
commit 1e9875b7a9
11 files changed
+51 -17

No files matched your search

@@ -273,4 +273,5 @@ SmoothedSpeed=Smoothed Speed
RatioDistanceLongVsShortTack=Ratio distance long tack / short tack
RatioDurationLongVsShortTack=Ratio duration long tack / short tack
Discarded=Discarded
DurationFromRaceStartToFirstTack=Duration from race start to first tack
DurationFromRaceStartToFirstTack=Duration from race start to first tack
TypeOfFirstLeg=Type of first leg
@@ -271,4 +271,5 @@ SmoothedSpeed=Geglättete Geschwindigkeit
RatioDistanceLongVsShortTack=Verhältnis gesegelte Distanz auf Streck- zu Holebug
RatioDurationLongVsShortTack=Verhältnis gesegelte Dauer auf Streck- zu Holebug
Discarded=Gestrichen
DurationFromRaceStartToFirstTack=Dauer vom Start der Wettfahrt bis zur ersten Wende
DurationFromRaceStartToFirstTack=Dauer vom Start der Wettfahrt bis zur ersten Wende
TypeOfFirstLeg=Art des ersten Bahnschenkels
@@ -6,7 +6,9 @@ import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.common.LegType;
import com.sap.sailing.domain.common.NauticalSide;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sse.common.Bearing;
import com.sap.sse.common.Distance;
@@ -87,6 +89,9 @@ public interface HasTrackedRaceContext {
@Dimension(messageKey="Day")
public String getDayAsISO();
@Dimension(messageKey="TypeOfFirstLeg")
public LegType getTypeOfFirstLeg() throws NoWindException;
// Convenience methods for race dependent calculation to avoid code duplication
public Double getRelativeScoreForCompetitor(Competitor competitor);
@@ -4,6 +4,7 @@ import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;
@@ -19,18 +20,23 @@ import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState;
import com.sap.sailing.domain.abstractlog.race.state.impl.ReadonlyRaceStateImpl;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Course;
import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.DomainFactory;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.Leg;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.common.LegType;
import com.sap.sailing.domain.common.NauticalSide;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.common.WindSourceType;
import com.sap.sailing.domain.tracking.LineDetails;
import com.sap.sailing.domain.tracking.Track;
import com.sap.sailing.domain.tracking.TrackedLeg;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.geocoding.ReverseGeocoder;
import com.sap.sse.common.Bearing;
@@ -473,4 +479,29 @@ public class TrackedRaceWithContext implements HasTrackedRaceContext {
}
return cachedDayAsISO;
}
@Override
public LegType getTypeOfFirstLeg() throws NoWindException {
final LegType result;
final TimePoint startOfRace = getTrackedRace().getStartOfRace();
if (startOfRace == null) {
result = null;
} else {
final Course course = getTrackedRace().getRace().getCourse();
final List<Leg> legs = course.getLegs();
if (legs.isEmpty()) {
result = null;
} else {
final TrackedLeg firstTrackedLeg = getTrackedRace().getTrackedLeg(legs.get(0));
if (firstTrackedLeg == null) {
result = null;
} else {
result = firstTrackedLeg.getLegType(startOfRace);
}
}
}
return result;
}
}
@@ -113,8 +113,7 @@ public class MetadataCollection extends MongoFixHandler {
return result;
}
long getNumberOfFixes(DeviceIdentifier device)
throws TransformationException, NoCorrespondingServiceRegisteredException {
long getNumberOfFixes(DeviceIdentifier device) throws TransformationException, NoCorrespondingServiceRegisteredException {
final Document resultDocument = findMetadataObject(device);
final long result;
if (resultDocument == null) {
@@ -46,12 +46,10 @@ public class SensorFixStoreTest {
protected final DeviceIdentifier device2 = new SmartphoneImeiIdentifier("b");
protected SensorFixStore store;
private ClientSession clientSession;
private ClientSession metadataCollectionClientSession;
@Before
public void setUp() throws UnknownHostException, MongoException {
clientSession = MongoDBService.INSTANCE.startCausallyConsistentSession();
metadataCollectionClientSession = MongoDBService.INSTANCE.startCausallyConsistentSession();
dropPersistedData();
newStore();
}
@@ -59,7 +57,7 @@ public class SensorFixStoreTest {
private void newStore() {
store = new MongoSensorFixStoreImpl(PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory(),
PersistenceFactory.INSTANCE.getDefaultDomainObjectFactory(), serviceFinderFactory, ReadConcern.MAJORITY,
WriteConcern.MAJORITY, clientSession, metadataCollectionClientSession);
WriteConcern.MAJORITY, clientSession, clientSession);
}
@After
@@ -70,7 +68,7 @@ public class SensorFixStoreTest {
private void dropPersistedData() {
MongoDatabase db = PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory().getDatabase();
db.getCollection(CollectionNames.GPS_FIXES.name()).withWriteConcern(WriteConcern.MAJORITY).drop(clientSession);
db.getCollection(CollectionNames.GPS_FIXES_METADATA.name()).withWriteConcern(WriteConcern.MAJORITY).drop(metadataCollectionClientSession);
db.getCollection(CollectionNames.GPS_FIXES_METADATA.name()).withWriteConcern(WriteConcern.MAJORITY).drop(clientSession);
}
@Test
@@ -13,6 +13,8 @@
lines or course middle lines) from showing when hovering the mouse over them.</li>
<li>In Data Mining, race results now have a new dimension "Discarded" for grouping and filtering.</li>
<li>Races of competitors now have a new statistic in Data Mining: duration since start to first tack.</li>
<li>New data mining dimension for races: type of first leg. This way, races can be filtered or results can
be grouped by whether a race's first leg is an upwind, reaching or downwind leg.</li>
</ul>
<h5 class="articleSubheadline">July 2024</h5>
<ul class="bulletList">
@@ -130,10 +130,9 @@ public class TestAbortingHeavyLoadQuery {
query.abort();
QueryResult<HashSet<Integer>> result = queryTask.get();
// The query execution returned, so all processors are aborted (checked below).
// The query execution returned, so all processors have received the abort signal (checked below).
// The number of unfinished instructions mustn't change after this point
int unfinishedInstructionsCount = unfinishedInstructions.size();
boolean unfinishedInstructionWasFinished = false;
Set<StatefulProcessorInstruction<?>> runningInstructions = new HashSet<>();
Set<StatefulProcessorInstruction<?>> notStartedInstructions = new HashSet<>();
for (StatefulProcessorInstruction<?> instruction : unfinishedInstructions) {
@@ -142,13 +141,11 @@ public class TestAbortingHeavyLoadQuery {
} else {
notStartedInstructions.add(instruction);
}
unfinishedInstructionWasFinished |= instruction.computeResultWasFinished();
}
logExecution(unfinishedInstructionsCount + " unfinished instructions left - " +
runningInstructions.size() + " running, " + notStartedInstructions.size() + " not started");
printExecutionRecord();
assertThat("Number of unfinished instructions changed", runningInstructions.size() + notStartedInstructions.size(), is(unfinishedInstructionsCount));
assertFalse("Unfinished instructions expected, but at least one was completed", unfinishedInstructionWasFinished);
// Checking query, result and processor chain state
assertThat(query.getState(), is(QueryState.ABORTED));
@@ -365,7 +362,9 @@ public class TestAbortingHeavyLoadQuery {
@Override
public void afterInstructionFinished(ProcessorInstruction<Element> instruction) {
super.afterInstructionFinished(instruction);
if(canProcessElements()) unfinishedInstructions.remove(instruction);
if (canProcessElements()) {
unfinishedInstructions.remove(instruction);
}
}
};
Processor<Iterable<String>, String> retriever0 = new AbstractRetrievalProcessor<Iterable<String>, String>(dataSourceType, String.class, executor, Collections.singleton(retriever1), 0, "") {
@@ -46,7 +46,7 @@ public class StatefulBlockingInstruction<ResultType> extends StatefulProcessorIn
}
return result;
}
protected void actionBeforeBlock() { }
protected void actionBeforeAbort() { }
protected void actionAfterBlock() { }
@@ -58,5 +58,4 @@ public class StatefulBlockingInstruction<ResultType> extends StatefulProcessorIn
public boolean computeResultWasAborted() {
return computeResultWasAborted;
}
}
@@ -50,5 +50,4 @@ public abstract class StatefulProcessorInstruction<ResultType> extends AbstractP
public boolean computeResultWasFinished() {
return computeResultWasFinished;
}
}
@@ -224,7 +224,7 @@ public abstract class ProcessorQuery<ResultType, DataSourceType> implements Quer
public void abort() {
synchronized (monitorObject) {
LOGGER.log(Level.INFO, "Aborting the query processing");
state = QueryState.ABORTED;
state = state == QueryState.RUNNING || state == QueryState.NOT_STARTED ? QueryState.ABORTED : state;
monitorObject.notify();
}
}