Repository: graphhopper/graphhopper (java)

Issue:
QueryGraph edge-explorer cache does not work for edge-based CH.
We can do 
```java
queryGraph.setUseEdgeExplorerCache(true);
```
and 
```java
queryGraph.createEdgeExplorer(edgeFilter)
```
will return the same edge-explorer instance for all subsequent calls of `DefaultEdgeFilter.inEdges`, `DefaultEdgeFilter.outEdges`, `DefaultEdgeFilter.allEdges` and `EdgeFilter.ALL_EDGES` (for each of these filters there will be a separate edge-explorer instance).

The problem is that in some cases we explicitly need to create two different instances for the same filter. This is not needed very often, but for example here: 

https://github.com/graphhopper/graphhopper/blob/d24173a188f4574b6eb9e7c6ff641eaec9029208/core/src/main/java/com/graphhopper/routing/AbstractBidirectionEdgeCHNoSOD.java#L46-L48

there is a nested loop over edge iterators where the 'inner' explorer must be different to the 'outer' one.

Because of this using the edge-explorer cache with edge-based CH fails at the moment.

I started adding a test for the query graph behavior here: https://github.com/graphhopper/graphhopper/commit/58e7ac1777c2382d5a42dd7c9153c2de65e31a28, but so far it does not show much, obviously if we use the same instance of the edge explorer within an inner loop the outer loop will be messed up.




Pull request description:
Makes QueryGraph's edge-explorer cache work for all EdgeFilters, fixes #1623.
1) `QueryGraph` caches edge-explorers based on the identity of the `EdgeFilter`s passed into `createEdgeExplorer`
2) fixes edge-based CH in combination with edge-explorer cache (by setting explicit filter ids)
3) deprecates creators of `DefaultEdgeFilter` using `FlagEncoder` (and adds new ones taking only access encoded value instead)
4) replaces `PrepEdgeFilter` with `DefaultEdgeFilter` in `PrepareRoutingSubnetworks` (it did not really do anything different than `DefaultEdgeFilter#allEdges`).

Most changed files are due to 3), and not sure about this. 
- good: `DefaultEdgeFilter` is decoupled from `FlagEncoder`
- bad: it changes a frequently used API and its a bit less comfortable because in most cases we have to pass `flagEncoder.getAccessEnc()` instead of simply `flagEncoder`. Also 3) is a bit unrelated to the actual issue #1623. 

WDYT ? I can also revert this.

Patch:
diff --git a/core/src/main/java/com/graphhopper/routing/AbstractBidirectionEdgeCHNoSOD.java b/core/src/main/java/com/graphhopper/routing/AbstractBidirectionEdgeCHNoSOD.java
index ed9d5b9bf..2d1550e23 100644
--- a/core/src/main/java/com/graphhopper/routing/AbstractBidirectionEdgeCHNoSOD.java
+++ b/core/src/main/java/com/graphhopper/routing/AbstractBidirectionEdgeCHNoSOD.java
@@ -44,8 +44,10 @@ public abstract class AbstractBidirectionEdgeCHNoSOD extends AbstractBidirAlgo {
         super(graph, weighting, TraversalMode.EDGE_BASED_2DIR);
         this.turnWeighting = weighting;
         // we need extra edge explorers, because they get called inside a loop that already iterates over edges
-        innerInExplorer = graph.createEdgeExplorer(DefaultEdgeFilter.inEdges(flagEncoder));
-        innerOutExplorer = graph.createEdgeExplorer(DefaultEdgeFilter.outEdges(flagEncoder));
+        // important: we have to use different filter ids, otherwise this will not work with QueryGraph's edge explorer
+        // cache, see #1623.
+        innerInExplorer = graph.createEdgeExplorer(DefaultEdgeFilter.inEdges(flagEncoder).setFilterId(1));
+        innerOutExplorer = graph.createEdgeExplorer(DefaultEdgeFilter.outEdges(flagEncoder).setFilterId(1));
         if (!(graph.getExtension() instanceof TurnCostExtension)) {
             throw new IllegalArgumentException("edge-based CH algorithms require a turn cost extension");
         }
diff --git a/core/src/main/java/com/graphhopper/routing/QueryGraph.java b/core/src/main/java/com/graphhopper/routing/QueryGraph.java
index 7e96ad677..f3c1fecb7 100644
--- a/core/src/main/java/com/graphhopper/routing/QueryGraph.java
+++ b/core/src/main/java/com/graphhopper/routing/QueryGraph.java
@@ -57,8 +57,7 @@ public class QueryGraph implements Graph {
     private final int mainEdges;
     private final QueryGraph baseGraph;
     private final GraphExtension wrappedExtension;
-    // TODO when spreading it on different threads we need multiple independent explorers
-    private final Map<Integer, EdgeExplorer> cacheMap = new HashMap<>(4);
+    private final Map<EdgeFilter, EdgeExplorer> cacheMap = new HashMap<>(4);
 
     // For every virtual node there are 4 edges: base-snap, snap-base, snap-adj, adj-snap.
     List<VirtualEdgeIteratorState> virtualEdges;
@@ -372,11 +371,11 @@ public class QueryGraph implements Graph {
 
     /**
      * This method is an experimental feature to reduce memory and CPU resources if there are many
-     * locations ("hundreds") for one QueryGraph. It can make problems for custom or threaded
-     * algorithms or when using custom EdgeFilters for EdgeExplorer creation. Another limitation is
-     * that the same edge explorer is used even if a different vehicle/flagEncoder is chosen.
-     * Currently we can cache only the ALL_EDGES filter or instances of the DefaultEdgeFilter where
-     * three edge explorers will be created: forward OR backward OR both.
+     * locations ("hundreds") for one QueryGraph. EdgeExplorer instances are cached based on the {@link EdgeFilter}
+     * passed into {@link #createEdgeExplorer(EdgeFilter)}. For equal (in the java sense) {@link EdgeFilter}s always
+     * the same {@link EdgeExplorer} will be returned when caching is enabled. Care has to be taken for example for
+     * custom or threaded algorithms, when using custom {@link EdgeFilter}s, or when the same edge explorer is used
+     * with different vehicles/encoders.
      */
     public QueryGraph setUseEdgeExplorerCache(boolean useEECache) {
         this.useEdgeExplorerCache = useEECache;
@@ -575,32 +574,15 @@ public class QueryGraph implements Graph {
             throw new IllegalStateException("Call lookup before using this graph");
 
         if (useEdgeExplorerCache) {
-            int counter = -1;
-            if (edgeFilter instanceof DefaultEdgeFilter) {
-                DefaultEdgeFilter dee = (DefaultEdgeFilter) edgeFilter;
-                counter = 0;
-                if (dee.acceptsBackward())
-                    counter = 1;
-                if (dee.acceptsForward())
-                    counter += 2;
-
-                if (counter == 0)
-                    throw new IllegalStateException("You tried to use an edge filter blocking every access");
-
-            } else if (edgeFilter == EdgeFilter.ALL_EDGES) {
-                counter = 4;
-            }
-
-            if (counter >= 0) {
-                EdgeExplorer cached = cacheMap.get(counter);
-                if (cached == null) {
-                    cached = createUncachedEdgeExplorer(edgeFilter);
-                    cacheMap.put(counter, cached);
-                }
-                return cached;
+            EdgeExplorer cached = cacheMap.get(edgeFilter);
+            if (cached == null) {
+                cached = createUncachedEdgeExplorer(edgeFilter);
+                cacheMap.put(edgeFilter, cached);
             }
+            return cached;
+        } else {
+            return createUncachedEdgeExplorer(edgeFilter);
         }
-        return createUncachedEdgeExplorer(edgeFilter);
     }
 
     private EdgeExplorer createUncachedEdgeExplorer(EdgeFilter edgeFilter) {
diff --git a/core/src/main/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworks.java b/core/src/main/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworks.java
index 91659fb0f..69b8f0eb7 100644
--- a/core/src/main/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworks.java
+++ b/core/src/main/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworks.java
@@ -79,7 +79,7 @@ public class PrepareRoutingSubnetworks {
         int unvisitedDeadEnds = 0;
         for (FlagEncoder encoder : encoders) {
             // mark edges for one vehicle as inaccessible
-            PrepEdgeFilter filter = new PrepEdgeFilter(encoder);
+            DefaultEdgeFilter filter = DefaultEdgeFilter.allEdges(encoder);
             if (minOneWayNetworkSize > 0)
                 unvisitedDeadEnds += removeDeadEndUnvisitedNetworks(filter);
 
@@ -104,7 +104,7 @@ public class PrepareRoutingSubnetworks {
     /**
      * This method finds the double linked components according to the specified filter.
      */
-    List<IntArrayList> findSubnetworks(PrepEdgeFilter filter) {
+    List<IntArrayList> findSubnetworks(DefaultEdgeFilter filter) {
         final BooleanEncodedValue accessEnc = filter.getAccessEnc();
         final EdgeExplorer explorer = ghStorage.createEdgeExplorer(filter);
         int locs = ghStorage.getNodes();
@@ -152,7 +152,7 @@ public class PrepareRoutingSubnetworks {
     /**
      * Deletes all but the largest subnetworks.
      */
-    int keepLargeNetworks(PrepEdgeFilter filter, List<IntArrayList> components) {
+    int keepLargeNetworks(DefaultEdgeFilter filter, List<IntArrayList> components) {
         if (components.size() <= 1)
             return 0;
 
@@ -195,7 +195,7 @@ public class PrepareRoutingSubnetworks {
      *
      * @return number of removed edges
      */
-    int removeDeadEndUnvisitedNetworks(final PrepEdgeFilter bothFilter) {
+    int removeDeadEndUnvisitedNetworks(final DefaultEdgeFilter bothFilter) {
         StopWatch sw = new StopWatch(bothFilter.getAccessEnc() + " findComponents").start();
         final EdgeFilter outFilter = DefaultEdgeFilter.outEdges(bothFilter.getAccessEnc());
 
@@ -213,7 +213,7 @@ public class PrepareRoutingSubnetworks {
      *
      * @return number of removed edges
      */
-    int removeEdges(final PrepEdgeFilter bothFilter, List<IntArrayList> components, int min) {
+    int removeEdges(final DefaultEdgeFilter bothFilter, List<IntArrayList> components, int min) {
         // remove edges determined from nodes but only if less than minimum size
         EdgeExplorer explorer = ghStorage.createEdgeExplorer(bothFilter);
         int removedEdges = 0;
@@ -270,15 +270,4 @@ public class PrepareRoutingSubnetworks {
 
         return true;
     }
-
-    static class PrepEdgeFilter extends DefaultEdgeFilter {
-
-        public PrepEdgeFilter(FlagEncoder encoder) {
-            super(encoder.getAccessEnc(), true, true);
-        }
-
-        public BooleanEncodedValue getAccessEnc() {
-            return accessEnc;
-        }
-    }
 }
diff --git a/core/src/main/java/com/graphhopper/routing/util/DefaultEdgeFilter.java b/core/src/main/java/com/graphhopper/routing/util/DefaultEdgeFilter.java
index cc499b0a1..1ae1fb402 100644
--- a/core/src/main/java/com/graphhopper/routing/util/DefaultEdgeFilter.java
+++ b/core/src/main/java/com/graphhopper/routing/util/DefaultEdgeFilter.java
@@ -24,26 +24,28 @@ import com.graphhopper.util.EdgeIteratorState;
  * @author Peter Karich
  */
 public class DefaultEdgeFilter implements EdgeFilter {
+    private static int DEFAULT_FILTER_ID = 0;
     private final boolean bwd;
     private final boolean fwd;
-    protected final BooleanEncodedValue accessEnc;
+    private final BooleanEncodedValue accessEnc;
+    /**
+     * Used to be able to create non-equal filter instances with equal access encoder and fwd/bwd flags.
+     */
+    private int filterId;
 
-    protected DefaultEdgeFilter(BooleanEncodedValue accessEnc, boolean fwd, boolean bwd) {
+    private DefaultEdgeFilter(BooleanEncodedValue accessEnc, boolean fwd, boolean bwd, int filterId) {
         this.accessEnc = accessEnc;
         this.fwd = fwd;
         this.bwd = bwd;
+        this.filterId = filterId;
     }
 
     public static DefaultEdgeFilter outEdges(BooleanEncodedValue accessEnc) {
-        return new DefaultEdgeFilter(accessEnc, true, false);
+        return new DefaultEdgeFilter(accessEnc, true, false, DEFAULT_FILTER_ID);
     }
 
-    public static DefaultEdgeFilter outEdges(FlagEncoder flagEncoder) {
-        return new DefaultEdgeFilter(flagEncoder.getAccessEnc(), true, false);
-    }
-
-    public static DefaultEdgeFilter inEdges(FlagEncoder flagEncoder) {
-        return new DefaultEdgeFilter(flagEncoder.getAccessEnc(), false, true);
+    public static DefaultEdgeFilter inEdges(BooleanEncodedValue accessEnc) {
+        return new DefaultEdgeFilter(accessEnc, false, true, DEFAULT_FILTER_ID);
     }
 
     /**
@@ -51,8 +53,29 @@ public class DefaultEdgeFilter implements EdgeFilter {
      * Edges where neither one of the flags is enabled will still not be accepted. If you need to retrieve all edges
      * regardless of their encoding use {@link EdgeFilter#ALL_EDGES} instead.
      */
+    public static DefaultEdgeFilter allEdges(BooleanEncodedValue accessEnc) {
+        return new DefaultEdgeFilter(accessEnc, true, true, DEFAULT_FILTER_ID);
+    }
+
+    public static DefaultEdgeFilter outEdges(FlagEncoder flagEncoder) {
+        return DefaultEdgeFilter.outEdges(flagEncoder.getAccessEnc());
+    }
+
+    public static DefaultEdgeFilter inEdges(FlagEncoder flagEncoder) {
+        return DefaultEdgeFilter.inEdges(flagEncoder.getAccessEnc());
+    }
+
     public static DefaultEdgeFilter allEdges(FlagEncoder flagEncoder) {
-        return new DefaultEdgeFilter(flagEncoder.getAccessEnc(), true, true);
+        return DefaultEdgeFilter.allEdges(flagEncoder.getAccessEnc());
+    }
+
+    public DefaultEdgeFilter setFilterId(int filterId) {
+        this.filterId = filterId;
+        return this;
+    }
+
+    public BooleanEncodedValue getAccessEnc() {
+        return accessEnc;
     }
 
     @Override
@@ -67,16 +90,30 @@ public class DefaultEdgeFilter implements EdgeFilter {
         return fwd && iter.get(accessEnc) || bwd && iter.getReverse(accessEnc);
     }
 
-    public boolean acceptsBackward() {
-        return bwd;
+    @Override
+    public String toString() {
+        return accessEnc.toString() + ", bwd:" + bwd + ", fwd:" + fwd;
     }
 
-    public boolean acceptsForward() {
-        return fwd;
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        DefaultEdgeFilter that = (DefaultEdgeFilter) o;
+
+        if (bwd != that.bwd) return false;
+        if (fwd != that.fwd) return false;
+        if (filterId != that.filterId) return false;
+        return accessEnc.equals(that.accessEnc);
     }
 
     @Override
-    public String toString() {
-        return accessEnc.toString() + ", bwd:" + bwd + ", fwd:" + fwd;
+    public int hashCode() {
+        int result = (bwd ? 1 : 0);
+        result = 31 * result + (fwd ? 1 : 0);
+        result = 31 * result + accessEnc.hashCode();
+        result = 31 * result + filterId;
+        return result;
     }
 }


Test patch:
diff --git a/core/src/test/java/com/graphhopper/routing/QueryGraphTest.java b/core/src/test/java/com/graphhopper/routing/QueryGraphTest.java
index 076a51ec5..fda2a4854 100644
--- a/core/src/test/java/com/graphhopper/routing/QueryGraphTest.java
+++ b/core/src/test/java/com/graphhopper/routing/QueryGraphTest.java
@@ -33,9 +33,7 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedHashSet;
+import java.util.*;
 
 import static com.graphhopper.storage.index.QueryResult.Position.*;
 import static org.junit.Assert.*;
@@ -678,7 +676,55 @@ public class QueryGraphTest {
 
         EdgeExplorer edgeExplorer = queryGraph.createEdgeExplorer();
         // using cache means same reference
-        assertTrue(edgeExplorer == queryGraph.createEdgeExplorer());
+        assertSame(edgeExplorer, queryGraph.createEdgeExplorer());
+    }
+
+    @Test
+    public void useEECache_nestedLoop() {
+        //
+        // 0->3
+        // |\
+        // 1 2->6
+        //   |\
+        //   4 5
+        g.edge(0, 1, 10, false);
+        g.edge(0, 2, 10, false);
+        g.edge(0, 3, 10, false);
+        g.edge(2, 4, 10, false);
+        g.edge(2, 5, 10, false);
+        g.edge(2, 6, 10, false);
+
+        EdgeExplorer explorer = g.createEdgeExplorer();
+        EdgeIterator iter = explorer.setBaseNode(0);
+        assertTrue(iter.next());
+        QueryResult res = createLocationResult(0, 0, iter, 1, PILLAR);
+
+        QueryGraph queryGraph = new QueryGraph(g).setUseEdgeExplorerCache(true);
+        queryGraph.lookup(Collections.singletonList(res));
+
+        EdgeExplorer outerEdgeExplorer = queryGraph.createEdgeExplorer(DefaultEdgeFilter.outEdges(carEncoder));
+        EdgeExplorer innerEdgeExplorer = queryGraph.createEdgeExplorer(DefaultEdgeFilter.outEdges(carEncoder));
+
+        // without using filter id for DefaultEdgeFilter the filters are equal and using the explorers in a nested
+        // loop would fail
+        assertSame(outerEdgeExplorer, innerEdgeExplorer);
+
+        // using a different filter id for the second filter we get different explorers
+        outerEdgeExplorer = queryGraph.createEdgeExplorer(DefaultEdgeFilter.outEdges(carEncoder));
+        innerEdgeExplorer = queryGraph.createEdgeExplorer(DefaultEdgeFilter.outEdges(carEncoder).setFilterId(1));
+        assertNotSame(outerEdgeExplorer, innerEdgeExplorer);
+
+        // now we can safely use the two explorers in a nested loop
+        Set<String> edges = new HashSet<>();
+        EdgeIterator outerIter = outerEdgeExplorer.setBaseNode(0);
+        while (outerIter.next()) {
+            edges.add("o" + outerIter.getBaseNode() + "-" + outerIter.getAdjNode());
+            EdgeIterator innerIter = innerEdgeExplorer.setBaseNode(outerIter.getAdjNode());
+            while (innerIter.next()) {
+                edges.add("i" + innerIter.getBaseNode() + "-" + innerIter.getAdjNode());
+            }
+        }
+        assertEquals(new HashSet<>(Arrays.asList("o0-1", "o0-2", "o0-3", "i2-4", "i2-5", "i2-6")), edges);
     }
 
     @Test
diff --git a/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java b/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java
index a6d7602ac..20b425e28 100644
--- a/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java
+++ b/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java
@@ -849,6 +849,43 @@ public class CHTurnCostTest {
         assertFalse("no path should be found, but found " + path.calcNodes(), path.isFound());
     }
 
+    @Test
+    public void test_issue_1623_query_graph_cache() {
+        // 4-2->5-3
+        NodeAccess na = graph.getNodeAccess();
+        na.setNode(0, 49.408550, 9.701805);
+        na.setNode(1, 49.405988, 9.706111);
+        na.setNode(2, 49.400772, 9.706245);
+        na.setNode(3, 49.403167, 9.704774);
+        na.setNode(4, 49.405817, 9.704301);
+        na.setNode(5, 49.402488, 9.707799);
+        graph.edge(2, 5, 222.771000, false);
+        graph.edge(4, 2, 583.496000, true);
+        graph.edge(3, 5, 231.495000, true);
+        graph.freeze();
+
+        RoutingAlgorithmFactory pch = automaticPrepareCH();
+        LocationIndexTree index = new LocationIndexTree(graph, new RAMDirectory());
+        index.prepareIndex();
+        QueryResult qr1 = index.findClosest(49.400772, 9.706245, EdgeFilter.ALL_EDGES);
+        QueryResult qr2 = index.findClosest(49.403167, 9.704774, EdgeFilter.ALL_EDGES);
+        QueryGraph queryGraph = new QueryGraph(chGraph);
+
+        // before fixing #1623 this test only worked for a disabled edge explorer cache
+        queryGraph.setUseEdgeExplorerCache(true);
+
+        queryGraph.lookup(Arrays.asList(qr1, qr2));
+        assertEquals(2, qr1.getClosestNode());
+        assertEquals(3, qr2.getClosestNode());
+        RoutingAlgorithm chAlgo = pch.createAlgo(queryGraph, AlgorithmOptions.start()
+                .traversalMode(TraversalMode.EDGE_BASED_2DIR)
+                .build());
+        Path path = chAlgo.calcPath(2, 3);
+        assertTrue("no path found", path.isFound());
+        assertEquals(IntArrayList.from(2, 5, 3), path.calcNodes());
+        assertEquals(454.266, path.getDistance(), 1.e-1);
+    }
+
     @Test
     public void testRouteViaVirtualNode() {
         //   3
diff --git a/core/src/test/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworksTest.java b/core/src/test/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworksTest.java
index 247cf18a0..72f9f0635 100644
--- a/core/src/test/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworksTest.java
+++ b/core/src/test/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworksTest.java
@@ -18,7 +18,6 @@
 package com.graphhopper.routing.subnetwork;
 
 import com.carrotsearch.hppc.IntArrayList;
-import com.graphhopper.routing.subnetwork.PrepareRoutingSubnetworks.PrepEdgeFilter;
 import com.graphhopper.routing.util.*;
 import com.graphhopper.storage.GraphBuilder;
 import com.graphhopper.storage.GraphHopperStorage;
@@ -96,7 +95,7 @@ public class PrepareRoutingSubnetworksTest {
     @Test
     public void testFindSubnetworks() {
         GraphHopperStorage g = createSubnetworkTestStorage();
-        PrepEdgeFilter filter = new PrepEdgeFilter(carFlagEncoder);
+        DefaultEdgeFilter filter = DefaultEdgeFilter.allEdges(carFlagEncoder);
         PrepareRoutingSubnetworks instance = new PrepareRoutingSubnetworks(g, Collections.singletonList(carFlagEncoder));
         List<IntArrayList> components = instance.findSubnetworks(filter);
 
@@ -112,7 +111,7 @@ public class PrepareRoutingSubnetworksTest {
     @Test
     public void testKeepLargestNetworks() {
         GraphHopperStorage g = createSubnetworkTestStorage();
-        PrepEdgeFilter filter = new PrepEdgeFilter(carFlagEncoder);
+        DefaultEdgeFilter filter = DefaultEdgeFilter.allEdges(carFlagEncoder);
         PrepareRoutingSubnetworks instance = new PrepareRoutingSubnetworks(g, Collections.singletonList(carFlagEncoder));
         List<IntArrayList> components = instance.findSubnetworks(filter);
         assertEquals(3, components.size());
@@ -253,7 +252,7 @@ public class PrepareRoutingSubnetworksTest {
 
         PrepareRoutingSubnetworks instance = new PrepareRoutingSubnetworks(g, Collections.singletonList(carFlagEncoder)).
                 setMinOneWayNetworkSize(3);
-        int removed = instance.removeDeadEndUnvisitedNetworks(new PrepEdgeFilter(carFlagEncoder));
+        int removed = instance.removeDeadEndUnvisitedNetworks(DefaultEdgeFilter.allEdges(carFlagEncoder));
 
         assertEquals(3, removed);
         instance.markNodesRemovedIfUnreachable();
@@ -269,7 +268,7 @@ public class PrepareRoutingSubnetworksTest {
 
         PrepareRoutingSubnetworks instance = new PrepareRoutingSubnetworks(g, Collections.singletonList(carFlagEncoder)).
                 setMinOneWayNetworkSize(3);
-        int removed = instance.removeDeadEndUnvisitedNetworks(new PrepEdgeFilter(carFlagEncoder));
+        int removed = instance.removeDeadEndUnvisitedNetworks(DefaultEdgeFilter.allEdges(carFlagEncoder));
 
         assertEquals(3, removed);
         instance.markNodesRemovedIfUnreachable();
@@ -309,7 +308,7 @@ public class PrepareRoutingSubnetworksTest {
 
         PrepareRoutingSubnetworks instance = new PrepareRoutingSubnetworks(g, Collections.singletonList(carFlagEncoder)).
                 setMinOneWayNetworkSize(2);
-        int removedEdges = instance.removeDeadEndUnvisitedNetworks(new PrepEdgeFilter(carFlagEncoder));
+        int removedEdges = instance.removeDeadEndUnvisitedNetworks(DefaultEdgeFilter.allEdges(carFlagEncoder));
         assertEquals(2, removedEdges);
     }
 
@@ -336,7 +335,7 @@ public class PrepareRoutingSubnetworksTest {
         instance.doWork();
 
         // only one remaining network
-        List<IntArrayList> components = instance.findSubnetworks(new PrepEdgeFilter(carFlagEncoder));
+        List<IntArrayList> components = instance.findSubnetworks(DefaultEdgeFilter.allEdges(carFlagEncoder));
         assertEquals(1, components.size());
     }
 
diff --git a/core/src/test/java/com/graphhopper/storage/GraphEdgeIdFinderTest.java b/core/src/test/java/com/graphhopper/storage/GraphEdgeIdFinderTest.java
index f2db4b59f..55982a04e 100644
--- a/core/src/test/java/com/graphhopper/storage/GraphEdgeIdFinderTest.java
+++ b/core/src/test/java/com/graphhopper/storage/GraphEdgeIdFinderTest.java
@@ -124,13 +124,13 @@ public class GraphEdgeIdFinderTest {
         GraphEdgeIdFinder.BlockArea blockArea = graphFinder.parseBlockArea("2,1, 0,2, 2,3", DefaultEdgeFilter.allEdges(encoder), 1000 * 1000);
 
         GHIntHashSet blockedEdges = new GHIntHashSet();
-        blockedEdges.addAll(new int[]{1, 2, 6, 7});
+        blockedEdges.addAll(1, 2, 6, 7);
         assertEquals(blockedEdges, blockArea.blockedEdges);
 
         blockArea = graphFinder.parseBlockArea("2,1, 1,3, 1,2, 0,1", DefaultEdgeFilter.allEdges(encoder), 1000 * 1000);
 
         blockedEdges = new GHIntHashSet();
-        blockedEdges.addAll(new int[]{4, 9, 6, 7});
+        blockedEdges.addAll(4, 9, 6, 7);
         assertEquals(blockedEdges, blockArea.blockedEdges);
     }
 }