PreparePartition.java
package org.heigit.ors.fastisochrones.partitioning;
import com.graphhopper.storage.GraphHopperStorage;
import com.graphhopper.util.EdgeExplorer;
import com.graphhopper.util.EdgeIterator;
import org.heigit.ors.fastisochrones.partitioning.storage.CellStorage;
import org.heigit.ors.fastisochrones.partitioning.storage.IsochroneNodeStorage;
import org.heigit.ors.routing.graphhopper.extensions.edgefilters.EdgeFilterSequence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.ExecutorService;
import static org.heigit.ors.fastisochrones.partitioning.FastIsochroneParameters.getMaxThreadCount;
/**
* Prepares the partition of the graph.
* <p>
*
* @author Hendrik Leuschner
*/
public class PreparePartition {
private static final Logger LOGGER = LoggerFactory.getLogger(PreparePartition.class);
private final GraphHopperStorage ghStorage;
private final EdgeFilterSequence edgeFilters;
private final IsochroneNodeStorage isochroneNodeStorage;
private final CellStorage cellStorage;
private final int nodes;
public PreparePartition(GraphHopperStorage ghStorage, EdgeFilterSequence edgeFilters) {
this.ghStorage = ghStorage;
this.edgeFilters = edgeFilters;
this.nodes = ghStorage.getBaseGraph().getNodes();
this.isochroneNodeStorage = new IsochroneNodeStorage(this.nodes, ghStorage.getDirectory());
this.cellStorage = new CellStorage(this.nodes, ghStorage.getDirectory(), isochroneNodeStorage);
}
public PreparePartition prepare() {
//Use Inertialflow to calculate node id to cell
int[] nodeCellId = runInertialFlow();
//Identify border nodes
boolean[] nodeBorderness = calcBorderNodes(nodeCellId);
//Create and calculate isochrone info that is ordered by node
if (!isochroneNodeStorage.loadExisting()) {
isochroneNodeStorage.setCellIds(nodeCellId);
isochroneNodeStorage.setBorderness(nodeBorderness);
isochroneNodeStorage.flush();
}
//Info that is ordered by cell
if (!cellStorage.loadExisting()) {
cellStorage.init();
cellStorage.calcCellNodesMap();
cellStorage.flush();
}
return this;
}
private int[] runInertialFlow() {
int[] nodeToCellArray = new int[ghStorage.getNodes()];
ExecutorService threadPool = java.util.concurrent.Executors.newFixedThreadPool(Math.min(getMaxThreadCount(), Runtime.getRuntime().availableProcessors()));
InverseSemaphore inverseSemaphore = new InverseSemaphore();
inverseSemaphore.beforeSubmit();
LOGGER.debug("Submitting task for cell 1");
threadPool.execute(new InertialFlow(nodeToCellArray, ghStorage, edgeFilters, threadPool, inverseSemaphore));
try {
inverseSemaphore.awaitCompletion();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
LOGGER.error(e.getLocalizedMessage());
}
threadPool.shutdown();
return nodeToCellArray;
}
private boolean[] calcBorderNodes(int[] nodeCellId) {
boolean[] nodeBorderness = new boolean[this.nodes];
boolean borderness = false;
int adjNode;
EdgeExplorer ghEdgeExpl = ghStorage.getBaseGraph().createEdgeExplorer();
EdgeIterator edgeIter;
for (int baseNode = 0; baseNode < nodes; baseNode++) {
edgeIter = ghEdgeExpl.setBaseNode(baseNode);
while (edgeIter.next()) {
adjNode = edgeIter.getAdjNode();
if (nodeCellId[baseNode] != nodeCellId[adjNode]) {
borderness = true;
break;
}
}
nodeBorderness[baseNode] = borderness;
borderness = false;
}
return nodeBorderness;
}
public IsochroneNodeStorage getIsochroneNodeStorage() {
return isochroneNodeStorage;
}
public CellStorage getCellStorage() {
return cellStorage;
}
}