package dk.daoas.adressevedligehold.afstandandenrute;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import ags.utils.dataStructures.MaxHeap;
import ags.utils.dataStructures.trees.thirdGenKD.DistanceFunction;
import ags.utils.dataStructures.trees.thirdGenKD.KdTree;
import ags.utils.dataStructures.trees.thirdGenKD.SquareEuclideanDistanceFunction;
import dk.daoas.adressevedligehold.ServiceConfig;
import dk.daoas.adressevedligehold.beans.Address;
import dk.daoas.adressevedligehold.tasks.Task;
import dk.daoas.adressevedligehold.tasks.TaskLogger;
public class LookupWorker implements Runnable {
static final int MAX_RESULTS = 99;
private TaskLogger logger = TaskLogger.getInstance();
OSRMHelper osrmHelper = new OSRMHelper();
CyclicBarrier barrier;
Queue
ikkeDaekkede;
Map> hoTrees;
DatabaseRouteDistance db;
Constants consts;
AtomicInteger antalFundne;
AtomicInteger antalBeregnet;
int workerID;
boolean verbose;
Task task;
DistanceFunction dist = new SquareEuclideanDistanceFunction();
public LookupWorker(int workerID,
Task task,
CyclicBarrier barrier,
Queue ikkeDaekkede,
Map> hoTrees,
AtomicInteger antalFundne,
AtomicInteger antalBeregnet,
DatabaseRouteDistance db,
boolean verbose,
Constants consts) {
this.workerID = workerID;
this.task = task;
this.barrier = barrier;
this.ikkeDaekkede = ikkeDaekkede;
this.hoTrees = hoTrees;
this.antalFundne = antalFundne;
this.antalBeregnet = antalBeregnet;
this.db = db;
this.verbose = verbose;
this.consts = consts;
}
@Override
public void run() {
logger.info( "Worker/" + workerID + " starting");
ServiceConfig conf = ServiceConfig.getInstance();
try (BarrierMarker marker = new BarrierMarker() ) {
while ( ! ikkeDaekkede.isEmpty() ) {
if (task.isAborted()) {
logger.info( "Worker/" + workerID + " aborting");
break;
}
Address qAddress = ikkeDaekkede.remove();
short ho = qAddress.ho;
KdTree addressTree = hoTrees.get(ho);
MaxHeap res = addressTree.findNearestNeighbors(qAddress.xyz, MAX_RESULTS, dist);
//Collection res = addressTree.nearestNeighbourSearch(MAX_RESULTS, qAddress);
int size = res.size();
if (size > MAX_RESULTS ) {
logger.info("Returnerede mere end MAX_RESULTS> " + res.size() );
throw new Exception("Returnerede mere end MAX_RESULTS> " + res.size());
}
ArrayList adrList = new ArrayList();
for (int i=0; i" + bedsteAdr + " ::: " + bedsteAfstand );
}
antalFundne.incrementAndGet();
try {
db.gemResultat(qAddress, bedsteAdr, bedsteAfstand);
} catch (SQLException e) {
logger.warning("Error saving result", e);
logger.warning("Shutting down");
throw e; // rethrow
}
} else {
if (verbose == true) {
logger.fine("For stor afstand: " + qAddress + " > " + bedsteAfstand);
}
}
antalBeregnet.incrementAndGet();
}
} catch (Exception e) {
logger.log( Level.SEVERE, "Worker/" + workerID, e);
task.doAbort();
}
logger.info( "Worker/" + workerID + " stopping");
}
/**
* Makes sure the barrier is touched correctly no matter how the the current code block is exited.
* @author thn
*
*/
public class BarrierMarker implements AutoCloseable {
@Override
public void close() {
try {
logger.info( "Worker/" + workerID + " afventer barrier");
barrier.await();
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
}
}
}