java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java
... ...
@@ -1022,6 +1022,11 @@ public abstract class GPSFixTrackImpl<ItemType, FixType extends GPSFix> extends
1022 1022
* point of the <code>gpsFix</code> "upwards." However, if the adjacent earlier fixes have changed their validity by
1023 1023
* the addition of <code>gpsFix</code>, the distance cache must be invalidated starting with the first fix whose
1024 1024
* validity changed.
1025
+ * <p>
1026
+ *
1027
+ * When a fix's validity changes, the set of fixes returned by {@link #getInternalFixes()} changes. Since
1028
+ * {@link #getEstimatedSpeed(TimePoint)} uses {@link #getInternalFixes()} for its calculation, the estimated
1029
+ * speed caches of fixes whose speed calculation might be affected need to be invalidated as well.
1025 1030
*/
1026 1031
private void invalidateValidityAndEstimatedSpeedAndDistanceCaches(FixType gpsFix) {
1027 1032
assertWriteLock();
... ...
@@ -1047,14 +1052,42 @@ public abstract class GPSFixTrackImpl<ItemType, FixType extends GPSFix> extends
1047 1052
boolean lowerWasValid = isValid(getRawFixes(), lower);
1048 1053
lower.invalidateCache();
1049 1054
boolean lowerIsValid = isValid(getRawFixes(), lower);
1050
- if (lowerIsValid != lowerWasValid && lower.getTimePoint().before(distanceCacheInvalidationStart)) {
1051
- distanceCacheInvalidationStart = lower.getTimePoint();
1055
+ if (lowerIsValid != lowerWasValid) {
1056
+ if (lower.getTimePoint().before(distanceCacheInvalidationStart)) {
1057
+ distanceCacheInvalidationStart = lower.getTimePoint();
1058
+ }
1059
+ invalidateEstimatedSpeedCachesAffectedByValidityChange(lower);
1052 1060
}
1053 1061
}
1054 1062
getDistanceCache().invalidateAllAtOrLaterThan(distanceCacheInvalidationStart);
1055 1063
Iterable<FixType> highers = getLaterFixesWhoseValidityMayBeAffected(gpsFix);
1056 1064
for (FixType higher : highers) {
1065
+ boolean higherWasValid = isValid(getRawFixes(), higher);
1057 1066
higher.invalidateCache();
1067
+ boolean higherIsValid = isValid(getRawFixes(), higher);
1068
+ if (higherIsValid != higherWasValid) {
1069
+ invalidateEstimatedSpeedCachesAffectedByValidityChange(higher);
1070
+ }
1071
+ }
1072
+ }
1073
+
1074
+ /**
1075
+ * When the validity of {@code fixWithChangedValidity} changes, the set of fixes returned by
1076
+ * {@link #getInternalFixes()} changes. Since {@link #getEstimatedSpeed(TimePoint)} uses
1077
+ * {@link #getInternalFixes()} for its calculation, this method invalidates the estimated speed caches
1078
+ * of all fixes whose speed estimation might be affected by this change.
1079
+ * <p>
1080
+ *
1081
+ * The affected fixes are those within the time interval returned by
1082
+ * {@link #getTimeIntervalWhoseEstimatedSpeedMayHaveChangedAfterAddingFix(GPSFix)}, since a validity
1083
+ * change has the same effect on speed estimation as adding or removing a fix.
1084
+ */
1085
+ private void invalidateEstimatedSpeedCachesAffectedByValidityChange(FixType fixWithChangedValidity) {
1086
+ TimeRange affectedInterval = getTimeIntervalWhoseEstimatedSpeedMayHaveChangedAfterAddingFix(fixWithChangedValidity);
1087
+ for (FixType affectedFix : getInternalRawFixes().subSet(
1088
+ createDummyGPSFix(affectedInterval.from()), true,
1089
+ createDummyGPSFix(affectedInterval.to()), true)) {
1090
+ affectedFix.invalidateEstimatedSpeedCache();
1058 1091
}
1059 1092
}
1060 1093