mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-28 00:16:46 +00:00
clone listener set into array, moving listener notification out of synchronized block, trying to increase concurrency
This commit is contained in:
+27
-9
@@ -16,6 +16,7 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
@@ -92,6 +93,14 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
private final Map<Pair<String, String>, com.sap.sailing.domain.base.Event> eventCache =
|
||||
new HashMap<Pair<String, String>, com.sap.sailing.domain.base.Event>();
|
||||
|
||||
/**
|
||||
* A cache based on weak references to the TracTrac event, allowing for quick Event lookup as long as the
|
||||
* TracTrac event remains referenced. This is intended to reduce the number of times the dominant boat
|
||||
* class needs to be determined for an event. Synchronization for additions / removals is tied to the
|
||||
* synchronization for {@link #eventCache}.
|
||||
*/
|
||||
private final WeakHashMap<com.tractrac.clientmodule.Event, Event> weakEventCache = new WeakHashMap<>();
|
||||
|
||||
private final Map<Race, RaceDefinition> raceCache = new HashMap<Race, RaceDefinition>();
|
||||
|
||||
private final Set<String> mayStartWithNoUpwindLeg;
|
||||
@@ -254,16 +263,24 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
// This means that currently it is permissible to assume that we'll get at most one
|
||||
// boat class per TracTrac event. Generally, however, we have to assume that
|
||||
// one TracTrac event may map to multiple domain Event objects with one BoatClass each
|
||||
Collection<CompetitorClass> competitorClassList = new ArrayList<CompetitorClass>();
|
||||
for (com.tractrac.clientmodule.Competitor c : event.getCompetitorList()) {
|
||||
competitorClassList.add(c.getCompetitorClass());
|
||||
}
|
||||
BoatClass boatClass = getDominantBoatClass(competitorClassList);
|
||||
Pair<String, String> key = new Pair<String, String>(event.getName(), boatClass==null?null:boatClass.getName());
|
||||
Event result = eventCache.get(key);
|
||||
|
||||
// try a quick look-up in the weak cache using the TracTrac event as key; only if that delivers no result,
|
||||
// compute the dominant boat class which requires a lot more effort
|
||||
Event result = weakEventCache.get(event);
|
||||
if (result == null) {
|
||||
result = new EventImpl(event.getName(), boatClass);
|
||||
eventCache.put(key, result);
|
||||
Collection<CompetitorClass> competitorClassList = new ArrayList<CompetitorClass>();
|
||||
for (com.tractrac.clientmodule.Competitor c : event.getCompetitorList()) {
|
||||
competitorClassList.add(c.getCompetitorClass());
|
||||
}
|
||||
BoatClass boatClass = getDominantBoatClass(competitorClassList);
|
||||
Pair<String, String> key = new Pair<String, String>(event.getName(), boatClass == null ? null
|
||||
: boatClass.getName());
|
||||
result = eventCache.get(key);
|
||||
if (result == null) {
|
||||
result = new EventImpl(event.getName(), boatClass);
|
||||
eventCache.put(key, result);
|
||||
weakEventCache.put(event, result);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -338,6 +355,7 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
event.removeRace(raceDefinition);
|
||||
if (oldSize > 0 && Util.size(event.getAllRaces()) == 0) {
|
||||
eventCache.remove(key);
|
||||
weakEventCache.remove(tractracEvent);
|
||||
}
|
||||
TrackedEvent trackedEvent = trackedEventRegistry.getTrackedEvent(event);
|
||||
if (trackedEvent != null) {
|
||||
|
||||
+67
-53
@@ -147,96 +147,110 @@ public class DynamicTrackedRaceImpl extends TrackedRaceImpl implements
|
||||
}
|
||||
|
||||
private void notifyListeners(GPSFix fix, Buoy buoy) {
|
||||
RaceChangeListener[] listeners;
|
||||
synchronized (getListeners()) {
|
||||
for (RaceChangeListener listener : getListeners()) {
|
||||
try {
|
||||
listener.buoyPositionChanged(fix, buoy);
|
||||
} catch (Throwable t) {
|
||||
logger.log(Level.SEVERE, "RaceChangeListener " + listener + " threw exception " + t.getMessage());
|
||||
logger.throwing(DynamicTrackedRaceImpl.class.getName(), "notifyListeners(GPSFix, Competitor)", t);
|
||||
}
|
||||
listeners = getListeners().toArray(new RaceChangeListener[getListeners().size()]);
|
||||
}
|
||||
for (RaceChangeListener listener : listeners) {
|
||||
try {
|
||||
listener.buoyPositionChanged(fix, buoy);
|
||||
} catch (Throwable t) {
|
||||
logger.log(Level.SEVERE, "RaceChangeListener " + listener + " threw exception " + t.getMessage());
|
||||
logger.throwing(DynamicTrackedRaceImpl.class.getName(), "notifyListeners(GPSFix, Competitor)", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyListeners(GPSFix fix, Competitor competitor) {
|
||||
RaceChangeListener[] listeners;
|
||||
synchronized (getListeners()) {
|
||||
for (RaceChangeListener listener : getListeners()) {
|
||||
try {
|
||||
listener.competitorPositionChanged(fix, competitor);
|
||||
} catch (Throwable t) {
|
||||
logger.log(Level.SEVERE, "RaceChangeListener " + listener + " threw exception " + t.getMessage());
|
||||
logger.throwing(DynamicTrackedRaceImpl.class.getName(), "notifyListeners(GPSFix, Competitor)", t);
|
||||
}
|
||||
listeners = getListeners().toArray(new RaceChangeListener[getListeners().size()]);
|
||||
}
|
||||
for (RaceChangeListener listener : listeners) {
|
||||
try {
|
||||
listener.competitorPositionChanged(fix, competitor);
|
||||
} catch (Throwable t) {
|
||||
logger.log(Level.SEVERE, "RaceChangeListener " + listener + " threw exception " + t.getMessage());
|
||||
logger.throwing(DynamicTrackedRaceImpl.class.getName(), "notifyListeners(GPSFix, Competitor)", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyListeners(Wind wind) {
|
||||
RaceChangeListener[] listeners;
|
||||
synchronized (getListeners()) {
|
||||
for (RaceChangeListener listener : getListeners()) {
|
||||
try {
|
||||
listener.windDataReceived(wind);
|
||||
} catch (Throwable t) {
|
||||
logger.log(Level.SEVERE, "RaceChangeListener " + listener + " threw exception " + t.getMessage());
|
||||
logger.throwing(DynamicTrackedRaceImpl.class.getName(), "notifyListeners(Wind)", t);
|
||||
}
|
||||
listeners = getListeners().toArray(new RaceChangeListener[getListeners().size()]);
|
||||
}
|
||||
for (RaceChangeListener listener : listeners) {
|
||||
try {
|
||||
listener.windDataReceived(wind);
|
||||
} catch (Throwable t) {
|
||||
logger.log(Level.SEVERE, "RaceChangeListener " + listener + " threw exception " + t.getMessage());
|
||||
logger.throwing(DynamicTrackedRaceImpl.class.getName(), "notifyListeners(Wind)", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyListenersSpeedAveragingChanged(long oldMillisecondsOverWhichToAverageSpeed, long newMillisecondsOverWhichToAverageSpeed) {
|
||||
RaceChangeListener[] listeners;
|
||||
synchronized (getListeners()) {
|
||||
for (RaceChangeListener listener : getListeners()) {
|
||||
try {
|
||||
listener.speedAveragingChanged(oldMillisecondsOverWhichToAverageSpeed,
|
||||
newMillisecondsOverWhichToAverageSpeed);
|
||||
} catch (Throwable t) {
|
||||
logger.log(Level.SEVERE, "RaceChangeListener " + listener + " threw exception " + t.getMessage());
|
||||
logger.throwing(DynamicTrackedRaceImpl.class.getName(),
|
||||
"notifyListenersSpeedAveragingChanged(long, long)", t);
|
||||
}
|
||||
listeners = getListeners().toArray(new RaceChangeListener[getListeners().size()]);
|
||||
}
|
||||
for (RaceChangeListener listener : listeners) {
|
||||
try {
|
||||
listener.speedAveragingChanged(oldMillisecondsOverWhichToAverageSpeed,
|
||||
newMillisecondsOverWhichToAverageSpeed);
|
||||
} catch (Throwable t) {
|
||||
logger.log(Level.SEVERE, "RaceChangeListener " + listener + " threw exception " + t.getMessage());
|
||||
logger.throwing(DynamicTrackedRaceImpl.class.getName(),
|
||||
"notifyListenersSpeedAveragingChanged(long, long)", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyListenersWindAveragingChanged(long oldMillisecondsOverWhichToAverageWind, long newMillisecondsOverWhichToAverageWind) {
|
||||
RaceChangeListener[] listeners;
|
||||
synchronized (getListeners()) {
|
||||
for (RaceChangeListener listener : getListeners()) {
|
||||
try {
|
||||
listener.windAveragingChanged(oldMillisecondsOverWhichToAverageWind,
|
||||
newMillisecondsOverWhichToAverageWind);
|
||||
} catch (Throwable t) {
|
||||
logger.log(Level.SEVERE, "RaceChangeListener " + listener + " threw exception " + t.getMessage());
|
||||
logger.throwing(DynamicTrackedRaceImpl.class.getName(),
|
||||
"notifyListenersWindAveragingChanged(long, long)", t);
|
||||
}
|
||||
listeners = getListeners().toArray(new RaceChangeListener[getListeners().size()]);
|
||||
}
|
||||
for (RaceChangeListener listener : listeners) {
|
||||
try {
|
||||
listener.windAveragingChanged(oldMillisecondsOverWhichToAverageWind,
|
||||
newMillisecondsOverWhichToAverageWind);
|
||||
} catch (Throwable t) {
|
||||
logger.log(Level.SEVERE, "RaceChangeListener " + listener + " threw exception " + t.getMessage());
|
||||
logger.throwing(DynamicTrackedRaceImpl.class.getName(),
|
||||
"notifyListenersWindAveragingChanged(long, long)", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyListenersWindRemoved(Wind wind) {
|
||||
RaceChangeListener[] listeners;
|
||||
synchronized (getListeners()) {
|
||||
for (RaceChangeListener listener : getListeners()) {
|
||||
try {
|
||||
listener.windDataRemoved(wind);
|
||||
} catch (Throwable t) {
|
||||
logger.log(Level.SEVERE, "RaceChangeListener " + listener + " threw exception " + t.getMessage());
|
||||
logger.throwing(DynamicTrackedRaceImpl.class.getName(), "notifyListenersWindRemoved(Wind)", t);
|
||||
}
|
||||
listeners = getListeners().toArray(new RaceChangeListener[getListeners().size()]);
|
||||
}
|
||||
for (RaceChangeListener listener : listeners) {
|
||||
try {
|
||||
listener.windDataRemoved(wind);
|
||||
} catch (Throwable t) {
|
||||
logger.log(Level.SEVERE, "RaceChangeListener " + listener + " threw exception " + t.getMessage());
|
||||
logger.throwing(DynamicTrackedRaceImpl.class.getName(), "notifyListenersWindRemoved(Wind)", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyListeners(MarkPassing oldMarkPassing, MarkPassing markPassing) {
|
||||
RaceChangeListener[] listeners;
|
||||
synchronized (getListeners()) {
|
||||
for (RaceChangeListener listener : getListeners()) {
|
||||
try {
|
||||
listener.markPassingReceived(oldMarkPassing, markPassing);
|
||||
} catch (Throwable t) {
|
||||
logger.log(Level.SEVERE, "RaceChangeListener " + listener + " threw exception " + t.getMessage());
|
||||
logger.throwing(DynamicTrackedRaceImpl.class.getName(), "notifyListeners(MarkPassing)", t);
|
||||
}
|
||||
listeners = getListeners().toArray(new RaceChangeListener[getListeners().size()]);
|
||||
}
|
||||
for (RaceChangeListener listener : listeners) {
|
||||
try {
|
||||
listener.markPassingReceived(oldMarkPassing, markPassing);
|
||||
} catch (Throwable t) {
|
||||
logger.log(Level.SEVERE, "RaceChangeListener " + listener + " threw exception " + t.getMessage());
|
||||
logger.throwing(DynamicTrackedRaceImpl.class.getName(), "notifyListeners(MarkPassing)", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user