mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-22 03:53:56 +00:00
bridged the gap between device mapping events where "to" is inclusive, and TimeRange, where "to" is exclusive; TimePoint.plus|minus no longer wraps around but bumps
Change-Id: I97f30deb38d83872879c33971616bfcf18a5469a
This commit is contained in:
1 parent
da9e5d20b3
commit
d4479a3bc1
17 files changed
+121
-46
No files matched your search
+3
-3
@@ -970,8 +970,8 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
|||||||
if (event.getFrom() != null) {
|
if (event.getFrom() != null) {
|
||||||
storeTimePoint(event.getFrom(), result, fromField);
|
storeTimePoint(event.getFrom(), result, fromField);
|
||||||
}
|
}
|
||||||
if (event.getTo() != null) {
|
if (event.getToInclusive() != null) {
|
||||||
storeTimePoint(event.getTo(), result, toField);
|
storeTimePoint(event.getToInclusive(), result, toField);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1440,7 +1440,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
|||||||
DBObject result = createBasicRegattaLogEventDBObject(event);
|
DBObject result = createBasicRegattaLogEventDBObject(event);
|
||||||
result.put(FieldNames.REGATTA_LOG_EVENT_CLASS.name(), RegattaLogCloseOpenEndedDeviceMappingEvent.class.getSimpleName());
|
result.put(FieldNames.REGATTA_LOG_EVENT_CLASS.name(), RegattaLogCloseOpenEndedDeviceMappingEvent.class.getSimpleName());
|
||||||
result.put(FieldNames.REGATTA_LOG_DEVICE_MAPPING_EVENT_ID.name(), event.getDeviceMappingEventId());
|
result.put(FieldNames.REGATTA_LOG_DEVICE_MAPPING_EVENT_ID.name(), event.getDeviceMappingEventId());
|
||||||
storeTimePoint(event.getClosingTimePoint(), result, FieldNames.REGATTA_LOG_CLOSING_TIMEPOINT);
|
storeTimePoint(event.getClosingTimePointInclusive(), result, FieldNames.REGATTA_LOG_CLOSING_TIMEPOINT);
|
||||||
storeRegattaLogEvent(regattaLikeId, result);
|
storeRegattaLogEvent(regattaLikeId, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-2
@@ -7,7 +7,7 @@ import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent;
|
|||||||
import com.sap.sse.common.TimePoint;
|
import com.sap.sse.common.TimePoint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the time range of a {@link RegattaLogDeviceMappingEvent}. This means that the {@link #getClosingTimePoint() timepoint} provided
|
* Closes the time range of a {@link RegattaLogDeviceMappingEvent}. This means that the {@link #getClosingTimePointInclusive() timepoint} provided
|
||||||
* by this event is substituted for the missing timepoint in the {@code DeviceMappingEvent} it refers to.
|
* by this event is substituted for the missing timepoint in the {@code DeviceMappingEvent} it refers to.
|
||||||
* @author Fredrik Teschke
|
* @author Fredrik Teschke
|
||||||
*
|
*
|
||||||
@@ -15,8 +15,10 @@ import com.sap.sse.common.TimePoint;
|
|||||||
public interface RegattaLogCloseOpenEndedDeviceMappingEvent extends RegattaLogEvent, Revokable {
|
public interface RegattaLogCloseOpenEndedDeviceMappingEvent extends RegattaLogEvent, Revokable {
|
||||||
/**
|
/**
|
||||||
* Returns the timepoint that shall substitute the missing one in the corresponding {@link RegattaLogDeviceMappingEvent}.
|
* Returns the timepoint that shall substitute the missing one in the corresponding {@link RegattaLogDeviceMappingEvent}.
|
||||||
|
* As with {@link RegattaLogDeviceMappingEvent#getToInclusive()}, this time point marks the <em>inclusive</em> end
|
||||||
|
* of the interval.
|
||||||
*/
|
*/
|
||||||
TimePoint getClosingTimePoint();
|
TimePoint getClosingTimePointInclusive();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@code id} of the event for which this event provides the closing timepoint.
|
* Returns the {@code id} of the event for which this event provides the closing timepoint.
|
||||||
|
|||||||
+9
-4
@@ -9,15 +9,16 @@ import com.sap.sailing.domain.base.Mark;
|
|||||||
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
||||||
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
|
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
|
||||||
import com.sap.sse.common.TimePoint;
|
import com.sap.sse.common.TimePoint;
|
||||||
|
import com.sap.sse.common.TimeRange;
|
||||||
import com.sap.sse.common.WithID;
|
import com.sap.sse.common.WithID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event type for mapping {@link DeviceIdentifier devices} to {@code items} ({@link Competitor competitors} or {@link Mark marks}).
|
* Event type for mapping {@link DeviceIdentifier devices} to {@code items} ({@link Competitor competitors} or {@link Mark marks}).
|
||||||
* <p>
|
* <p>
|
||||||
* Not both {@link #getFrom()} and {@link #getTo()} may be {@code null} at the same time (which would be a mapping for "all times",
|
* Not both {@link #getFrom()} and {@link #getToInclusive()} may be {@code null} at the same time (which would be a mapping for "all times",
|
||||||
* as the semantics of somehow later limiting this range would become unclear
|
* as the semantics of somehow later limiting this range would become unclear
|
||||||
* <p>
|
* <p>
|
||||||
* If one end of the time range enclosed by {@link #getFrom()} and {@link #getTo()} is open, this can be closed
|
* If one end of the time range enclosed by {@link #getFrom()} and {@link #getToInclusive()} is open, this can be closed
|
||||||
* by a {@link RegattaLogCloseOpenEndedDeviceMappingEvent}.
|
* by a {@link RegattaLogCloseOpenEndedDeviceMappingEvent}.
|
||||||
*
|
*
|
||||||
* @see RegattaLogDefinedMarkAnalyzer for rules by which {@link DeviceMapping}s are derived from these events.
|
* @see RegattaLogDefinedMarkAnalyzer for rules by which {@link DeviceMapping}s are derived from these events.
|
||||||
@@ -29,15 +30,19 @@ public interface RegattaLogDeviceMappingEvent<ItemType extends WithID> extends R
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@code return} value may be {@code null}, symbolizing an open range.
|
* The {@code return} value may be {@code null}, symbolizing an open range.
|
||||||
* In that case the device should be mapped to the item for any timepoint before that specified by {@link #getTo()}.
|
* In that case the device should be mapped to the item for any timepoint before that specified by {@link #getToInclusive()}.
|
||||||
*/
|
*/
|
||||||
TimePoint getFrom();
|
TimePoint getFrom();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@code return} value may be {@code null}, symbolizing an open range.
|
* The {@code return} value may be {@code null}, symbolizing an open range.
|
||||||
* In that case the device should be mapped to the item for any timepoint after that specified by {@link #getFrom()}.
|
* In that case the device should be mapped to the item for any timepoint after that specified by {@link #getFrom()}.
|
||||||
|
* Otherwise, this marks the <em>inclusive</em> end of the interval, other than the {@link TimeRange#to()} semantics which
|
||||||
|
* uses an <em>exclusive</em> interval end. To bridge this gap, whenever mapping this event's from/to interval to a
|
||||||
|
* {@link TimeRange}, at least the resolution of the {@link TimePoint} representation must be added to the result of
|
||||||
|
* this method to make it into a valid end of a {@link TimeRange} that includes the time interval covered by this mapping.
|
||||||
*/
|
*/
|
||||||
TimePoint getTo();
|
TimePoint getToInclusive();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Visitor patter implementation for event mapping handling differentiation.
|
* Visitor patter implementation for event mapping handling differentiation.
|
||||||
|
|||||||
+20
-8
@@ -15,23 +15,35 @@ RegattaLogDeviceMappingEvent<ItemType> {
|
|||||||
|
|
||||||
private final ItemType mappedTo;
|
private final ItemType mappedTo;
|
||||||
private final DeviceIdentifier device;
|
private final DeviceIdentifier device;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* inclusive start time point
|
||||||
|
*/
|
||||||
private final TimePoint from;
|
private final TimePoint from;
|
||||||
private final TimePoint to;
|
|
||||||
|
/**
|
||||||
|
* inclusive end time point
|
||||||
|
*/
|
||||||
|
private final TimePoint toInclusive;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param from inclusive
|
||||||
|
* @param toInclusive inclusive
|
||||||
|
*/
|
||||||
public RegattaLogDeviceMappingEventImpl(TimePoint createdAt, TimePoint logicalTimePoint,
|
public RegattaLogDeviceMappingEventImpl(TimePoint createdAt, TimePoint logicalTimePoint,
|
||||||
AbstractLogEventAuthor author, Serializable id, ItemType mappedTo,
|
AbstractLogEventAuthor author, Serializable id, ItemType mappedTo,
|
||||||
DeviceIdentifier device, TimePoint from, TimePoint to) {
|
DeviceIdentifier device, TimePoint from, TimePoint toInclusive) {
|
||||||
super(createdAt, logicalTimePoint, author, id);
|
super(createdAt, logicalTimePoint, author, id);
|
||||||
this.mappedTo = mappedTo;
|
this.mappedTo = mappedTo;
|
||||||
this.device = device;
|
this.device = device;
|
||||||
this.from = from;
|
this.from = from;
|
||||||
this.to = to;
|
this.toInclusive = toInclusive;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegattaLogDeviceMappingEventImpl(TimePoint logicalTimePoint,
|
public RegattaLogDeviceMappingEventImpl(TimePoint logicalTimePoint,
|
||||||
AbstractLogEventAuthor author, ItemType mappedTo,
|
AbstractLogEventAuthor author, ItemType mappedTo,
|
||||||
DeviceIdentifier device, TimePoint from, TimePoint to) {
|
DeviceIdentifier device, TimePoint from, TimePoint toInclusive) {
|
||||||
this(now(), logicalTimePoint, author, randId(), mappedTo, device, from, to);
|
this(now(), logicalTimePoint, author, randId(), mappedTo, device, from, toInclusive);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemType getMappedTo() {
|
public ItemType getMappedTo() {
|
||||||
@@ -43,12 +55,12 @@ RegattaLogDeviceMappingEvent<ItemType> {
|
|||||||
public TimePoint getFrom() {
|
public TimePoint getFrom() {
|
||||||
return from;
|
return from;
|
||||||
}
|
}
|
||||||
public TimePoint getTo() {
|
public TimePoint getToInclusive() {
|
||||||
return to;
|
return toInclusive;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getShortInfo() {
|
public String getShortInfo() {
|
||||||
return "device: " + device + ", mapped to: " + mappedTo + ", from: " + from + ", to: " + to;
|
return "device: " + device + ", mapped to: " + mappedTo + ", from: " + from + ", to: " + toInclusive;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -33,7 +33,7 @@ public class RegattaLogCloseOpenEndedDeviceMappingEventImpl extends AbstractLogE
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TimePoint getClosingTimePoint() {
|
public TimePoint getClosingTimePointInclusive() {
|
||||||
return closingTimePoint;
|
return closingTimePoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -15,13 +15,13 @@ public class RegattaLogDeviceCompetitorMappingEventImpl extends RegattaLogDevice
|
|||||||
RegattaLogDeviceCompetitorMappingEvent {
|
RegattaLogDeviceCompetitorMappingEvent {
|
||||||
public RegattaLogDeviceCompetitorMappingEventImpl(TimePoint createdAt, TimePoint logicalTimePoint,
|
public RegattaLogDeviceCompetitorMappingEventImpl(TimePoint createdAt, TimePoint logicalTimePoint,
|
||||||
AbstractLogEventAuthor author, Serializable pId, Competitor mappedTo, DeviceIdentifier device,
|
AbstractLogEventAuthor author, Serializable pId, Competitor mappedTo, DeviceIdentifier device,
|
||||||
TimePoint from, TimePoint to) {
|
TimePoint from, TimePoint toInclusive) {
|
||||||
super(createdAt, logicalTimePoint, author, pId, mappedTo, device, from, to);
|
super(createdAt, logicalTimePoint, author, pId, mappedTo, device, from, toInclusive);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegattaLogDeviceCompetitorMappingEventImpl(TimePoint logicalTimePoint, AbstractLogEventAuthor author,
|
public RegattaLogDeviceCompetitorMappingEventImpl(TimePoint logicalTimePoint, AbstractLogEventAuthor author,
|
||||||
Competitor mappedTo, DeviceIdentifier device, TimePoint from, TimePoint to) {
|
Competitor mappedTo, DeviceIdentifier device, TimePoint from, TimePoint toInclusive) {
|
||||||
super(logicalTimePoint, author, mappedTo, device, from, to);
|
super(logicalTimePoint, author, mappedTo, device, from, toInclusive);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final long serialVersionUID = -1494030544804758753L;
|
private static final long serialVersionUID = -1494030544804758753L;
|
||||||
|
|||||||
+5
-5
@@ -51,8 +51,8 @@ public abstract class BaseRegattaLogDeviceMappingFinder<ItemT extends WithID>
|
|||||||
for (final RegattaLogDeviceMappingEvent<ItemT> event : events.get(item)) {
|
for (final RegattaLogDeviceMappingEvent<ItemT> event : events.get(item)) {
|
||||||
final TimePoint from = event.getFrom();
|
final TimePoint from = event.getFrom();
|
||||||
final RegattaLogCloseOpenEndedDeviceMappingEvent closingEvent = closingEvents.get(event.getId());
|
final RegattaLogCloseOpenEndedDeviceMappingEvent closingEvent = closingEvents.get(event.getId());
|
||||||
final TimePoint to = closingEvent != null ? closingEvent.getClosingTimePoint() : event.getTo();
|
final TimePoint toInclusive = closingEvent != null ? closingEvent.getClosingTimePointInclusive() : event.getToInclusive();
|
||||||
final TimeRange mappingTimeRange = new TimeRangeImpl(from, to);
|
final TimeRange mappingTimeRange = new TimeRangeImpl(from, toInclusive.plus(1) /* convert from inclusive to exclusive end */);
|
||||||
if (mappingTimeRange.includes(fixTimePoint)) {
|
if (mappingTimeRange.includes(fixTimePoint)) {
|
||||||
if (closingEvent != null) {
|
if (closingEvent != null) {
|
||||||
log.revokeEvent(closingEvent.getAuthor(), closingEvent,
|
log.revokeEvent(closingEvent.getAuthor(), closingEvent,
|
||||||
@@ -65,8 +65,8 @@ public abstract class BaseRegattaLogDeviceMappingFinder<ItemT extends WithID>
|
|||||||
if (!endOfFirstHalf.before(from)) {
|
if (!endOfFirstHalf.before(from)) {
|
||||||
log.add(createDeviceMappingEvent(item, event.getAuthor(), from, endOfFirstHalf, event.getDevice()));
|
log.add(createDeviceMappingEvent(item, event.getAuthor(), from, endOfFirstHalf, event.getDevice()));
|
||||||
}
|
}
|
||||||
if (to == null || !to.before(startOfSecondHalf)) {
|
if (toInclusive == null || !toInclusive.before(startOfSecondHalf)) {
|
||||||
log.add(createDeviceMappingEvent(item, event.getAuthor(), startOfSecondHalf, to,
|
log.add(createDeviceMappingEvent(item, event.getAuthor(), startOfSecondHalf, toInclusive,
|
||||||
event.getDevice()));
|
event.getDevice()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,6 +74,6 @@ public abstract class BaseRegattaLogDeviceMappingFinder<ItemT extends WithID>
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected abstract RegattaLogDeviceMappingEvent<ItemT> createDeviceMappingEvent(ItemT item,
|
protected abstract RegattaLogDeviceMappingEvent<ItemT> createDeviceMappingEvent(ItemT item,
|
||||||
AbstractLogEventAuthor author, TimePoint plus, TimePoint to, DeviceIdentifier deviceId);
|
AbstractLogEventAuthor author, TimePoint plus, TimePoint toInclusive, DeviceIdentifier deviceId);
|
||||||
|
|
||||||
}
|
}
|
||||||
+2
-2
@@ -25,8 +25,8 @@ public class RegattaLogDeviceCompetitorMappingFinder extends BaseRegattaLogDevic
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RegattaLogDeviceCompetitorMappingEvent createDeviceMappingEvent(Competitor item, AbstractLogEventAuthor author,
|
protected RegattaLogDeviceCompetitorMappingEvent createDeviceMappingEvent(Competitor item, AbstractLogEventAuthor author,
|
||||||
TimePoint from, TimePoint to, DeviceIdentifier deviceId) {
|
TimePoint from, TimePoint toInclusive, DeviceIdentifier deviceId) {
|
||||||
final TimePoint now = MillisecondsTimePoint.now();
|
final TimePoint now = MillisecondsTimePoint.now();
|
||||||
return new RegattaLogDeviceCompetitorMappingEventImpl(now, now, author, UUID.randomUUID(), item, deviceId, from, to);
|
return new RegattaLogDeviceCompetitorMappingEventImpl(now, now, author, UUID.randomUUID(), item, deviceId, from, toInclusive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+7
-7
@@ -48,8 +48,8 @@ public class RegattaLogDeviceMappingFinder<ItemT extends WithID>
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected DeviceMappingWithRegattaLogEvent<ItemT> createMapping(DeviceIdentifier device, ItemT item,
|
protected DeviceMappingWithRegattaLogEvent<ItemT> createMapping(DeviceIdentifier device, ItemT item,
|
||||||
TimePoint from, TimePoint to, Serializable originalEventId, RegattaLogDeviceMappingEvent<ItemT> event) {
|
TimePoint from, TimePoint toInclusive, Serializable originalEventId, RegattaLogDeviceMappingEvent<ItemT> event) {
|
||||||
return new DeviceMappingWithRegattaLogEventImpl<ItemT>(item, device, new TimeRangeImpl(from, to),
|
return new DeviceMappingWithRegattaLogEventImpl<ItemT>(item, device, new TimeRangeImpl(from, toInclusive.plus(1) /* TimeRange uses exclusive end */),
|
||||||
Collections.singletonList(originalEventId), event);
|
Collections.singletonList(originalEventId), event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,16 +95,16 @@ public class RegattaLogDeviceMappingFinder<ItemT extends WithID>
|
|||||||
List<DeviceMappingWithRegattaLogEvent<ItemT>> result = new ArrayList<>();
|
List<DeviceMappingWithRegattaLogEvent<ItemT>> result = new ArrayList<>();
|
||||||
for (final RegattaLogDeviceMappingEvent<ItemT> event : events) {
|
for (final RegattaLogDeviceMappingEvent<ItemT> event : events) {
|
||||||
TimePoint from = event.getFrom();
|
TimePoint from = event.getFrom();
|
||||||
TimePoint to = event.getTo();
|
TimePoint toInclusive = event.getToInclusive();
|
||||||
TimePoint closingTimePoint = closingEvents.containsKey(event.getId()) ? closingEvents.get(event.getId())
|
TimePoint closingTimePoint = closingEvents.containsKey(event.getId()) ? closingEvents.get(event.getId())
|
||||||
.getClosingTimePoint() : null;
|
.getClosingTimePointInclusive() : null;
|
||||||
if (from == null) {
|
if (from == null) {
|
||||||
logger.severe("No start time set for DeviceMappingEvent with ID: " + event.getId());
|
logger.severe("No start time set for DeviceMappingEvent with ID: " + event.getId());
|
||||||
}
|
}
|
||||||
if (to == null) {
|
if (toInclusive == null) {
|
||||||
to = closingTimePoint;
|
toInclusive = closingTimePoint;
|
||||||
}
|
}
|
||||||
result.add(createMapping(event.getDevice(), item, from, to, event.getId(), event));
|
result.add(createMapping(event.getDevice(), item, from, toInclusive, event.getId(), event));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -46,7 +46,7 @@ public class RegattaLogOpenEndedDeviceMappingCloser extends
|
|||||||
|
|
||||||
for (Serializable eventId : mapping.getOriginalRaceLogEventIds()) {
|
for (Serializable eventId : mapping.getOriginalRaceLogEventIds()) {
|
||||||
RegattaLogDeviceMappingEvent<?> event = (RegattaLogDeviceMappingEvent<?>) getLog().getEventById(eventId);
|
RegattaLogDeviceMappingEvent<?> event = (RegattaLogDeviceMappingEvent<?>) getLog().getEventById(eventId);
|
||||||
if (event.getFrom() == null || event.getTo() == null) {
|
if (event.getFrom() == null || event.getToInclusive() == null) {
|
||||||
result.add(createCloseEvent(MillisecondsTimePoint.now(), event.getId()));
|
result.add(createCloseEvent(MillisecondsTimePoint.now(), event.getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -66,7 +66,8 @@ public class DeviceMappingImpl<ItemType extends WithID> implements DeviceMapping
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends WithID> DeviceMapping<T> convertToDeviceMapping(RegattaLogDeviceMappingEvent<T> event) {
|
public static <T extends WithID> DeviceMapping<T> convertToDeviceMapping(RegattaLogDeviceMappingEvent<T> event) {
|
||||||
return new DeviceMappingImpl<T>(event.getMappedTo(), event.getDevice(), new TimeRangeImpl(event.getFrom(), event.getTo()),
|
return new DeviceMappingImpl<T>(event.getMappedTo(), event.getDevice(),
|
||||||
|
new TimeRangeImpl(event.getFrom(), event.getToInclusive().plus(1) /* TimeRange uses exclusive end */),
|
||||||
event.getId(), event.getClass());
|
event.getId(), event.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+24
-1
@@ -11,6 +11,7 @@ import java.util.GregorianCalendar;
|
|||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.sap.sse.common.Duration;
|
||||||
import com.sap.sse.common.TimePoint;
|
import com.sap.sse.common.TimePoint;
|
||||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||||
|
|
||||||
@@ -39,12 +40,34 @@ public class TimePointTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEqualForEuqal() {
|
public void testEqualForEqual() {
|
||||||
TimePoint t1 = new MillisecondsTimePoint(Long.MIN_VALUE);
|
TimePoint t1 = new MillisecondsTimePoint(Long.MIN_VALUE);
|
||||||
TimePoint t2 = new MillisecondsTimePoint(Long.MIN_VALUE);
|
TimePoint t2 = new MillisecondsTimePoint(Long.MIN_VALUE);
|
||||||
assertThat(t1, is(t2));
|
assertThat(t1, is(t2));
|
||||||
assertThat(t2, is(t1));
|
assertThat(t2, is(t1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAvoidOverflowBeyondEndOfTime() {
|
||||||
|
TimePoint t1 = TimePoint.EndOfTime;
|
||||||
|
assertEquals(TimePoint.EndOfTime, t1.plus(1));
|
||||||
|
assertEquals(TimePoint.EndOfTime, t1.plus(100));
|
||||||
|
assertEquals(TimePoint.EndOfTime, t1.plus(Duration.ONE_MINUTE));
|
||||||
|
TimePoint t2 = TimePoint.EndOfTime.minus(100);
|
||||||
|
assertEquals(TimePoint.EndOfTime, t2.plus(200));
|
||||||
|
assertEquals(TimePoint.EndOfTime, t2.plus(Duration.ONE_HOUR));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAvoidUnderflowBeyondBeginningOfTime() {
|
||||||
|
TimePoint t1 = TimePoint.BeginningOfTime;
|
||||||
|
assertEquals(TimePoint.BeginningOfTime, t1.minus(1));
|
||||||
|
assertEquals(TimePoint.BeginningOfTime, t1.minus(100));
|
||||||
|
assertEquals(TimePoint.BeginningOfTime, t1.minus(Duration.ONE_MINUTE));
|
||||||
|
TimePoint t2 = TimePoint.BeginningOfTime.plus(100);
|
||||||
|
assertEquals(TimePoint.BeginningOfTime, t2.minus(200));
|
||||||
|
assertEquals(TimePoint.BeginningOfTime, t2.minus(Duration.ONE_HOUR));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEqualForNull() {
|
public void testEqualForNull() {
|
||||||
|
|||||||
+1
-1
@@ -134,7 +134,7 @@ public class TopLevelMasterData implements Serializable {
|
|||||||
relevantFixes.put(device, new HashSet<>());
|
relevantFixes.put(device, new HashSet<>());
|
||||||
}
|
}
|
||||||
Set<Timed> fixes = relevantFixes.get(device);
|
Set<Timed> fixes = relevantFixes.get(device);
|
||||||
sensorFixStore.loadFixes(fixes::add, mappingEvent.getDevice(), mappingEvent.getFrom(), mappingEvent.getTo(),
|
sensorFixStore.loadFixes(fixes::add, mappingEvent.getDevice(), mappingEvent.getFrom(), mappingEvent.getToInclusive(),
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -738,7 +738,7 @@ public class GPSFixTrackImpl<ItemType, FixType extends GPSFix> extends MappedTra
|
|||||||
}
|
}
|
||||||
if (intervalStart == null) {
|
if (intervalStart == null) {
|
||||||
if (beforeFixIter.hasNext()) {
|
if (beforeFixIter.hasNext()) {
|
||||||
// No before fix within half averaging interval, but there is one further away; is its next neighbour even further away?
|
// No before fix within half averaging interval, but there is one further away; is its next neighbor even further away?
|
||||||
// If so, or no more neighbours are found, it's affected and marks the invalidation interval start; otherwise, fix'
|
// If so, or no more neighbours are found, it's affected and marks the invalidation interval start; otherwise, fix'
|
||||||
// time point is the invalidation interval start
|
// time point is the invalidation interval start
|
||||||
TimePoint intervalStartCandidate = beforeFixIter.next().getTimePoint();
|
TimePoint intervalStartCandidate = beforeFixIter.next().getTimePoint();
|
||||||
@@ -783,7 +783,7 @@ public class GPSFixTrackImpl<ItemType, FixType extends GPSFix> extends MappedTra
|
|||||||
} finally {
|
} finally {
|
||||||
unlockAfterRead();
|
unlockAfterRead();
|
||||||
}
|
}
|
||||||
return new TimeRangeImpl(intervalStart, intervalEnd);
|
return new TimeRangeImpl(intervalStart, intervalEnd.plus(1) /* need to add one millisecond to make intervalEnd included in time range */);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected FixType createDummyGPSFix(TimePoint at) {
|
protected FixType createDummyGPSFix(TimePoint at) {
|
||||||
|
|||||||
@@ -16,12 +16,32 @@ public interface TimePoint extends Comparable<TimePoint>, Serializable {
|
|||||||
|
|
||||||
Date asDate();
|
Date asDate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a time point that is {@code milliseconds} later than {@code this} time point, except in case the
|
||||||
|
* resulting time point would be after the {@link #EndOfTime} in which case {@link #EndOfTime} is returned
|
||||||
|
* instead of provoking an overflow with wrap-around.
|
||||||
|
*/
|
||||||
TimePoint plus(long milliseconds);
|
TimePoint plus(long milliseconds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a time point that is {@code duration} later than {@code this} time point, except in case the
|
||||||
|
* resulting time point would be after the {@link #EndOfTime} in which case {@link #EndOfTime} is returned
|
||||||
|
* instead of provoking an overflow with wrap-around.
|
||||||
|
*/
|
||||||
TimePoint plus(Duration duration);
|
TimePoint plus(Duration duration);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a time point that is {@code milliseconds} earlier than {@code this} time point, except in case the
|
||||||
|
* resulting time point would be before the {@link #BeginningOfTime} in which case {@link #BeginningOfTime} is returned
|
||||||
|
* instead of provoking an underflow with wrap-around.
|
||||||
|
*/
|
||||||
TimePoint minus(long milliseconds);
|
TimePoint minus(long milliseconds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a time point that is {@code duration} earlier than {@code this} time point, except in case the
|
||||||
|
* resulting time point would be before the {@link #BeginningOfTime} in which case {@link #BeginningOfTime} is returned
|
||||||
|
* instead of provoking an underflow with wrap-around.
|
||||||
|
*/
|
||||||
TimePoint minus(Duration duration);
|
TimePoint minus(Duration duration);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -64,7 +64,19 @@ public abstract class AbstractTimePoint implements TimePoint {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TimePoint plus(long milliseconds) {
|
public TimePoint plus(long milliseconds) {
|
||||||
return new MillisecondsTimePoint(asMillis()+milliseconds);
|
final TimePoint result;
|
||||||
|
if (milliseconds > 0) {
|
||||||
|
if (EndOfTime.asMillis()-milliseconds >= asMillis()) {
|
||||||
|
result = new MillisecondsTimePoint(asMillis()+milliseconds);
|
||||||
|
} else {
|
||||||
|
result = EndOfTime;
|
||||||
|
}
|
||||||
|
} else if (asMillis() < milliseconds) {
|
||||||
|
result = BeginningOfTime;
|
||||||
|
} else {
|
||||||
|
result = new MillisecondsTimePoint(asMillis()+milliseconds);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -21,13 +21,13 @@ public class TimeRangeImpl extends Util.Pair<TimePoint, TimePoint> implements Ti
|
|||||||
* if {@code null}, the time range is considered open on its "left" end, and all {@link TimePoint}s at or
|
* if {@code null}, the time range is considered open on its "left" end, and all {@link TimePoint}s at or
|
||||||
* after {@link TimePoint#BeginningOfTime} and at or before {@code to} are considered {@link #includes
|
* after {@link TimePoint#BeginningOfTime} and at or before {@code to} are considered {@link #includes
|
||||||
* included} in this time range.
|
* included} in this time range.
|
||||||
* @param to
|
* @param toExclusive
|
||||||
* if {@code null}, the time range is considered open on its "right" end, and all {@link TimePoint}s at
|
* if {@code null}, the time range is considered open on its "right" end, and all {@link TimePoint}s at
|
||||||
* or before {@link TimePoint#EndOfTime} and at or after {@code from} are considered {@link #includes
|
* or before {@link TimePoint#EndOfTime} and at or after {@code from} are considered {@link #includes
|
||||||
* included} in this time range.
|
* included} in this time range.
|
||||||
*/
|
*/
|
||||||
public TimeRangeImpl(TimePoint from, TimePoint to) {
|
public TimeRangeImpl(TimePoint from, TimePoint toExclusive) {
|
||||||
super(from == null ? TimePoint.BeginningOfTime : from, to == null ? TimePoint.EndOfTime : to);
|
super(from == null ? TimePoint.BeginningOfTime : from, toExclusive == null ? TimePoint.EndOfTime : toExclusive);
|
||||||
if (from().after(to())) {
|
if (from().after(to())) {
|
||||||
throw new IllegalArgumentException("from " + from() + " must lie before to " + to() + " in a TimeRange");
|
throw new IllegalArgumentException("from " + from() + " must lie before to " + to() + " in a TimeRange");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user