8288979: Improve CLDRConverter run time

Reviewed-by: naoto, rriggs
This commit is contained in:
Daniel Jeliński 2022-06-23 18:44:54 +00:00
parent 740169ce1c
commit c8cc94a384

View File

@ -33,7 +33,6 @@ import java.util.Formatter;
import java.util.HashSet; import java.util.HashSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Locale; import java.util.Locale;
import java.util.Objects; import java.util.Objects;
@ -70,7 +69,6 @@ class ResourceBundleGenerator implements BundleGenerator {
private static final String META_VALUE_PREFIX = "metaValue_"; private static final String META_VALUE_PREFIX = "metaValue_";
@Override @Override
@SuppressWarnings("unchecked")
public void generateBundle(String packageName, String baseName, String localeID, boolean useJava, public void generateBundle(String packageName, String baseName, String localeID, boolean useJava,
Map<String, ?> map, BundleType type) throws IOException { Map<String, ?> map, BundleType type) throws IOException {
String suffix = useJava ? ".java" : ".properties"; String suffix = useJava ? ".java" : ".properties";
@ -144,56 +142,34 @@ class ResourceBundleGenerator implements BundleGenerator {
map = newMap; map = newMap;
} else { } else {
// generic reduction of duplicated values // generic reduction of duplicated values
Map<String, Object> newMap = null; Map<String, Object> newMap = new LinkedHashMap<>(map);
for (String key : map.keySet()) { Map<BundleEntryValue, BundleEntryValue> dedup = new HashMap<>(map.size());
Object val = map.get(key); for (Map.Entry<String, ?> entry : map.entrySet()) {
String metaVal = null; String key = entry.getKey();
Object val = entry.getValue();
for (Map.Entry<String, ?> entry : map.entrySet()) { BundleEntryValue newEntry = new BundleEntryValue(key, val);
String k = entry.getKey(); BundleEntryValue oldEntry = dedup.putIfAbsent(newEntry, newEntry);
if (!k.equals(key) && if (oldEntry != null) {
Objects.deepEquals(val, entry.getValue()) && if (oldEntry.meta()) {
!(Objects.nonNull(newMap) && newMap.containsKey(k))) { if (fmt == null) {
if (Objects.isNull(newMap)) {
newMap = new HashMap<>();
fmt = new Formatter(); fmt = new Formatter();
} }
String metaVal = oldEntry.metaKey();
if (Objects.isNull(metaVal)) { if (val instanceof String[] values) {
metaVal = META_VALUE_PREFIX + key.replaceAll("[\\.-]", "_"); fmt.format(" final String[] %s = new String[] {\n", metaVal);
for (String s : values) {
if (val instanceof String[]) { fmt.format(" \"%s\",\n", CLDRConverter.saveConvert(s, useJava));
fmt.format(" final String[] %s = new String[] {\n", metaVal);
for (String s : (String[]) val) {
fmt.format(" \"%s\",\n", CLDRConverter.saveConvert(s, useJava));
}
fmt.format(" };\n");
} else if (val instanceof List) {
fmt.format(" final String[] %s = new String[] {\n", metaVal);
for (String s : (List<String>) val) {
fmt.format(" \"%s\",\n", CLDRConverter.saveConvert(s, useJava));
}
fmt.format(" };\n");
} else {
fmt.format(" final String %s = \"%s\";\n", metaVal, CLDRConverter.saveConvert((String)val, useJava));
} }
fmt.format(" };\n");
} else {
fmt.format(" final String %s = \"%s\";\n", metaVal, CLDRConverter.saveConvert((String)val, useJava));
} }
newMap.put(oldEntry.key, oldEntry.metaKey());
newMap.put(k, metaVal);
} }
} newMap.put(key, oldEntry.metaKey());
if (Objects.nonNull(metaVal)) {
newMap.put(key, metaVal);
} }
} }
map = newMap;
if (Objects.nonNull(newMap)) {
for (String key : map.keySet()) {
newMap.putIfAbsent(key, map.get(key));
}
map = newMap;
}
} }
try (PrintWriter out = new PrintWriter(file, encoding)) { try (PrintWriter out = new PrintWriter(file, encoding)) {
@ -247,6 +223,58 @@ class ResourceBundleGenerator implements BundleGenerator {
} }
} }
private static class BundleEntryValue {
private final String key;
private final Object value;
private final int hashCode;
private String metaKey;
BundleEntryValue(String key, Object value) {
this.key = Objects.requireNonNull(key);
this.value = Objects.requireNonNull(value);
if (value instanceof String) {
hashCode = value.hashCode();
} else if (value instanceof String[] arr) {
hashCode = Arrays.hashCode(arr);
} else {
throw new InternalError("Expected a string or a string array");
}
}
/**
* mark the entry as meta
* @return true if the entry was not meta before, false otherwise
*/
public boolean meta() {
if (metaKey == null) {
metaKey = META_VALUE_PREFIX + key.replaceAll("[\\.-]", "_");
return true;
}
return false;
}
public String metaKey() {
return metaKey;
}
@Override
public int hashCode() {
return hashCode;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof BundleEntryValue entry) {
if (value instanceof String s) {
return s.equals(entry.value);
} else if (entry.value instanceof String[] otherVal) {
return Arrays.equals((String[]) value, otherVal);
}
}
return false;
}
}
@Override @Override
public void generateMetaInfo(Map<String, SortedSet<String>> metaInfo) throws IOException { public void generateMetaInfo(Map<String, SortedSet<String>> metaInfo) throws IOException {
String dirName = CLDRConverter.DESTINATION_DIR + File.separator + "sun" + File.separator + "util" + String dirName = CLDRConverter.DESTINATION_DIR + File.separator + "sun" + File.separator + "util" +