Repository: graphhopper/graphhopper
Pull request #1947 (2020-03-08 01:44:26)

avoid IntsRef recreation and simpler getter
reducing IntsRef creation should reduce GC activity a bit


Patch:
diff --git a/core/src/main/java/com/graphhopper/storage/TurnCostStorage.java b/core/src/main/java/com/graphhopper/storage/TurnCostStorage.java
index 46ec4c5cc..4a343aa9d 100644
--- a/core/src/main/java/com/graphhopper/storage/TurnCostStorage.java
+++ b/core/src/main/java/com/graphhopper/storage/TurnCostStorage.java
@@ -25,9 +25,9 @@ import com.graphhopper.util.EdgeIterator;
  * A key/value store, where the unique keys are turn relations, and the values are IntRefs.
  * A turn relation is a triple (fromEdge, viaNode, toEdge),
  * and refers to one of the possible ways of crossing an intersection.
- *
+ * <p>
  * Like IntRefs on edges, this can in principle be used to store values of any kind.
- *
+ * <p>
  * In practice, the IntRefs are used to store generalized travel costs per turn relation per vehicle type.
  * In practice, we only store 0 or infinity. (Can turn, or cannot turn.)
  *
@@ -242,15 +242,20 @@ public class TurnCostStorage implements Storable<TurnCostStorage> {
 
     public interface TurnRelationIterator {
         int getFromEdge();
+
         int getViaNode();
+
         int getToEdge();
-        IntsRef getFlags();
+
+        double getCost(DecimalEncodedValue encodedValue);
+
         boolean next();
     }
 
     private class Itr implements TurnRelationIterator {
         private int viaNode = -1;
         private int turnCostIndex = -1;
+        private IntsRef intsRef = TurnCost.createFlags();
 
         private long turnCostPtr() {
             return (long) turnCostIndex * BYTES_PER_ENTRY;
@@ -272,8 +277,9 @@ public class TurnCostStorage implements Storable<TurnCostStorage> {
         }
 
         @Override
-        public IntsRef getFlags() {
-            return new IntsRef(new int[]{turnCosts.getInt(turnCostPtr() + TC_FLAGS)}, 0, 1);
+        public double getCost(DecimalEncodedValue encodedValue) {
+            intsRef.ints[0] = turnCosts.getInt(turnCostPtr() + TC_FLAGS);
+            return encodedValue.getDecimal(false, intsRef);
         }
 
         @Override


Test patch:
diff --git a/core/src/test/java/com/graphhopper/storage/TurnCostStorageTest.java b/core/src/test/java/com/graphhopper/storage/TurnCostStorageTest.java
index 0832d0484..34b8a3688 100644
--- a/core/src/test/java/com/graphhopper/storage/TurnCostStorageTest.java
+++ b/core/src/test/java/com/graphhopper/storage/TurnCostStorageTest.java
@@ -19,7 +19,6 @@
 package com.graphhopper.storage;
 
 import com.graphhopper.routing.profiles.DecimalEncodedValue;
-import com.graphhopper.routing.profiles.EncodedValueLookup;
 import com.graphhopper.routing.profiles.TurnCost;
 import com.graphhopper.routing.util.BikeFlagEncoder;
 import com.graphhopper.routing.util.CarFlagEncoder;
@@ -28,7 +27,10 @@ import com.graphhopper.routing.util.FlagEncoder;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.util.*;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 
 import static com.graphhopper.util.GHUtility.getEdge;
 import static org.junit.Assert.assertEquals;
@@ -67,8 +69,8 @@ public class TurnCostStorageTest {
         initGraph(g);
         TurnCostStorage turnCostStorage = g.getTurnCostStorage();
 
-        DecimalEncodedValue car = ((EncodedValueLookup) manager).getDecimalEncodedValue(TurnCost.key("car"));
-        DecimalEncodedValue bike = ((EncodedValueLookup) manager).getDecimalEncodedValue(TurnCost.key("bike"));
+        DecimalEncodedValue carEnc = manager.getDecimalEncodedValue(TurnCost.key("car"));
+        DecimalEncodedValue bikeEnc = manager.getDecimalEncodedValue(TurnCost.key("bike"));
         int edge42 = getEdge(g, 4, 2).getEdge();
         int edge23 = getEdge(g, 2, 3).getEdge();
         int edge31 = getEdge(g, 3, 1).getEdge();
@@ -76,43 +78,44 @@ public class TurnCostStorageTest {
         int edge02 = getEdge(g, 0, 2).getEdge();
         int edge24 = getEdge(g, 2, 4).getEdge();
 
-        turnCostStorage.set(car, edge42, 2, edge23, Double.POSITIVE_INFINITY);
-        turnCostStorage.set(bike, edge42, 2, edge23, Double.POSITIVE_INFINITY);
-        turnCostStorage.set(car, edge23, 3, edge31, Double.POSITIVE_INFINITY);
-        turnCostStorage.set(bike, edge23, 3, edge31, 2.0);
-        turnCostStorage.set(car, edge31, 1, edge10, 2.0);
-        turnCostStorage.set(bike, edge31, 1, edge10, Double.POSITIVE_INFINITY);
-        turnCostStorage.set(bike, edge02, 2, edge24, Double.POSITIVE_INFINITY);
+        turnCostStorage.set(carEnc, edge42, 2, edge23, Double.POSITIVE_INFINITY);
+        turnCostStorage.set(bikeEnc, edge42, 2, edge23, Double.POSITIVE_INFINITY);
+        turnCostStorage.set(carEnc, edge23, 3, edge31, Double.POSITIVE_INFINITY);
+        turnCostStorage.set(bikeEnc, edge23, 3, edge31, 2.0);
+        turnCostStorage.set(carEnc, edge31, 1, edge10, 2.0);
+        turnCostStorage.set(bikeEnc, edge31, 1, edge10, Double.POSITIVE_INFINITY);
+        turnCostStorage.set(bikeEnc, edge02, 2, edge24, Double.POSITIVE_INFINITY);
 
-        assertEquals(Double.POSITIVE_INFINITY, turnCostStorage.get(car, edge42, 2, edge23), 0);
-        assertEquals(Double.POSITIVE_INFINITY, turnCostStorage.get(bike, edge42, 2, edge23), 0);
+        assertEquals(Double.POSITIVE_INFINITY, turnCostStorage.get(carEnc, edge42, 2, edge23), 0);
+        assertEquals(Double.POSITIVE_INFINITY, turnCostStorage.get(bikeEnc, edge42, 2, edge23), 0);
 
-        assertEquals(Double.POSITIVE_INFINITY, turnCostStorage.get(car, edge23, 3, edge31), 0);
-        assertEquals(2.0, turnCostStorage.get(bike, edge23, 3, edge31), 0);
+        assertEquals(Double.POSITIVE_INFINITY, turnCostStorage.get(carEnc, edge23, 3, edge31), 0);
+        assertEquals(2.0, turnCostStorage.get(bikeEnc, edge23, 3, edge31), 0);
 
-        assertEquals(2.0, turnCostStorage.get(car, edge31, 1, edge10), 0);
-        assertEquals(Double.POSITIVE_INFINITY, turnCostStorage.get(bike, edge31, 1, edge10), 0);
+        assertEquals(2.0, turnCostStorage.get(carEnc, edge31, 1, edge10), 0);
+        assertEquals(Double.POSITIVE_INFINITY, turnCostStorage.get(bikeEnc, edge31, 1, edge10), 0);
 
-        assertEquals(0.0, turnCostStorage.get(car, edge02, 2, edge24), 0);
-        assertEquals(Double.POSITIVE_INFINITY, turnCostStorage.get(bike, edge02, 2, edge24), 0);
+        assertEquals(0.0, turnCostStorage.get(carEnc, edge02, 2, edge24), 0);
+        assertEquals(Double.POSITIVE_INFINITY, turnCostStorage.get(bikeEnc, edge02, 2, edge24), 0);
 
-        turnCostStorage.set(car, edge02, 2, edge23, Double.POSITIVE_INFINITY);
-        turnCostStorage.set(bike, edge02, 2, edge23, Double.POSITIVE_INFINITY);
-        assertEquals(Double.POSITIVE_INFINITY, turnCostStorage.get(car, edge02, 2, edge23), 0);
-        assertEquals(Double.POSITIVE_INFINITY, turnCostStorage.get(bike, edge02, 2, edge23), 0);
+        turnCostStorage.set(carEnc, edge02, 2, edge23, Double.POSITIVE_INFINITY);
+        turnCostStorage.set(bikeEnc, edge02, 2, edge23, Double.POSITIVE_INFINITY);
+        assertEquals(Double.POSITIVE_INFINITY, turnCostStorage.get(carEnc, edge02, 2, edge23), 0);
+        assertEquals(Double.POSITIVE_INFINITY, turnCostStorage.get(bikeEnc, edge02, 2, edge23), 0);
 
         Set<List<Integer>> allTurnRelations = new HashSet<>();
         TurnCostStorage.TurnRelationIterator iterator = turnCostStorage.getAllTurnRelations();
         while (iterator.next()) {
-            allTurnRelations.add(Arrays.asList(iterator.getFromEdge(), iterator.getViaNode(),iterator.getToEdge(), (int) car.getDecimal(false, iterator.getFlags()), (int) bike.getDecimal(false, iterator.getFlags())));
+            allTurnRelations.add(Arrays.asList(iterator.getFromEdge(), iterator.getViaNode(), iterator.getToEdge(),
+                    (int) iterator.getCost(carEnc), (int) iterator.getCost(bikeEnc)));
         }
 
         Set<List<Integer>> expectedTurnRelations = new HashSet<>();
-        expectedTurnRelations.add(Arrays.asList(edge31,1,edge10,2,Integer.MAX_VALUE));
-        expectedTurnRelations.add(Arrays.asList(edge42,2,edge23,Integer.MAX_VALUE,Integer.MAX_VALUE));
-        expectedTurnRelations.add(Arrays.asList(edge02,2,edge24,0,Integer.MAX_VALUE));
-        expectedTurnRelations.add(Arrays.asList(edge02,2,edge23,Integer.MAX_VALUE,Integer.MAX_VALUE));
-        expectedTurnRelations.add(Arrays.asList(edge23,3,edge31,Integer.MAX_VALUE,2));
+        expectedTurnRelations.add(Arrays.asList(edge31, 1, edge10, 2, Integer.MAX_VALUE));
+        expectedTurnRelations.add(Arrays.asList(edge42, 2, edge23, Integer.MAX_VALUE, Integer.MAX_VALUE));
+        expectedTurnRelations.add(Arrays.asList(edge02, 2, edge24, 0, Integer.MAX_VALUE));
+        expectedTurnRelations.add(Arrays.asList(edge02, 2, edge23, Integer.MAX_VALUE, Integer.MAX_VALUE));
+        expectedTurnRelations.add(Arrays.asList(edge23, 3, edge31, Integer.MAX_VALUE, 2));
 
         assertEquals(expectedTurnRelations, allTurnRelations);
     }
@@ -123,24 +126,25 @@ public class TurnCostStorageTest {
         initGraph(g);
         TurnCostStorage turnCostStorage = g.getTurnCostStorage();
 
-        DecimalEncodedValue car = ((EncodedValueLookup) manager).getDecimalEncodedValue(TurnCost.key("car"));
-        DecimalEncodedValue bike = ((EncodedValueLookup) manager).getDecimalEncodedValue(TurnCost.key("bike"));
+        DecimalEncodedValue carEnc = manager.getDecimalEncodedValue(TurnCost.key("car"));
+        DecimalEncodedValue bikeEnc = manager.getDecimalEncodedValue(TurnCost.key("bike"));
         int edge23 = getEdge(g, 2, 3).getEdge();
         int edge02 = getEdge(g, 0, 2).getEdge();
 
-        turnCostStorage.set(car, edge02, 2, edge23, Double.POSITIVE_INFINITY);
-        turnCostStorage.set(bike, edge02, 2, edge23, Double.POSITIVE_INFINITY);
-        assertEquals(Double.POSITIVE_INFINITY, turnCostStorage.get(car, edge02, 2, edge23), 0);
-        assertEquals(Double.POSITIVE_INFINITY, turnCostStorage.get(bike, edge02, 2, edge23), 0);
+        turnCostStorage.set(carEnc, edge02, 2, edge23, Double.POSITIVE_INFINITY);
+        turnCostStorage.set(bikeEnc, edge02, 2, edge23, Double.POSITIVE_INFINITY);
+        assertEquals(Double.POSITIVE_INFINITY, turnCostStorage.get(carEnc, edge02, 2, edge23), 0);
+        assertEquals(Double.POSITIVE_INFINITY, turnCostStorage.get(bikeEnc, edge02, 2, edge23), 0);
 
         Set<List<Integer>> allTurnRelations = new HashSet<>();
         TurnCostStorage.TurnRelationIterator iterator = turnCostStorage.getAllTurnRelations();
         while (iterator.next()) {
-            allTurnRelations.add(Arrays.asList(iterator.getFromEdge(), iterator.getViaNode(),iterator.getToEdge(), (int) car.getDecimal(false, iterator.getFlags()), (int) bike.getDecimal(false, iterator.getFlags())));
+            allTurnRelations.add(Arrays.asList(iterator.getFromEdge(), iterator.getViaNode(), iterator.getToEdge(),
+                    (int) iterator.getCost(carEnc), (int) iterator.getCost(bikeEnc)));
         }
 
         Set<List<Integer>> expectedTurnRelations = new HashSet<>();
-        expectedTurnRelations.add(Arrays.asList(edge02,2,edge23,Integer.MAX_VALUE,Integer.MAX_VALUE));
+        expectedTurnRelations.add(Arrays.asList(edge02, 2, edge23, Integer.MAX_VALUE, Integer.MAX_VALUE));
 
         assertEquals(expectedTurnRelations, allTurnRelations);
     }