fixed issues with Collections.unmodifiableCollection's equals/hashCode, affecting ShortTimeWindCache's key structure regarding excluded wind sources

This commit is contained in:
Axel Uhl committed 2014-10-30 10:36:59 +01:00
1 parent 09b85ec2de
commit ee261a5477
15 files changed
+81 -54

No files matched your search

@@ -6,6 +6,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.NavigableSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.Executor;
@@ -216,7 +217,7 @@ public class PolarSheetGenerationTest {
}
@Override
public Wind getWind(Position p, TimePoint at, Iterable<WindSource> windSourcesToExclude) {
public Wind getWind(Position p, TimePoint at, Set<WindSource> windSourcesToExclude) {
return getWind(p, at);
}
@@ -229,7 +230,7 @@ public class PolarSheetGenerationTest {
@Override
public WindWithConfidence<com.sap.sse.common.Util.Pair<Position, TimePoint>> getWindWithConfidence(Position p, TimePoint at,
Iterable<WindSource> windSourcesToExclude) {
Set<WindSource> windSourcesToExclude) {
return getWindWithConfidence(p, at);
}
@@ -263,8 +264,8 @@ public class PolarSheetGenerationTest {
}
@Override
public Iterable<WindSource> getWindSources(WindSourceType type) {
List<WindSource> sources = new ArrayList<WindSource>();
public Set<WindSource> getWindSources(WindSourceType type) {
Set<WindSource> sources = new HashSet<>();
sources.add(new WindSourceImpl(type));
return sources;
}
@@ -7,6 +7,7 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.junit.Test;
@@ -15,6 +16,7 @@ import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.common.WindSourceType;
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
import com.sap.sailing.domain.common.impl.DegreePosition;
@@ -65,4 +67,17 @@ public class WindEstimationOnStoredTracksTest extends StoredTrackBasedTestWithTr
assertNotNull(estimatedWindDirection);
}
@Test
public void testWindSourcesAreEqualAcrossCalls() {
Set<WindSource> ws1 = getTrackedRace().getWindSources();
Set<WindSource> ws2 = getTrackedRace().getWindSources();
assertEquals(ws1, ws2);
}
@Test
public void testExcludedWindSourcesAreEqualAcrossCalls() {
Set<WindSource> ews1 = getTrackedRace().getWindSourcesToExclude();
Set<WindSource> ews2 = getTrackedRace().getWindSourcesToExclude();
assertEquals(ews1, ews2);
}
}
@@ -4,6 +4,7 @@ import java.io.Serializable;
import java.util.Collections;
import java.util.List;
import java.util.NavigableSet;
import java.util.Set;
import java.util.TreeSet;
import com.sap.sailing.domain.base.BoatClass;
@@ -611,24 +612,24 @@ public class MockedTrackedRace implements DynamicTrackedRace {
}
@Override
public Wind getWind(Position p, TimePoint at, Iterable<WindSource> windSourcesToExclude) {
public Wind getWind(Position p, TimePoint at, Set<WindSource> windSourcesToExclude) {
// TODO Auto-generated method stub
return null;
}
@Override
public Iterable<WindSource> getWindSources(WindSourceType type) {
return Collections.emptyList();
public Set<WindSource> getWindSources(WindSourceType type) {
return Collections.emptySet();
}
@Override
public Iterable<WindSource> getWindSources() {
return Collections.emptyList();
public Set<WindSource> getWindSources() {
return Collections.emptySet();
}
@Override
public WindWithConfidence<Util.Pair<Position, TimePoint>> getWindWithConfidence(Position p, TimePoint at,
Iterable<WindSource> windSourcesToExclude) {
Set<WindSource> windSourcesToExclude) {
// TODO Auto-generated method stub
return null;
}
@@ -646,7 +647,7 @@ public class MockedTrackedRace implements DynamicTrackedRace {
}
@Override
public Iterable<WindSource> getWindSourcesToExclude() {
public Set<WindSource> getWindSourcesToExclude() {
// TODO Auto-generated method stub
return null;
}
@@ -5,6 +5,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.NavigableSet;
import java.util.Set;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Leg;
@@ -226,19 +227,19 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace {
}
@Override
public Wind getWind(Position p, TimePoint at, Iterable<WindSource> windSourcesToExclude) {
public Wind getWind(Position p, TimePoint at, Set<WindSource> windSourcesToExclude) {
// TODO Auto-generated method stub
return null;
}
@Override
public Iterable<WindSource> getWindSources(WindSourceType type) {
return Collections.emptyList();
public Set<WindSource> getWindSources(WindSourceType type) {
return Collections.emptySet();
}
@Override
public Iterable<WindSource> getWindSources() {
return Collections.emptyList();
public Set<WindSource> getWindSources() {
return Collections.emptySet();
}
@Override
@@ -399,14 +400,14 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace {
}
@Override
public Iterable<WindSource> getWindSourcesToExclude() {
public Set<WindSource> getWindSourcesToExclude() {
// TODO Auto-generated method stub
return null;
}
@Override
public WindWithConfidence<Util.Pair<Position, TimePoint>> getWindWithConfidence(Position p, TimePoint at,
Iterable<WindSource> windSourcesToExclude) {
Set<WindSource> windSourcesToExclude) {
// TODO Auto-generated method stub
return null;
}
@@ -172,7 +172,7 @@ public class PerRaceAndCompetitorPolarSheetGenerationWorker implements Runnable
= new ArrayList<Util.Pair<String, WindWithConfidence<Util.Pair<Position, TimePoint>>>>();
for (WindSource windGaugeSource : windGaugeSources) {
Iterable<WindSource> allSources = race.getWindSources();
List<WindSource> allSourcesButTheSingleWindGaugeSource = new ArrayList<WindSource>();
Set<WindSource> allSourcesButTheSingleWindGaugeSource = new HashSet<WindSource>();
for (WindSource windSource : allSources) {
if (windSource != windGaugeSource) {
allSourcesButTheSingleWindGaugeSource.add(windSource);
@@ -202,7 +202,7 @@ public class PerRaceAndCompetitorPolarSheetGenerationWorker implements Runnable
return done;
}
private Iterable<WindSource> collectWindSourcesToIgnoreForSpeed() {
private Set<WindSource> collectWindSourcesToIgnoreForSpeed() {
Set<WindSource> windSourcesToExclude = new HashSet<WindSource>();
Iterable<WindSource> combinedSources = race.getWindSources(WindSourceType.COMBINED);
for (WindSource combinedSource : combinedSources) {
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.tracking;
import java.io.Serializable;
import java.util.List;
import java.util.NavigableSet;
import java.util.Set;
import java.util.SortedSet;
import com.sap.sailing.domain.base.Competitor;
@@ -238,7 +239,7 @@ public interface TrackedRace extends Serializable {
Position getApproximatePosition(Waypoint waypoint, TimePoint timePoint);
/**
* Same as {@link #getWind(Position, TimePoint, Iterable) getWind(p, at, Collections.emptyList())}
* Same as {@link #getWind(Position, TimePoint, Set) getWind(p, at, Collections.emptyList())}
*/
Wind getWind(Position p, TimePoint at);
@@ -247,7 +248,7 @@ public interface TrackedRace extends Serializable {
* from all wind sources available except for those listed in <code>windSourcesToExclude</code>, using the
* confidences of the wind values provided by the various sources during averaging.
*/
Wind getWind(Position p, TimePoint at, Iterable<WindSource> windSourcesToExclude);
Wind getWind(Position p, TimePoint at, Set<WindSource> windSourcesToExclude);
/**
* Retrieves the wind sources used so far by this race that have the specified <code>type</code> as their
@@ -255,13 +256,13 @@ public interface TrackedRace extends Serializable {
* race does not use any wind source of the specified type (yet). Additional sources may be returned after
*
*/
Iterable<WindSource> getWindSources(WindSourceType type);
Set<WindSource> getWindSources(WindSourceType type);
/**
* Retrieves all wind sources known to this race, including those {@link #getWindSourcesToExclude() to exclude}.
* Callers can freely iterate because a copied collection is returned.
*/
Iterable<WindSource> getWindSources();
Set<WindSource> getWindSources();
/**
* Same as {@link #getOrCreateWindTrack(WindSource, long) getOrCreateWindTrack(windSource,
@@ -484,7 +485,7 @@ public interface TrackedRace extends Serializable {
* Lists those wind sources which by default are not considered in {@link #getWind(Position, TimePoint)} and
* {@link #getWindWithConfidence(Position, TimePoint)}.
*/
Iterable<WindSource> getWindSourcesToExclude();
Set<WindSource> getWindSourcesToExclude();
/**
* Loops over this tracked race's wind sources and from each asks its averaged wind for the position <code>p</code>
@@ -493,7 +494,7 @@ public interface TrackedRace extends Serializable {
* averaged confidence attached.
*/
WindWithConfidence<Util.Pair<Position, TimePoint>> getWindWithConfidence(Position p, TimePoint at,
Iterable<WindSource> windSourcesToExclude);
Set<WindSource> windSourcesToExclude);
/**
* Same as {@link #getEstimatedWindDirection(TimePoint)}, but propagates the confidence of the wind
@@ -122,7 +122,7 @@ public abstract class TrackedRaceWithWindEssentials implements TrackedRace {
}
@Override
public Iterable<WindSource> getWindSources(WindSourceType type) {
public Set<WindSource> getWindSources(WindSourceType type) {
Set<WindSource> result = new HashSet<WindSource>();
for (WindSource windSource : getWindSources()) {
if (windSource.getType() == type) {
@@ -133,7 +133,7 @@ public abstract class TrackedRaceWithWindEssentials implements TrackedRace {
}
@Override
public Iterable<WindSource> getWindSources() {
public Set<WindSource> getWindSources() {
while (true) {
try {
return new HashSet<WindSource>(windTracks.keySet());
@@ -1,5 +1,6 @@
package com.sap.sailing.domain.tracking.impl;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
@@ -24,13 +25,13 @@ import com.sap.sse.common.Util.Triple;
*/
public class ShortTimeWindCache {
private static final Logger logger = Logger.getLogger(ShortTimeWindCache.class.getName());
private final ConcurrentHashMap<Triple<Position, TimePoint, Iterable<WindSource>>,
private final ConcurrentHashMap<Triple<Position, TimePoint, Set<WindSource>>,
WindWithConfidence<com.sap.sse.common.Util.Pair<Position, TimePoint>>> cache;
/**
* The keys of {@link #cache} in the order in which to invalidate them, keyed by the time they were entered into the cache.
*/
private final ConcurrentLinkedDeque<Pair<Long, Triple<Position, TimePoint, Iterable<WindSource>>>> order;
private final ConcurrentLinkedDeque<Pair<Long, Triple<Position, TimePoint, Set<WindSource>>>> order;
/**
* Creation and removal / cancellation of the timer is synchronized using {@link #order}.
@@ -47,7 +48,7 @@ public class ShortTimeWindCache {
@Override
public void run() {
long oldestToKeep = System.currentTimeMillis() - preserveHowManyMilliseconds;
Pair<Long, Triple<Position, TimePoint, Iterable<WindSource>>> next;
Pair<Long, Triple<Position, TimePoint, Set<WindSource>>> next;
while ((next = order.pollFirst()) != null && next.getA() < oldestToKeep) {
cache.remove(next.getB());
}
@@ -68,11 +69,11 @@ public class ShortTimeWindCache {
order = new ConcurrentLinkedDeque<>();
}
public void add(Triple<Position, TimePoint, Iterable<WindSource>> key, WindWithConfidence<com.sap.sse.common.Util.Pair<Position, TimePoint>> wind) {
public void add(Triple<Position, TimePoint, Set<WindSource>> key, WindWithConfidence<com.sap.sse.common.Util.Pair<Position, TimePoint>> wind) {
cache.put(key, wind);
boolean orderEmpty = order.isEmpty();
synchronized (order) {
order.add(new Pair<Long, Triple<Position, TimePoint, Iterable<WindSource>>>(System.currentTimeMillis(), key));
order.add(new Pair<Long, Triple<Position, TimePoint, Set<WindSource>>>(System.currentTimeMillis(), key));
if (orderEmpty) {
ensureTimerIsRunning();
}
@@ -80,9 +81,9 @@ public class ShortTimeWindCache {
}
WindWithConfidence<com.sap.sse.common.Util.Pair<Position, TimePoint>> getWindWithConfidence(Position p,
TimePoint at, Iterable<WindSource> windSourcesToExclude) {
TimePoint at, Set<WindSource> windSourcesToExclude) {
WindWithConfidence<com.sap.sse.common.Util.Pair<Position, TimePoint>> wind;
final Triple<Position, TimePoint, Iterable<WindSource>> key = new Triple<>(p, at, windSourcesToExclude);
final Triple<Position, TimePoint, Set<WindSource>> key = new Triple<Position, TimePoint, Set<WindSource>>(p, at, windSourcesToExclude);
wind = cache.get(key);
if (wind == null) {
misses++;
@@ -8,6 +8,7 @@ import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.logging.Logger;
@@ -245,7 +246,7 @@ public class TrackedLegImpl implements TrackedLeg, RaceChangeListener {
return effectivePosition;
}
private Wind getWind(Position p, TimePoint at, Iterable<WindSource> windSourcesToExclude) {
private Wind getWind(Position p, TimePoint at, Set<WindSource> windSourcesToExclude) {
return getTrackedRace().getWind(p, at, windSourcesToExclude);
}
@@ -5,6 +5,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.NavigableSet;
import java.util.Set;
import java.util.concurrent.Callable;
import com.sap.sailing.domain.base.Competitor;
@@ -227,7 +228,7 @@ public class TrackedLegOfCompetitorImpl implements TrackedLegOfCompetitor {
* Projects <code>speed</code> onto the wind direction for upwind/downwind legs to see how fast a boat travels
* "along the wind's direction." For reaching legs (neither upwind nor downwind), the speed is projected onto
* the leg's direction.
* @param windPositionMode see {@link #getWind(Position, TimePoint, WindPositionMode)}
* @param windPositionMode see {@link #getWind(Position, TimePoint, Set)}
*
* @throws NoWindException in case the wind direction is not known
*/
@@ -1323,7 +1323,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
}
@Override
public Wind getWind(Position p, TimePoint at, Iterable<WindSource> windSourcesToExclude) {
public Wind getWind(Position p, TimePoint at, Set<WindSource> windSourcesToExclude) {
final WindWithConfidence<com.sap.sse.common.Util.Pair<Position, TimePoint>> windWithConfidence = getWindWithConfidence(p, at,
windSourcesToExclude);
return windWithConfidence == null ? null : windWithConfidence.getObject();
@@ -1335,9 +1335,9 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
}
@Override
public Iterable<WindSource> getWindSourcesToExclude() {
public Set<WindSource> getWindSourcesToExclude() {
synchronized (windSourcesToExclude) {
return Collections.unmodifiableCollection(windSourcesToExclude);
return Collections.unmodifiableSet(windSourcesToExclude);
}
}
@@ -1363,7 +1363,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
@Override
public WindWithConfidence<com.sap.sse.common.Util.Pair<Position, TimePoint>> getWindWithConfidence(Position p, TimePoint at,
Iterable<WindSource> windSourcesToExclude) {
Set<WindSource> windSourcesToExclude) {
return shortTimeWindCache.getWindWithConfidence(p, at, windSourcesToExclude);
}
@@ -3,6 +3,7 @@ package com.sap.sailing.gwt.ui.test;
import java.io.Serializable;
import java.util.List;
import java.util.NavigableSet;
import java.util.Set;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
@@ -611,26 +612,26 @@ public class MockedTrackedRace implements DynamicTrackedRace {
}
@Override
public Wind getWind(Position p, TimePoint at, Iterable<WindSource> windSourcesToExclude) {
public Wind getWind(Position p, TimePoint at, Set<WindSource> windSourcesToExclude) {
// TODO Auto-generated method stub
return null;
}
@Override
public Iterable<WindSource> getWindSources(WindSourceType type) {
public Set<WindSource> getWindSources(WindSourceType type) {
// TODO Auto-generated method stub
return null;
}
@Override
public Iterable<WindSource> getWindSources() {
public Set<WindSource> getWindSources() {
// TODO Auto-generated method stub
return null;
}
@Override
public WindWithConfidence<Util.Pair<Position, TimePoint>> getWindWithConfidence(Position p, TimePoint at,
Iterable<WindSource> windSourcesToExclude) {
Set<WindSource> windSourcesToExclude) {
// TODO Auto-generated method stub
return null;
}
@@ -648,7 +649,7 @@ public class MockedTrackedRace implements DynamicTrackedRace {
}
@Override
public Iterable<WindSource> getWindSourcesToExclude() {
public Set<WindSource> getWindSourcesToExclude() {
// TODO Auto-generated method stub
return null;
}
@@ -1,8 +1,10 @@
package com.sap.sailing.gwt.ui.test;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.NavigableSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentSkipListSet;
@@ -133,7 +135,7 @@ public class PolarSheetGenerationServiceTest {
}
@Override
public Wind getWind(Position p, TimePoint at, Iterable<WindSource> windSourcesToExclude) {
public Wind getWind(Position p, TimePoint at, Set<WindSource> windSourcesToExclude) {
return getWind(p, at);
}
@@ -146,7 +148,7 @@ public class PolarSheetGenerationServiceTest {
@Override
public WindWithConfidence<com.sap.sse.common.Util.Pair<Position, TimePoint>> getWindWithConfidence(Position p, TimePoint at,
Iterable<WindSource> windSourcesToExclude) {
Set<WindSource> windSourcesToExclude) {
return getWindWithConfidence(p, at);
}
@@ -184,8 +186,8 @@ public class PolarSheetGenerationServiceTest {
}
@Override
public Iterable<WindSource> getWindSources(WindSourceType type) {
List<WindSource> sources = new ArrayList<WindSource>();
public Set<WindSource> getWindSources(WindSourceType type) {
Set<WindSource> sources = new HashSet<WindSource>();
sources.add(new WindSourceImpl(type));
return sources;
}
@@ -9,6 +9,7 @@ import static org.mockito.Mockito.when;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
@@ -103,7 +104,7 @@ public class WindJsonGetServletRefactoringTest {
public void compareOldAndNewImplementation() {
TrackedRace trackedRace = mock(TrackedRace.class);
final WindSourceImpl webWindSource = new WindSourceImpl(WindSourceType.WEB);
when(trackedRace.getWindSources()).thenReturn(Arrays.asList(new WindSource[] { webWindSource }));
when(trackedRace.getWindSources()).thenReturn(new HashSet<>(Arrays.asList(new WindSource[] { webWindSource })));
RaceDefinition race = mock(RaceDefinition.class);
when(race.getName()).thenReturn("Race Name");
when(trackedRace.getRace()).thenReturn(race);
@@ -5,6 +5,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.NavigableSet;
import java.util.Set;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Leg;
@@ -202,7 +203,7 @@ public class DummyTrackedRace extends TrackedRaceWithWindEssentials {
}
@Override
public Wind getWind(Position p, TimePoint at, Iterable<WindSource> windSourcesToExclude) {
public Wind getWind(Position p, TimePoint at, Set<WindSource> windSourcesToExclude) {
return null;
}
@@ -377,14 +378,14 @@ public class DummyTrackedRace extends TrackedRaceWithWindEssentials {
}
@Override
public Iterable<WindSource> getWindSourcesToExclude() {
public Set<WindSource> getWindSourcesToExclude() {
// TODO Auto-generated method stub
return null;
}
@Override
public WindWithConfidence<Util.Pair<Position, TimePoint>> getWindWithConfidence(Position p, TimePoint at,
Iterable<WindSource> windSourcesToExclude) {
Set<WindSource> windSourcesToExclude) {
// TODO Auto-generated method stub
return null;
}