1010import java .util .Map ;
1111import java .util .Map .Entry ;
1212import java .util .Objects ;
13+ import java .util .concurrent .ConcurrentHashMap ;
1314
1415/**
1516 * This is for translated strings for which translations are read from OSM or GTFS alerts.
@@ -24,7 +25,8 @@ public class TranslatedString implements I18NString, Serializable {
2425 * Store all translations, so we don't get memory overhead for identical strings As this is
2526 * static, it isn't serialized when saving the graph.
2627 */
27- private static final HashMap <Map <String , String >, I18NString > TRANSLATION_CACHE = new HashMap <>();
28+ private static final ConcurrentHashMap <Map <String , String >, I18NString > TRANSLATION_CACHE =
29+ new ConcurrentHashMap <>();
2830
2931 private final Map <String , String > translations = new HashMap <>();
3032
@@ -52,72 +54,25 @@ public static I18NString getI18NString(String untranslated, String... translatio
5254 return getI18NString (map , false );
5355 }
5456
55- /**
56- * Gets a deduplicated I18NString. If the translations only have a single value, return a
57- * NonLocalizedString, otherwise a TranslatedString. The resulting I18NString is interned for
58- * memory efficiency.
59- * <p>
60- * This should be used when calling this method during graph building. This should not be called
61- * from a real-time updater as this is not thread-safe and may cause a memory leak.
62- *
63- * @param translations A Map of languages and translations, a null language is the default
64- * translation
65- * @param forceTranslatedString Should the language information be kept, even when only a single
66- * translation is provided. This is useful when the language
67- * information is important or is presented to the user.
68- */
69- public static I18NString getDeduplicatedI18NString (
70- Map <String , String > translations ,
71- boolean forceTranslatedString
72- ) {
73- return getI18NString (translations , true , forceTranslatedString );
74- }
75-
76- /**
77- * Gets a non-deduplicated I18NString. If the translations only have a single value, return a
78- * NonLocalizedString, otherwise a TranslatedString. The resulting I18NString is NOT interned.
79- * <p>
80- * This should be used from real-time updaters to avoid memory leaks. For graph building, use
81- * {@link #getDeduplicatedI18NString(Map, boolean)} instead.
82- *
83- * @param translations A Map of languages and translations, a null language is the default
84- * translation
85- * @param forceTranslatedString Should the language information be kept, even when only a single
86- * translation is provided. This is useful when the language
87- * information is important or is presented to the user.
88- */
89- public static I18NString getI18NString (
90- Map <String , String > translations ,
91- boolean forceTranslatedString
92- ) {
93- return getI18NString (translations , false , forceTranslatedString );
94- }
95-
9657 /**
9758 * Gets an I18NString. If the translations only have a single value, return a NonLocalizedString,
9859 * otherwise a TranslatedString
9960 *
10061 * @param translations A Map of languages and translations, a null language is the default
10162 * translation
102- * @param intern Should the resulting I18NString be interned. This should be used when calling
103- * this method during graph building. This should not be called from a real-time
104- * updater as this is not thread-safe and may cause a memory leak.
10563 * @param forceTranslatedString Should the language information be kept, even when only a single
10664 * translation is provided. This is useful when the language
10765 * information is important or is presented to the user.
10866 */
109- static I18NString getI18NString (
67+ public static I18NString getI18NString (
11068 Map <String , String > translations ,
111- boolean intern ,
11269 boolean forceTranslatedString
11370 ) {
114- if (translations .isEmpty ()) {
115- throw new IllegalArgumentException ("At least one translation must be provided" );
116- }
117- if (TRANSLATION_CACHE .containsKey (translations )) {
118- return TRANSLATION_CACHE .get (translations );
119- } else {
120- I18NString ret ;
71+ I18NString ret = TRANSLATION_CACHE .get (translations );
72+ if (ret == null ) {
73+ if (translations .isEmpty ()) {
74+ throw new IllegalArgumentException ("At least one translation must be provided" );
75+ }
12176 // Check if we only have one name, even under multiple languages
12277 boolean allValuesEqual = new HashSet <>(translations .values ()).size () == 1 ;
12378 var firstLanguage = translations .keySet ().iterator ().next ();
@@ -130,11 +85,9 @@ static I18NString getI18NString(
13085 } else {
13186 ret = new TranslatedString (translations );
13287 }
133- if (intern ) {
134- TRANSLATION_CACHE .put (translations , ret );
135- }
136- return ret ;
88+ TRANSLATION_CACHE .put (translations , ret );
13789 }
90+ return ret ;
13891 }
13992
14093 @ Override
0 commit comments