use of com.graphhopper.storage.change.ChangeGraphHelper in project graphhopper by graphhopper.
the class GraphHopperAPITest method testConcurrentGraphChange.
@Test
public void testConcurrentGraphChange() throws InterruptedException {
final GraphHopperStorage graph = new GraphBuilder(encodingManager).create();
initGraph(graph);
graph.edge(1, 2, 10, true);
final CountDownLatch latch = new CountDownLatch(1);
final AtomicInteger checkPointCounter = new AtomicInteger(0);
final GraphHopper graphHopper = new GraphHopper() {
@Override
protected ChangeGraphHelper createChangeGraphHelper(Graph graph, LocationIndex locationIndex) {
return new ChangeGraphHelper(graph, locationIndex) {
@Override
public long applyChanges(EncodingManager em, Collection<JsonFeature> features) {
// force sleep inside the lock and let the main thread run until the lock barrier
latch.countDown();
try {
Thread.sleep(400);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
checkPointCounter.incrementAndGet();
return super.applyChanges(em, features);
}
};
}
}.setStoreOnFlush(false).setEncodingManager(encodingManager).setCHEnabled(false).loadGraph(graph);
GHResponse rsp = graphHopper.route(new GHRequest(42, 10.4, 42, 10));
assertFalse(rsp.toString(), rsp.hasErrors());
assertEquals(1800, rsp.getBest().getTime());
final List<JsonFeature> list = new ArrayList<>();
Map<String, Object> properties = new HashMap<>();
properties.put("speed", 5);
list.add(new JsonFeature("1", "bbox", new BBox(10.399, 10.4, 42.0, 42.001), null, properties));
ExecutorService executorService = Executors.newFixedThreadPool(1);
executorService.submit(new Runnable() {
@Override
public void run() {
graphHopper.changeGraph(list);
checkPointCounter.incrementAndGet();
}
});
latch.await();
assertEquals(0, checkPointCounter.get());
rsp = graphHopper.route(new GHRequest(42, 10.4, 42, 10));
assertFalse(rsp.toString(), rsp.hasErrors());
assertEquals(8400, rsp.getBest().getTime());
executorService.shutdown();
executorService.awaitTermination(3, TimeUnit.SECONDS);
assertEquals(2, checkPointCounter.get());
}
use of com.graphhopper.storage.change.ChangeGraphHelper in project graphhopper by graphhopper.
the class GraphHopper method changeGraph.
/**
* This method applies the changes to the graph specified as feature collection. It does so by locking the routing
* to avoid concurrent changes which could result in incorrect routing (like when done while a Dijkstra search) or
* also while just reading one edge row (inconsistent edge properties).
*/
public ChangeGraphResponse changeGraph(Collection<JsonFeature> collection) {
// TODO allow calling this method if called before CH preparation
if (getCHFactoryDecorator().isEnabled())
throw new IllegalArgumentException("To use the changeGraph API you need to turn off CH");
Lock writeLock = readWriteLock.writeLock();
writeLock.lock();
try {
ChangeGraphHelper overlay = createChangeGraphHelper(ghStorage, locationIndex);
long updateCount = overlay.applyChanges(encodingManager, collection);
return new ChangeGraphResponse(updateCount);
} finally {
writeLock.unlock();
}
}
Aggregations