mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-14 22:43:57 +00:00
Merge branch 'main' into hyperspace
This commit is contained in:
commit
1e9875b7a9
11 files changed
+51
-17
No files matched your search
+2
-1
@@ -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
|
||||
+2
-1
@@ -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
|
||||
+5
@@ -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);
|
||||
|
||||
+31
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+1
-2
@@ -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) {
|
||||
|
||||
+2
-4
@@ -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
|
||||
|
||||
+2
@@ -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">
|
||||
|
||||
+4
-5
@@ -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, "") {
|
||||
|
||||
+1
-2
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
-1
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user