Skip to content

Commit c8567ee

Browse files
committed
Do not allow modifications after EncodingManager.Builder.build, improves on graphhopper#1546
1 parent 0404b0b commit c8567ee

File tree

6 files changed

+92
-87
lines changed

6 files changed

+92
-87
lines changed

core/files/changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
0.12
22
access refactoring #1436 that moves AccessValue into SpatialRule.Access
33
refactoring of EncodingManager to use builder pattern. Migration should be simple. Replace new EncodingManager with EncodingManager.create
4+
The methods GraphHopper.setEnableInstructions/setPreferredLanguage is now in EncodingManager.Builder
45
EncodingManager.supports renames to hasEncoder
56
big refactoring #1447: to increase 64bit limit of flags, make reverse direction handling easier, to allow shared EncodedValues,
67
remove reverseFlags method, much simpler property access, simplify FlagEncoder (maybe even deprecate this interface at a later stage)

core/src/main/java/com/graphhopper/GraphHopper.java

Lines changed: 7 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ public class GraphHopper implements GraphHopperAPI {
7575
// utils
7676
private final TranslationMap trMap = new TranslationMap().doImport();
7777
boolean removeZipped = true;
78-
boolean enableInstructions = true;
7978
// for graph:
8079
private GraphHopperStorage ghStorage;
8180
private EncodingManager encodingManager;
@@ -86,7 +85,6 @@ public class GraphHopper implements GraphHopperAPI {
8685
private boolean elevation = false;
8786
private LockFactory lockFactory = new NativeFSLockFactory();
8887
private boolean allowWrites = true;
89-
private String preferredLanguage = "";
9088
private boolean fullyLoaded = false;
9189
private boolean smoothElevation = false;
9290
// for routing
@@ -359,44 +357,6 @@ public GraphHopper setElevation(boolean includeElevation) {
359357
return this;
360358
}
361359

362-
public boolean isEnableInstructions() {
363-
return enableInstructions;
364-
}
365-
366-
/**
367-
* This method specifies if the import should include way names to be able to return
368-
* instructions for a route.
369-
*/
370-
public GraphHopper setEnableInstructions(boolean b) {
371-
ensureNotLoaded();
372-
enableInstructions = b;
373-
return this;
374-
}
375-
376-
public String getPreferredLanguage() {
377-
return preferredLanguage;
378-
}
379-
380-
/**
381-
* This method specifies the preferred language for way names during import.
382-
* <p>
383-
* Language code as defined in ISO 639-1 or ISO 639-2.
384-
* <ul>
385-
* <li>If no preferred language is specified, only the default language with no tag will be
386-
* imported.</li>
387-
* <li>If a language is specified, it will be imported if its tag is found, otherwise fall back
388-
* to default language.</li>
389-
* </ul>
390-
*/
391-
public GraphHopper setPreferredLanguage(String preferredLanguage) {
392-
ensureNotLoaded();
393-
if (preferredLanguage == null)
394-
throw new IllegalArgumentException("preferred language cannot be null");
395-
396-
this.preferredLanguage = preferredLanguage;
397-
return this;
398-
}
399-
400360
/**
401361
* This methods enables gps point calculation. If disabled only distance will be calculated.
402362
*/
@@ -547,8 +507,12 @@ public GraphHopper init(CmdArgs args) {
547507
removeZipped = args.getBool("graph.remove_zipped", removeZipped);
548508
int bytesForFlags = args.getInt("graph.bytes_for_flags", 4);
549509
String flagEncodersStr = args.get("graph.flag_encoders", "");
550-
if (!flagEncodersStr.isEmpty())
551-
setEncodingManager(EncodingManager.create(flagEncoderFactory, flagEncodersStr, bytesForFlags));
510+
if (!flagEncodersStr.isEmpty()) {
511+
EncodingManager.Builder emBuilder = EncodingManager.createBuilder(flagEncoderFactory, flagEncodersStr, bytesForFlags);
512+
emBuilder.setEnableInstructions(args.getBool("datareader.instructions", true));
513+
emBuilder.setPreferredLanguage(args.get("datareader.preferred_language", ""));
514+
setEncodingManager(emBuilder.build());
515+
}
552516

553517
if (args.get("graph.locktype", "native").equals("simple"))
554518
lockFactory = new SimpleFSLockFactory();
@@ -609,8 +573,6 @@ public GraphHopper init(CmdArgs args) {
609573
dataReaderWayPointMaxDistance = args.getDouble(Routing.INIT_WAY_POINT_MAX_DISTANCE, dataReaderWayPointMaxDistance);
610574

611575
dataReaderWorkerThreads = args.getInt("datareader.worker_threads", dataReaderWorkerThreads);
612-
enableInstructions = args.getBool("datareader.instructions", enableInstructions);
613-
preferredLanguage = args.get("datareader.preferred_language", preferredLanguage);
614576

615577
// index
616578
preciseIndexResolution = args.getInt("index.high_resolution", preciseIndexResolution);
@@ -687,8 +649,6 @@ protected DataReader importData() throws IOException {
687649
throw new IllegalStateException("Couldn't load from existing folder: " + ghLocation
688650
+ " but also cannot use file for DataReader as it wasn't specified!");
689651

690-
encodingManager.setEnableInstructions(enableInstructions);
691-
encodingManager.setPreferredLanguage(preferredLanguage);
692652
DataReader reader = createReader(ghStorage);
693653
logger.info("using " + ghStorage.toString() + ", memory:" + getMemInfo());
694654
reader.readGraph();
@@ -1074,7 +1034,7 @@ else if (ALT_ROUTE.equalsIgnoreCase(algoStr))
10741034
// do the actual route calculation !
10751035
altPaths = routingTemplate.calcPaths(queryGraph, tmpAlgoFactory, algoOpts);
10761036

1077-
boolean tmpEnableInstructions = hints.getBool(Routing.INSTRUCTIONS, enableInstructions);
1037+
boolean tmpEnableInstructions = hints.getBool(Routing.INSTRUCTIONS, getEncodingManager().isEnableInstructions());
10781038
boolean tmpCalcPoints = hints.getBool(Routing.CALC_POINTS, calcPoints);
10791039
double wayPointMaxDistance = hints.getDouble(Routing.WAY_POINT_MAX_DISTANCE, 1d);
10801040

core/src/main/java/com/graphhopper/routing/util/EncodingManager.java

Lines changed: 69 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,11 @@ public static EncodingManager create(String flagEncodersStr, int bytesForEdgeFla
7373
}
7474

7575
public static EncodingManager create(FlagEncoderFactory factory, String flagEncodersStr, int bytesForEdgeFlags) {
76-
return create(parseEncoderString(factory, flagEncodersStr), bytesForEdgeFlags);
76+
return createBuilder(factory, flagEncodersStr, bytesForEdgeFlags).build();
77+
}
78+
79+
public static EncodingManager.Builder createBuilder(FlagEncoderFactory factory, String flagEncodersStr, int bytesForEdgeFlags) {
80+
return createBuilder(parseEncoderString(factory, flagEncodersStr), bytesForEdgeFlags);
7781
}
7882

7983
/**
@@ -95,11 +99,15 @@ public static EncodingManager create(List<? extends FlagEncoder> flagEncoders) {
9599
}
96100

97101
public static EncodingManager create(List<? extends FlagEncoder> flagEncoders, int bytesForEdgeFlags) {
102+
return createBuilder(flagEncoders, bytesForEdgeFlags).build();
103+
}
104+
105+
private static EncodingManager.Builder createBuilder(List<? extends FlagEncoder> flagEncoders, int bytesForEdgeFlags) {
98106
Builder builder = new Builder(bytesForEdgeFlags);
99107
for (FlagEncoder flagEncoder : flagEncoders) {
100108
builder.add(flagEncoder);
101109
}
102-
return builder.build();
110+
return builder;
103111
}
104112

105113
/**
@@ -126,7 +134,7 @@ public static EncodingManager create(FlagEncoderFactory factory, String ghLoc) {
126134
bytesForFlags = Integer.parseInt(properties.get("graph.bytes_for_flags"));
127135
} catch (NumberFormatException ex) {
128136
}
129-
return create(factory, acceptStr, bytesForFlags);
137+
return createBuilder(factory, acceptStr, bytesForFlags).build();
130138
}
131139

132140
/**
@@ -145,8 +153,7 @@ private EncodingManager(int bytes) {
145153
}
146154

147155
public static class Builder {
148-
private final EncodingManager em;
149-
private boolean buildCalled = false;
156+
private EncodingManager em;
150157

151158
public Builder(int bytes) {
152159
em = new EncodingManager(bytes);
@@ -164,6 +171,33 @@ public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, Access access, lo
164171
});
165172
}
166173

174+
/**
175+
* This method specifies the preferred language for way names during import.
176+
* <p>
177+
* Language code as defined in ISO 639-1 or ISO 639-2.
178+
* <ul>
179+
* <li>If no preferred language is specified, only the default language with no tag will be
180+
* imported.</li>
181+
* <li>If a language is specified, it will be imported if its tag is found, otherwise fall back
182+
* to default language.</li>
183+
* </ul>
184+
*/
185+
public Builder setPreferredLanguage(String language) {
186+
check();
187+
em.setPreferredLanguage(language);
188+
return this;
189+
}
190+
191+
/**
192+
* This method specifies if the import should include way names to be able to return
193+
* instructions for a route.
194+
*/
195+
public Builder setEnableInstructions(boolean enable) {
196+
check();
197+
em.setEnableInstructions(enable);
198+
return this;
199+
}
200+
167201
/**
168202
* For backward compatibility provide a way to add multiple FlagEncoders
169203
*/
@@ -175,11 +209,13 @@ public Builder addAll(FlagEncoderFactory factory, String flagEncodersStr) {
175209
}
176210

177211
public Builder add(FlagEncoder encoder) {
212+
check();
178213
em.addEncoder((AbstractFlagEncoder) encoder);
179214
return this;
180215
}
181216

182217
public Builder add(EncodedValue encodedValue) {
218+
check();
183219
em.addEncodedValue(encodedValue);
184220
return this;
185221
}
@@ -190,14 +226,19 @@ public Builder put(EncodedValue encodedValue, TagParser tagParser) {
190226
return this;
191227
}
192228

229+
private void check() {
230+
if (em == null)
231+
throw new IllegalStateException("Cannot call method after Builder.build() was called");
232+
}
233+
193234
public EncodingManager build() {
194-
if (buildCalled)
195-
throw new IllegalStateException("Cannot call Builder.build() twice");
235+
check();
196236
if (em.encodedValueMap.isEmpty())
197237
throw new IllegalStateException("No EncodedValues found");
198238

199-
buildCalled = true;
200-
return em;
239+
EncodingManager tmp = em;
240+
em = null;
241+
return tmp;
201242
}
202243
}
203244

@@ -244,6 +285,25 @@ public int getBytesForFlags() {
244285
return bitsForEdgeFlags / 8;
245286
}
246287

288+
private void setEnableInstructions(boolean enableInstructions) {
289+
this.enableInstructions = enableInstructions;
290+
}
291+
292+
public boolean isEnableInstructions() {
293+
return enableInstructions;
294+
}
295+
296+
private void setPreferredLanguage(String preferredLanguage) {
297+
if (preferredLanguage == null)
298+
throw new IllegalArgumentException("preferred language cannot be null");
299+
300+
this.preferredLanguage = preferredLanguage;
301+
}
302+
303+
public String getPreferredLanguage() {
304+
return preferredLanguage;
305+
}
306+
247307
private void addEncoder(AbstractFlagEncoder encoder) {
248308
if (encoder.isRegistered())
249309
throw new IllegalStateException("You must not register a FlagEncoder (" + encoder.toString() + ") twice!");
@@ -498,19 +558,6 @@ public long handleNodeTags(ReaderNode node) {
498558
return flags;
499559
}
500560

501-
public EncodingManager setEnableInstructions(boolean enableInstructions) {
502-
this.enableInstructions = enableInstructions;
503-
return this;
504-
}
505-
506-
public EncodingManager setPreferredLanguage(String preferredLanguage) {
507-
if (preferredLanguage == null)
508-
throw new IllegalArgumentException("preferred language cannot be null");
509-
510-
this.preferredLanguage = preferredLanguage;
511-
return this;
512-
}
513-
514561
public void applyWayTags(ReaderWay way, EdgeIteratorState edge) {
515562
// storing the road name does not yet depend on the flagEncoder so manage it directly
516563
if (enableInstructions) {

core/src/test/java/com/graphhopper/reader/dem/AbstractEdgeElevationInterpolatorTest.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,6 @@
1717
*/
1818
package com.graphhopper.reader.dem;
1919

20-
import java.util.Arrays;
21-
22-
import org.junit.After;
23-
import org.junit.Before;
24-
2520
import com.graphhopper.coll.GHBitSetImpl;
2621
import com.graphhopper.coll.GHIntHashSet;
2722
import com.graphhopper.reader.ReaderWay;
@@ -33,6 +28,10 @@
3328
import com.graphhopper.storage.RAMDirectory;
3429
import com.graphhopper.util.EdgeIteratorState;
3530
import com.graphhopper.util.Helper;
31+
import org.junit.After;
32+
import org.junit.Before;
33+
34+
import java.util.Arrays;
3635

3736
/**
3837
* @author Alexey Valikov
@@ -52,8 +51,7 @@ public abstract class AbstractEdgeElevationInterpolatorTest {
5251
public void setUp() {
5352
dataFlagEncoder = new DataFlagEncoder();
5453
graph = new GraphHopperStorage(new RAMDirectory(),
55-
EncodingManager.create(Arrays.asList(dataFlagEncoder, new FootFlagEncoder()),
56-
8),
54+
EncodingManager.create(Arrays.asList(dataFlagEncoder, new FootFlagEncoder()), 8),
5755
true, new GraphExtension.NoOpExtension()).create(100);
5856

5957
edgeElevationInterpolator = createEdgeElevationInterpolator();

reader-osm/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -306,14 +306,14 @@ public void testSortedGraph_noCH() {
306306
assertEquals(new GHPoint(51.199999850988384, 9.39999970197677), rsp.getPoints().toGHPoint(2));
307307

308308
GHRequest req = new GHRequest(51.2492152, 9.4317166, 51.2, 9.4);
309-
boolean old = instance.isEnableInstructions();
309+
boolean old = instance.getEncodingManager().isEnableInstructions();
310310
req.getHints().put("instructions", true);
311311
instance.route(req);
312-
assertEquals(old, instance.isEnableInstructions());
312+
assertEquals(old, instance.getEncodingManager().isEnableInstructions());
313313

314314
req.getHints().put("instructions", false);
315315
instance.route(req);
316-
assertEquals("route method should not change instance field", old, instance.isEnableInstructions());
316+
assertEquals("route method should not change instance field", old, instance.getEncodingManager().isEnableInstructions());
317317
}
318318

319319
@Test

reader-osm/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ public void testRelation() {
495495

496496
@Test
497497
public void testTurnRestrictions() {
498-
GraphHopper hopper = new GraphHopperFacade(fileTurnRestrictions, true).
498+
GraphHopper hopper = new GraphHopperFacade(fileTurnRestrictions, true, "").
499499
importOrLoad();
500500

501501
Graph graph = hopper.getGraphHopperStorage();
@@ -796,14 +796,14 @@ public Collection<OSMTurnRelation.TurnCostTableEntry> analyzeTurnRelation(FlagEn
796796

797797
@Test
798798
public void testPreferredLanguage() {
799-
GraphHopper hopper = new GraphHopperFacade(file1).setPreferredLanguage("de").importOrLoad();
799+
GraphHopper hopper = new GraphHopperFacade(file1, false, "de").importOrLoad();
800800
GraphHopperStorage graph = hopper.getGraphHopperStorage();
801801
int n20 = AbstractGraphStorageTester.getIdOf(graph, 52);
802802
EdgeIterator iter = carOutExplorer.setBaseNode(n20);
803803
assertTrue(iter.next());
804804
assertEquals("straße 123, B 122", iter.getName());
805805

806-
hopper = new GraphHopperFacade(file1).setPreferredLanguage("el").importOrLoad();
806+
hopper = new GraphHopperFacade(file1, false, "el").importOrLoad();
807807
graph = hopper.getGraphHopperStorage();
808808
n20 = AbstractGraphStorageTester.getIdOf(graph, 52);
809809
iter = carOutExplorer.setBaseNode(n20);
@@ -854,10 +854,10 @@ public void testRoutingRequestFails_issue665() {
854854

855855
class GraphHopperFacade extends GraphHopperOSM {
856856
public GraphHopperFacade(String osmFile) {
857-
this(osmFile, false);
857+
this(osmFile, false, "");
858858
}
859859

860-
public GraphHopperFacade(String osmFile, boolean turnCosts) {
860+
public GraphHopperFacade(String osmFile, boolean turnCosts, String prefLang) {
861861
setStoreOnFlush(false);
862862
setOSMFile(osmFile);
863863
setGraphHopperLocation(dir);
@@ -872,8 +872,8 @@ public GraphHopperFacade(String osmFile, boolean turnCosts) {
872872
}
873873

874874
footEncoder = new FootFlagEncoder();
875-
876-
setEncodingManager(EncodingManager.create(footEncoder, carEncoder, bikeEncoder));
875+
setEncodingManager(new EncodingManager.Builder(4).add(footEncoder).add(carEncoder).add(bikeEncoder).
876+
setPreferredLanguage(prefLang).build());
877877
carAccessEnc = carEncoder.getAccessEnc();
878878
}
879879

@@ -884,7 +884,6 @@ protected DataReader createReader(GraphHopperStorage tmpGraph) {
884884

885885
@Override
886886
protected DataReader importData() throws IOException {
887-
getEncodingManager().setPreferredLanguage(getPreferredLanguage());
888887
GraphHopperStorage tmpGraph = newGraph(dir, getEncodingManager(), hasElevation(),
889888
getEncodingManager().needsTurnCostsSupport());
890889
setGraphHopperStorage(tmpGraph);

0 commit comments

Comments
 (0)