EccentricityStorage.java
- /*
- * Licensed to GraphHopper GmbH under one or more contributor
- * license agreements. See the NOTICE file distributed with this work for
- * additional information regarding copyright ownership.
- *
- * GraphHopper GmbH licenses this file to you under the Apache License,
- * Version 2.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.heigit.ors.fastisochrones.storage;
- import com.carrotsearch.hppc.IntLongHashMap;
- import com.carrotsearch.hppc.cursors.IntLongCursor;
- import com.graphhopper.routing.weighting.Weighting;
- import com.graphhopper.storage.DataAccess;
- import com.graphhopper.storage.Directory;
- import com.graphhopper.storage.Storable;
- import org.heigit.ors.fastisochrones.partitioning.storage.IsochroneNodeStorage;
- import org.heigit.ors.util.FileUtility;
- import static org.heigit.ors.fastisochrones.storage.ByteConversion.byteArrayToLong;
- import static org.heigit.ors.fastisochrones.storage.ByteConversion.longToByteArray;
- /**
- * Stores eccentricities of cell border nodes for fast isochrones. Eccentricities are weighting dependent, therefore they are stored separately from cells.
- *
- * @author Hendrik Leuschner
- */
- public class EccentricityStorage implements Storable<EccentricityStorage> {
- private final DataAccess eccentricities;
- private final int eccentricityBytes;
- private final int mapBytes;
- private final int eccentricityPosition;
- private final int nodeCount;
- private final Weighting weighting;
- private final IsochroneNodeStorage isochroneNodeStorage;
- private int borderNodeIndexOffset;
- private int borderNodePointer;
- private IntLongHashMap borderNodeToPointerMap;
- private int borderNodeCount;
- /**
- * Instantiates a new Eccentricity storage.
- *
- * @param dir the dir
- * @param weighting the weighting
- * @param isochroneNodeStorage the isochrone node storage
- */
- public EccentricityStorage(Directory dir, Weighting weighting, IsochroneNodeStorage isochroneNodeStorage, int nodeCount) {
- //A map of nodeId to pointer is stored in the first block.
- //The second block stores 2 values for each pointer, full reachability and eccentricity
- final String name = FileUtility.weightingToFileName(weighting);
- eccentricities = dir.find("eccentricities_" + name);
- this.weighting = weighting;
- this.isochroneNodeStorage = isochroneNodeStorage;
- this.nodeCount = nodeCount;
- // 2 ints per node, first is fully reachable, second is eccentricity
- this.eccentricityBytes = 8;
- this.mapBytes = 12;
- this.eccentricityPosition = 4;
- }
- public boolean loadExisting() {
- if (eccentricities.loadExisting()) {
- borderNodeCount = eccentricities.getHeader(0);
- borderNodeIndexOffset = borderNodeCount * mapBytes;
- borderNodePointer = borderNodeIndexOffset;
- borderNodeToPointerMap = new IntLongHashMap(borderNodeCount);
- loadBorderNodeToPointerMap();
- return true;
- }
- return false;
- }
- /**
- * Init.
- */
- public void init() {
- eccentricities.create(1000);
- borderNodeCount = getNumBorderNodes();
- eccentricities.setHeader(0, borderNodeCount);
- borderNodeIndexOffset = borderNodeCount * mapBytes;
- borderNodePointer = borderNodeIndexOffset;
- borderNodeToPointerMap = new IntLongHashMap();
- generateBorderNodeToPointerMap();
- eccentricities.ensureCapacity((long) borderNodeIndexOffset + (long) borderNodeCount * eccentricityBytes);
- }
- private int getNumBorderNodes() {
- int count = 0;
- for (int node = 0; node < nodeCount; node++) {
- if (isochroneNodeStorage.getBorderness(node)) {
- count++;
- }
- }
- return count;
- }
- private void generateBorderNodeToPointerMap() {
- for (int node = 0; node < nodeCount; node++) {
- if (isochroneNodeStorage.getBorderness(node)) {
- borderNodeToPointerMap.put(node, borderNodePointer);
- borderNodePointer += (long) eccentricityBytes;
- }
- }
- }
- /**
- * Sets eccentricity.
- *
- * @param node the node
- * @param eccentricity the eccentricity
- */
- public void setEccentricity(int node, double eccentricity) {
- eccentricities.setInt(borderNodeToPointerMap.get(node) + eccentricityPosition, (int) Math.ceil(eccentricity));
- }
- /**
- * Gets eccentricity.
- *
- * @param node the node
- * @return the eccentricity
- */
- public int getEccentricity(int node) {
- long index = borderNodeToPointerMap.get(node);
- if (index == 0)
- throw new IllegalArgumentException("Requested node is not a border node");
- return eccentricities.getInt(index + eccentricityPosition);
- }
- /**
- * Sets fully reachable.
- *
- * @param node the node
- * @param isFullyReachable the is fully reachable
- */
- public void setFullyReachable(int node, boolean isFullyReachable) {
- if (isFullyReachable)
- eccentricities.setInt(borderNodeToPointerMap.get(node), 1);
- else
- eccentricities.setInt(borderNodeToPointerMap.get(node), 0);
- }
- /**
- * Gets fully reachable.
- *
- * @param node the node
- * @return the fully reachable
- */
- public boolean getFullyReachable(int node) {
- int isFullyReachable = eccentricities.getInt(borderNodeToPointerMap.get(node));
- return isFullyReachable == 1;
- }
- /**
- * Store border node to pointer map.
- */
- public void storeBorderNodeToPointerMap() {
- long listPointer = 0;
- long nodePointer;
- for (IntLongCursor borderNode : borderNodeToPointerMap) {
- eccentricities.setInt(listPointer, borderNode.key);
- listPointer = listPointer + 4;
- nodePointer = borderNode.value;
- eccentricities.setBytes(listPointer, longToByteArray(nodePointer), 8);
- listPointer = listPointer + 8;
- }
- }
- private void loadBorderNodeToPointerMap() {
- byte[] buffer = new byte[8];
- long listPointer = 0;
- for (int i = 0; i < borderNodeCount; i++) {
- int borderNode = eccentricities.getInt(listPointer);
- listPointer = listPointer + 4;
- eccentricities.getBytes(listPointer, buffer, 8);
- long nodePointer = byteArrayToLong(buffer);
- listPointer = listPointer + (long) 8;
- borderNodeToPointerMap.put(borderNode, nodePointer);
- }
- }
- public EccentricityStorage create(long byteCount) {
- throw new IllegalStateException("Do not call EccentricityStorage.create directly");
- }
- public void flush() {
- eccentricities.flush();
- }
- @Override
- public void close() {
- eccentricities.close();
- }
- @Override
- public boolean isClosed() {
- return eccentricities.isClosed();
- }
- public long getCapacity() {
- return eccentricities.getCapacity();
- }
- /**
- * Gets weighting.
- *
- * @return the weighting
- */
- public Weighting getWeighting() {
- return weighting;
- }
- public boolean hasWeighting(Weighting weighting) {
- return getWeighting().getName() != null
- && getWeighting().getName().equals(weighting.getName())
- && getWeighting().getFlagEncoder().toString() != null
- && getWeighting().getFlagEncoder().toString().equals(weighting.getFlagEncoder().toString());
- }
- }