mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-20 19:20:04 +00:00
initial calculator
This commit is contained in:
1 parent
55ec7a124f
commit
bfad7d0869
8 files changed
+184
-7
No files matched your search
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.sap.sailing.server.gateway.serialization.impl;
|
||||
package com.sap.sailing.domain.anniversary;
|
||||
|
||||
public class AnniversaryConflictResolver {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.sap.sailing.server.gateway.serialization.impl;
|
||||
package com.sap.sailing.domain.anniversary;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
+2
-2
@@ -12,6 +12,8 @@ import javax.ws.rs.core.Response;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONAware;
|
||||
|
||||
import com.sap.sailing.domain.anniversary.AnniversaryConflictResolver;
|
||||
import com.sap.sailing.domain.anniversary.AnniversaryRaceInfo;
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
@@ -20,8 +22,6 @@ import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.server.gateway.jaxrs.AbstractSailingServerResource;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.AnniversaryConflictResolver;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.AnniversaryRaceInfo;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.AnniversaryRaceInfoJsonSerializer;
|
||||
|
||||
@Path("/v1/anniversary")
|
||||
|
||||
+1
@@ -2,6 +2,7 @@ package com.sap.sailing.server.gateway.serialization.impl;
|
||||
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import com.sap.sailing.domain.anniversary.AnniversaryRaceInfo;
|
||||
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
|
||||
|
||||
public class AnniversaryRaceInfoJsonSerializer implements JsonSerializer<AnniversaryRaceInfo> {
|
||||
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
package com.sap.sailing.server.anniversary;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.sap.sailing.domain.anniversary.AnniversaryConflictResolver;
|
||||
import com.sap.sailing.domain.anniversary.AnniversaryRaceInfo;
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
|
||||
public class AnniversaryCalculator implements Runnable {
|
||||
private static final long INITIAL_DELAY = 1000;
|
||||
private static final long DELAY = 5000;
|
||||
private RacingEventService racingEventService;
|
||||
private AnniversaryConflictResolver resolver = new AnniversaryConflictResolver();
|
||||
private int lastAmount = -1;
|
||||
private CopyOnWriteArraySet<ChangeListener> listeners = new CopyOnWriteArraySet<>();
|
||||
|
||||
interface ChangeListener{
|
||||
void onChange(Collection<AnniversaryRaceInfo> collection);
|
||||
}
|
||||
|
||||
public AnniversaryCalculator(ScheduledExecutorService scheduledExecutorService) {
|
||||
scheduledExecutorService.scheduleWithFixedDelay(this,INITIAL_DELAY ,DELAY, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public void addListener(ChangeListener listener){
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public void removeListener(ChangeListener listener){
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if(racingEventService==null || listeners.isEmpty()){
|
||||
return;
|
||||
}
|
||||
HashMap<RegattaAndRaceIdentifier, AnniversaryRaceInfo> local = getLocalResults();
|
||||
//add remotes with resolver checking
|
||||
if(lastAmount < local.size()){
|
||||
for(ChangeListener listener:listeners){
|
||||
listener.onChange(local.values());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private HashMap<RegattaAndRaceIdentifier, AnniversaryRaceInfo> getLocalResults() {
|
||||
HashMap<RegattaAndRaceIdentifier, AnniversaryRaceInfo> anniversaryRaceList = new HashMap<RegattaAndRaceIdentifier, AnniversaryRaceInfo>();
|
||||
for (Event event : racingEventService.getAllEvents()) {
|
||||
for (LeaderboardGroup group : event.getLeaderboardGroups()) {
|
||||
for (Leaderboard leaderboard : group.getLeaderboards()) {
|
||||
for (RaceColumn race : leaderboard.getRaceColumns()) {
|
||||
for (Fleet fleet : race.getFleets()) {
|
||||
TrackedRace trackedRace = race.getTrackedRace(fleet);
|
||||
if (trackedRace != null) {
|
||||
RegattaAndRaceIdentifier raceIdentifier = trackedRace.getRaceIdentifier();
|
||||
AnniversaryRaceInfo current = anniversaryRaceList.get(raceIdentifier);
|
||||
AnniversaryRaceInfo raceInfo = new AnniversaryRaceInfo(raceIdentifier,
|
||||
leaderboard.getName(), trackedRace.getStartOfRace().asDate(),
|
||||
event.getId().toString(),null);
|
||||
if(current == null){
|
||||
anniversaryRaceList.put(raceIdentifier, raceInfo);
|
||||
}else{
|
||||
AnniversaryRaceInfo prefered = resolver.resolve(current,raceInfo);
|
||||
if(prefered != current){
|
||||
anniversaryRaceList.put(prefered.getIdentifier(), prefered);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return anniversaryRaceList;
|
||||
}
|
||||
|
||||
public void setRacingEventService(RacingEventService racingEventService) {
|
||||
this.racingEventService = racingEventService;
|
||||
}
|
||||
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
package com.sap.sailing.server.anniversary;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.sap.sailing.domain.anniversary.AnniversaryRaceInfo;
|
||||
import com.sap.sailing.server.anniversary.AnniversaryCalculator.ChangeListener;
|
||||
|
||||
public class AnniversaryDeterminator implements ChangeListener {
|
||||
private static int[] anniversaries = new int[]{10,25, 50,75};
|
||||
ConcurrentHashMap<Integer, AnniversaryRaceInfo> knownAnniversaries = new ConcurrentHashMap<>();
|
||||
|
||||
public AnniversaryDeterminator() {
|
||||
knownAnniversaries.putAll(load());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(Collection<AnniversaryRaceInfo> collection) {
|
||||
ArrayList<AnniversaryRaceInfo> allRaces = new ArrayList<>(collection);
|
||||
Collections.sort(allRaces,new Comparator<AnniversaryRaceInfo>() {
|
||||
|
||||
@Override
|
||||
public int compare(AnniversaryRaceInfo o1, AnniversaryRaceInfo o2) {
|
||||
return o1.getStartOfRace().compareTo(o2.getStartOfRace());
|
||||
}
|
||||
});
|
||||
checkForAnnivesaries(allRaces);
|
||||
}
|
||||
|
||||
private void checkForAnnivesaries(List<AnniversaryRaceInfo> collection) {
|
||||
int newAmount = collection.size();
|
||||
int factor = 1;
|
||||
while(true){
|
||||
for(int anniversary:anniversaries){
|
||||
int anniversaryToCheck = anniversary*factor;
|
||||
if(anniversaryToCheck > newAmount){
|
||||
return;
|
||||
}
|
||||
if(newAmount<anniversaryToCheck){
|
||||
onAnniversaryTraverse(anniversaryToCheck,collection.get(anniversaryToCheck));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onAnniversaryTraverse(int anniversaryToCheck, AnniversaryRaceInfo anniversaryRaceInfo) {
|
||||
AnniversaryRaceInfo knownAnniversary = knownAnniversaries.get(anniversaryToCheck);
|
||||
if(knownAnniversary != null){
|
||||
System.out.println("Skipping anniversary " + anniversaryToCheck + " as it is already known");
|
||||
}else{
|
||||
System.out.println("New anniversary " + anniversaryToCheck + " " + anniversaryRaceInfo);
|
||||
knownAnniversaries.put(anniversaryToCheck, anniversaryRaceInfo);
|
||||
persist();
|
||||
}
|
||||
}
|
||||
|
||||
private void persist() {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
|
||||
private Map<Integer, AnniversaryRaceInfo> load() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,8 @@ import com.sap.sailing.domain.polars.PolarDataService;
|
||||
import com.sap.sailing.server.MasterDataImportClassLoaderService;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sailing.server.RacingEventServiceMXBean;
|
||||
import com.sap.sailing.server.anniversary.AnniversaryCalculator;
|
||||
import com.sap.sailing.server.anniversary.AnniversaryDeterminator;
|
||||
import com.sap.sailing.server.impl.preferences.model.BoatClassNotificationPreferences;
|
||||
import com.sap.sailing.server.impl.preferences.model.CompetitorNotificationPreferences;
|
||||
import com.sap.sailing.server.notification.impl.SailingNotificationServiceImpl;
|
||||
@@ -48,6 +50,7 @@ import com.sap.sse.replication.Replicable;
|
||||
import com.sap.sse.security.PreferenceConverter;
|
||||
import com.sap.sse.util.ClearStateTestSupport;
|
||||
import com.sap.sse.util.ServiceTrackerFactory;
|
||||
import com.sap.sse.util.ThreadPoolUtil;
|
||||
|
||||
public class Activator implements BundleActivator {
|
||||
|
||||
@@ -82,6 +85,8 @@ public class Activator implements BundleActivator {
|
||||
private SailingNotificationServiceImpl notificationService;
|
||||
|
||||
private ServiceTracker<MailService, MailService> mailServiceTracker;
|
||||
|
||||
private AnniversaryCalculator anniversaryCalculator;
|
||||
|
||||
public Activator() {
|
||||
clearPersistentCompetitors = Boolean
|
||||
@@ -108,9 +113,12 @@ public class Activator implements BundleActivator {
|
||||
// this code block is not run, and the test case can inject some other type of finder
|
||||
// instead.
|
||||
serviceFinderFactory = new CachedOsgiTypeBasedServiceFinderFactory(context);
|
||||
anniversaryCalculator = new AnniversaryCalculator(ThreadPoolUtil.INSTANCE.getDefaultBackgroundTaskThreadPoolExecutor());
|
||||
racingEventService = new RacingEventServiceImpl(clearPersistentCompetitors, serviceFinderFactory,
|
||||
trackedRegattaListener, notificationService, restoreTrackedRaces);
|
||||
trackedRegattaListener, notificationService, restoreTrackedRaces,anniversaryCalculator);
|
||||
notificationService.setRacingEventService(racingEventService);
|
||||
anniversaryCalculator.addListener(new AnniversaryDeterminator());
|
||||
anniversaryCalculator.setRacingEventService(racingEventService);
|
||||
|
||||
masterDataImportClassLoaderServiceTracker = new ServiceTracker<MasterDataImportClassLoaderService, MasterDataImportClassLoaderService>(
|
||||
context, MasterDataImportClassLoaderService.class,
|
||||
|
||||
+7
-2
@@ -175,6 +175,7 @@ import com.sap.sailing.domain.tracking.impl.TrackedRaceImpl;
|
||||
import com.sap.sailing.expeditionconnector.ExpeditionWindTrackerFactory;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sailing.server.Replicator;
|
||||
import com.sap.sailing.server.anniversary.AnniversaryCalculator;
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.CourseAreaJsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.EventBaseJsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.LeaderboardGroupBaseJsonDeserializer;
|
||||
@@ -450,6 +451,8 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
||||
|
||||
private transient final ConcurrentHashMap<RaceDefinition, RaceTrackingConnectivityParameters> connectivityParametersByRace;
|
||||
|
||||
private AnniversaryCalculator anniversaryCalculator;
|
||||
|
||||
/**
|
||||
* Providing the constructor parameters for a new {@link RacingEventServiceImpl} instance is a bit tricky
|
||||
* in some cases because containment and initialization order of some types is fairly tightly coupled.
|
||||
@@ -489,7 +492,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
||||
}
|
||||
|
||||
public RacingEventServiceImpl(boolean clearPersistentCompetitorStore, final TypeBasedServiceFinderFactory serviceFinderFactory, boolean restoreTrackedRaces) {
|
||||
this(clearPersistentCompetitorStore, serviceFinderFactory, null, /* sailingNotificationService */ null, restoreTrackedRaces);
|
||||
this(clearPersistentCompetitorStore, serviceFinderFactory, null, /* sailingNotificationService */ null, restoreTrackedRaces,null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -503,9 +506,10 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
||||
* @param sailingNotificationService
|
||||
* a notification service to call upon events worth notifying users about, or {@code null} if no
|
||||
* notification service is available, e.g., in test set-ups
|
||||
* @param anniversaryCalculator
|
||||
*/
|
||||
public RacingEventServiceImpl(boolean clearPersistentCompetitorStore, final TypeBasedServiceFinderFactory serviceFinderFactory,
|
||||
TrackedRegattaListener trackedRegattaListener, SailingNotificationService sailingNotificationService, boolean restoreTrackedRaces) {
|
||||
TrackedRegattaListener trackedRegattaListener, SailingNotificationService sailingNotificationService, boolean restoreTrackedRaces, AnniversaryCalculator anniversaryCalculator) {
|
||||
this((final RaceLogResolver raceLogResolver)-> {
|
||||
return new ConstructorParameters() {
|
||||
private final MongoObjectFactory mongoObjectFactory = PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory(serviceFinderFactory);
|
||||
@@ -519,6 +523,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
|
||||
@Override public CompetitorStore getCompetitorStore() { return competitorStore; }
|
||||
};
|
||||
}, MediaDBFactory.INSTANCE.getDefaultMediaDB(), null, null, serviceFinderFactory ,trackedRegattaListener, sailingNotificationService, restoreTrackedRaces);
|
||||
this.anniversaryCalculator = anniversaryCalculator;
|
||||
}
|
||||
|
||||
private RacingEventServiceImpl(final boolean clearPersistentCompetitorStore, WindStore windStore,
|
||||
|
||||
Reference in new issue
Block a user