mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-07 12:51:02 +00:00
Merge branch 'master' of ssh://kielweek.web4sap.com/home/trac/git
This commit is contained in:
commit
40786f38f7
9 files changed
+108
-25
No files matched your search
+10
-3
@@ -57,7 +57,10 @@ public class DeclinationServiceImpl implements DeclinationService {
|
||||
int year = cal.get(Calendar.YEAR);
|
||||
QuadTree<Declination> set;
|
||||
while ((set = getYearStore(year)) != null) {
|
||||
Declination resultForYear = set.get(position);
|
||||
Declination resultForYear;
|
||||
synchronized (set) {
|
||||
resultForYear = set.get(position);
|
||||
}
|
||||
Distance spatialDistance = resultForYear.getPosition().getDistance(position);
|
||||
// consider result only if it's closer than maxDistance
|
||||
if (spatialDistance.compareTo(maxDistance) <= 0) {
|
||||
@@ -73,7 +76,9 @@ public class DeclinationServiceImpl implements DeclinationService {
|
||||
if (result == null) {
|
||||
QuadTree<Declination> importerCacheForYear = importerCache.get(year);
|
||||
if (importerCacheForYear != null) {
|
||||
result = importerCacheForYear.get(position);
|
||||
synchronized (importerCacheForYear) {
|
||||
result = importerCacheForYear.get(position);
|
||||
}
|
||||
if (result.getPosition().getDistance(position).compareTo(maxDistance) <= 0) {
|
||||
return result;
|
||||
// else it's further away from the requested position as demanded by maxDistance
|
||||
@@ -85,7 +90,9 @@ public class DeclinationServiceImpl implements DeclinationService {
|
||||
importerCacheForYear = new QuadTree<Declination>();
|
||||
importerCache.put(year, importerCacheForYear);
|
||||
}
|
||||
importerCacheForYear.put(result.getPosition(), result);
|
||||
synchronized (importerCacheForYear) {
|
||||
importerCacheForYear.put(result.getPosition(), result);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
+19
-5
@@ -49,7 +49,9 @@ public class DeclinationStore {
|
||||
result = new QuadTree<Declination>();
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(is));
|
||||
while ((record = readExternal(in)) != null) {
|
||||
result.put(record.getPosition(), record);
|
||||
synchronized (result) {
|
||||
result.put(record.getPosition(), record);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -150,7 +152,10 @@ public class DeclinationStore {
|
||||
System.out.println("Date: " + year + "/" + (month + 1) + ", Latitude: " + lat);
|
||||
for (double lng = 0; lng < 180; lng += grid) {
|
||||
Position point = new DegreePosition(lat, lng);
|
||||
Declination existingDeclinationRecord = storedDeclinations.get(point);
|
||||
Declination existingDeclinationRecord;
|
||||
synchronized (storedDeclinations) {
|
||||
existingDeclinationRecord = storedDeclinations.get(point);
|
||||
}
|
||||
if (existingDeclinationRecord == null
|
||||
|| DeclinationServiceImpl.timeAndSpaceDistance(existingDeclinationRecord
|
||||
.getPosition().getDistance(point), timePoint, existingDeclinationRecord
|
||||
@@ -161,7 +166,10 @@ public class DeclinationStore {
|
||||
}
|
||||
for (double lng = -grid; lng > -180; lng -= grid) {
|
||||
Position point = new DegreePosition(lat, lng);
|
||||
Declination existingDeclinationRecord = storedDeclinations.get(point);
|
||||
Declination existingDeclinationRecord;
|
||||
synchronized (storedDeclinations) {
|
||||
existingDeclinationRecord = storedDeclinations.get(point);
|
||||
}
|
||||
if (existingDeclinationRecord == null
|
||||
|| DeclinationServiceImpl.timeAndSpaceDistance(existingDeclinationRecord
|
||||
.getPosition().getDistance(point), timePoint, existingDeclinationRecord
|
||||
@@ -175,7 +183,10 @@ public class DeclinationStore {
|
||||
System.out.println("Date: " + year + "/" + (month + 1) + ", Latitude: " + lat);
|
||||
for (double lng = 0; lng < 180; lng += grid) {
|
||||
Position point = new DegreePosition(lat, lng);
|
||||
Declination existingDeclinationRecord = storedDeclinations.get(point);
|
||||
Declination existingDeclinationRecord;
|
||||
synchronized (storedDeclinations) {
|
||||
existingDeclinationRecord = storedDeclinations.get(point);
|
||||
}
|
||||
if (DeclinationServiceImpl.timeAndSpaceDistance(existingDeclinationRecord.getPosition().getDistance(point),
|
||||
timePoint, existingDeclinationRecord.getTimePoint()) > 0.1) {
|
||||
// less than ~6 nautical miles and/or ~.6 months off
|
||||
@@ -184,7 +195,10 @@ public class DeclinationStore {
|
||||
}
|
||||
for (double lng = -grid; lng > -180; lng -= grid) {
|
||||
Position point = new DegreePosition(lat, lng);
|
||||
Declination existingDeclinationRecord = storedDeclinations.get(point);
|
||||
Declination existingDeclinationRecord;
|
||||
synchronized (storedDeclinations) {
|
||||
existingDeclinationRecord = storedDeclinations.get(point);
|
||||
}
|
||||
if (DeclinationServiceImpl.timeAndSpaceDistance(existingDeclinationRecord.getPosition().getDistance(point),
|
||||
timePoint, existingDeclinationRecord.getTimePoint()) > 0.1) {
|
||||
// less than ~6 nautical miles and/or ~.6 months off
|
||||
|
||||
@@ -7,4 +7,5 @@ Bundle-Vendor: SAP
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
Export-Package: com.sap.sailing.domain.common,
|
||||
com.sap.sailing.domain.common.impl,
|
||||
com.sap.sailing.domain.common.quadtree
|
||||
com.sap.sailing.domain.common.quadtree,
|
||||
com.sap.sailing.domain.common.quadtree.impl;x-friends:="com.sap.sailing.domain.test"
|
||||
+6
-3
@@ -12,9 +12,12 @@ public class AbstractPosition implements Position {
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return o instanceof Position &&
|
||||
getLatRad() == ((Position) o).getLatRad() &&
|
||||
getLngRad() == ((Position) o).getLngRad();
|
||||
if (o == null) {
|
||||
return false;
|
||||
} else {
|
||||
return o instanceof Position && getLatRad() == ((Position) o).getLatRad()
|
||||
&& getLngRad() == ((Position) o).getLngRad();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+9
-4
@@ -32,11 +32,16 @@ import com.sap.sailing.domain.common.quadtree.impl.Bounds;
|
||||
import com.sap.sailing.domain.common.quadtree.impl.QuadTreeNode;
|
||||
|
||||
/**
|
||||
* The QuadTree lets you organize objects in a grid, that redefines
|
||||
* itself and focuses more gridding when more objects appear in a
|
||||
* certain area.
|
||||
* The QuadTree lets you organize objects in a grid, that redefines itself and focuses more gridding when more objects
|
||||
* appear in a certain area.
|
||||
* <p>
|
||||
*
|
||||
* @param <T> type of object stored by coordinates
|
||||
* Note that this class is not thread safe. If multiple threads can access the same instance concurrently, callers have
|
||||
* to ensure proper synchronization. Concurrent reads are permissible while any write should block all other operations.
|
||||
*
|
||||
* @param <T>
|
||||
* type of object stored by coordinates
|
||||
* @author Axel Uhl (D043530)
|
||||
*/
|
||||
public class QuadTree<T> implements Serializable {
|
||||
|
||||
|
||||
+3
-5
@@ -110,7 +110,7 @@ public class QuadTreeNode<T> implements Serializable {
|
||||
* into the children.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void split() {
|
||||
protected void split() {
|
||||
// Make sure we're bigger than the minimum, if we care,
|
||||
if (minSize != NO_MIN_SIZE) {
|
||||
if (Math.abs(bounds.getNorthEast().getLatDeg() - bounds.getSouthWest().getLatDeg()) < minSize
|
||||
@@ -121,7 +121,6 @@ public class QuadTreeNode<T> implements Serializable {
|
||||
double nsHalf = (bounds.getNorthEast().getLatDeg() + bounds.getSouthWest().getLatDeg()) / 2.0;
|
||||
double ewHalf = (bounds.getNorthEast().getLngDeg() + bounds.getSouthWest().getLngDeg()) / 2.0;
|
||||
children = new QuadTreeNode[4];
|
||||
|
||||
children[NORTHWEST] = new QuadTreeNode<T>(new Bounds(new DegreePosition(nsHalf, bounds.getSouthWest().getLngDeg()), new DegreePosition(bounds.getNorthEast().getLatDeg(), ewHalf)), maxItems);
|
||||
children[NORTHEAST] = new QuadTreeNode<T>(new Bounds(new DegreePosition(nsHalf, ewHalf), bounds.getNorthEast()), maxItems);
|
||||
children[SOUTHEAST] = new QuadTreeNode<T>(new Bounds(new DegreePosition(bounds.getSouthWest().getLatDeg(), ewHalf), new DegreePosition(nsHalf, bounds.getNorthEast().getLngDeg())), maxItems);
|
||||
@@ -131,7 +130,6 @@ public class QuadTreeNode<T> implements Serializable {
|
||||
for (Iterator<QuadTreeLeaf<T>> i=temp.iterator(); i.hasNext(); ) {
|
||||
put(i.next());
|
||||
}
|
||||
//items.removeAllElements();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -208,9 +206,9 @@ public class QuadTreeNode<T> implements Serializable {
|
||||
this.allTheSamePoint = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.items.size() > maxItems && !this.allTheSamePoint)
|
||||
if (this.items.size() > maxItems && !this.allTheSamePoint) {
|
||||
split();
|
||||
}
|
||||
} else {
|
||||
QuadTreeNode<T> node = getChild(leaf.getPoint());
|
||||
if (node != null) {
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package com.sap.sailing.domain.test;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.quadtree.QuadTree;
|
||||
import com.sap.sailing.domain.common.quadtree.impl.QuadTreeNode;
|
||||
|
||||
public class QuadTreeTest {
|
||||
private class GLatLngQuadTree extends QuadTree<Position> {
|
||||
@@ -21,6 +23,53 @@ public class QuadTreeTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static class QuadTreeWithPublicGetTop<T> extends QuadTree<T> {
|
||||
private static final long serialVersionUID = -783622065160380333L;
|
||||
@Override
|
||||
public QuadTreeNode<T> getTop() {
|
||||
return super.getTop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoNPEDuringSecondPutInSameLeaf() {
|
||||
final QuadTreeWithPublicGetTop<Object> qt = new QuadTreeWithPublicGetTop<Object>();
|
||||
final Position p = new DegreePosition(0, 0);
|
||||
final NullPointerException[] npe = new NullPointerException[1];
|
||||
final boolean[] stop = new boolean[1];
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
while (!stop[0]) {
|
||||
synchronized (qt) {
|
||||
try {
|
||||
qt.wait();
|
||||
// if the following try/catch is moved outside the synchronized block, occasional NPEs result
|
||||
try {
|
||||
qt.put(p, p);
|
||||
} catch (NullPointerException e) {
|
||||
npe[0] = e;
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
new Thread(r, "1").start();
|
||||
new Thread(r, "2").start();
|
||||
new Thread(r, "3").start();
|
||||
new Thread(r, "4").start();
|
||||
for (int i=0; i<10000000; i++) {
|
||||
synchronized(qt) {
|
||||
qt.notifyAll();
|
||||
}
|
||||
assertNull("NullPointerException "+(npe[0]==null?"":npe[0].getMessage())+" during iteration "+i, npe[0]);
|
||||
}
|
||||
stop[0] = true;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDistance() {
|
||||
GLatLngQuadTree quadtree = new GLatLngQuadTree(new DegreePosition(49.29,
|
||||
|
||||
+9
-3
@@ -194,7 +194,9 @@ public class ReverseGeocoderImpl implements ReverseGeocoder {
|
||||
private void cachePlacemarks(Position position, Double radius, List<Placemark> placemarks) {
|
||||
Collections.sort(placemarks, new Placemark.ByDistance(position));
|
||||
if (position != null) {
|
||||
cache.put(position, new Triple<Position, Double, List<Placemark>>(position, radius, placemarks));
|
||||
synchronized (cache) {
|
||||
cache.put(position, new Triple<Position, Double, List<Placemark>>(position, radius, placemarks));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,7 +213,9 @@ public class ReverseGeocoderImpl implements ReverseGeocoder {
|
||||
*/
|
||||
private void updateCachedPlacemarks(Position cachedPoint, Double newRadius, List<Placemark> newPlacemarks) {
|
||||
if (cachedPoint != null) {
|
||||
cache.replace(cachedPoint, new Triple<Position, Double, List<Placemark>>(cachedPoint, newRadius, newPlacemarks));
|
||||
synchronized (cache) {
|
||||
cache.replace(cachedPoint, new Triple<Position, Double, List<Placemark>>(cachedPoint, newRadius, newPlacemarks));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,7 +227,9 @@ public class ReverseGeocoderImpl implements ReverseGeocoder {
|
||||
* {@link ReverseGeocoderImpl#POSITION_CACHE_DISTANCE_LIMIT the distance limit}
|
||||
*/
|
||||
private Triple<Position, Double, List<Placemark>> checkCache(Position position) {
|
||||
return cache.get(position, POSITION_CACHE_DISTANCE_LIMIT);
|
||||
synchronized (cache) {
|
||||
return cache.get(position, POSITION_CACHE_DISTANCE_LIMIT);
|
||||
}
|
||||
}
|
||||
|
||||
private JSONArray callNearestService(Position position) throws MalformedURLException, IOException, ParseException {
|
||||
|
||||
+1
-1
@@ -1772,7 +1772,7 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
groupDTO.name = leaderboardGroup.getName();
|
||||
groupDTO.description = leaderboardGroup.getDescription();
|
||||
for (Leaderboard leaderboard : leaderboardGroup.getLeaderboards()) {
|
||||
groupDTO.leaderboards.add(createStrippedLeaderboardDTO(leaderboard, false));
|
||||
groupDTO.leaderboards.add(createStrippedLeaderboardDTO(leaderboard, true));
|
||||
}
|
||||
return groupDTO;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user