use List instead of TreeMap for intToString mapping

UniqueStringIntegerPairs stores mappings of integers
0-n to strings and vice versa. Mapping integers to
strings does not need a TreeMap, it can be done with
a List.
Makes insertions 3 times (when using the in-memory
variant that does not write to disk) and 7 times faster
for int to string mapping.
This commit is contained in:
2018-12-22 10:07:19 +01:00
parent e537e94d39
commit 0487c30582

View File

@@ -10,16 +10,16 @@ import java.io.Writer;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.function.Function; import java.util.function.Function;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
* A very simple {@link Set}-like or {@link Map}-like datastructure that stores * A very simple {@link Set}-like or {@link Map}-like data structure that stores
* unique¹ pairs of Strings and integers persistently. * unique¹ pairs of Strings and integers persistently.
* <p> * <p>
* (1) Unique means, that neither the string, nor the integer may occur twice. * (1) Unique means, that neither the string, nor the integer may occur twice.
@@ -42,7 +42,7 @@ public class UniqueStringIntegerPairs {
/** /**
* Maps an integer to a string. E.g. 123 -> "myLongValue" * Maps an integer to a string. E.g. 123 -> "myLongValue"
*/ */
private final SortedMap<Integer, String> intToString = new TreeMap<>(); private final List<String> intToString = new ArrayList<>();
private final Path file; private final Path file;
@@ -75,7 +75,7 @@ public class UniqueStringIntegerPairs {
if (tokens.length == 2) { if (tokens.length == 2) {
final String string = tokens[0]; final String string = tokens[0];
final int value = Integer.parseInt(tokens[1]); final int value = Integer.parseInt(tokens[1]);
intToString.put(value, string); intToStringPut(value, string);
stringToInt.put(string, value); stringToInt.put(string, value);
} }
} }
@@ -85,9 +85,19 @@ public class UniqueStringIntegerPairs {
} }
} }
public void put(final String first, final int second) { private void intToStringPut(final int value, final String string) {
if (intToString.size() <= value) {
// list is not long enough -> grow list
while (intToString.size() <= value) {
intToString.add(null);
}
}
intToString.set(value, string);
}
if (stringToInt.containsKey(first) || intToString.containsKey(second)) { void put(final String first, final int second) {
if (stringToInt.containsKey(first) || (intToString.size() > second && intToString.get(second) != null)) {
throw new IllegalArgumentException("Unique key constraint violation for (" + first + ", " + second + ")"); throw new IllegalArgumentException("Unique key constraint violation for (" + first + ", " + second + ")");
} }
if (file != null) { if (file != null) {
@@ -101,7 +111,7 @@ public class UniqueStringIntegerPairs {
} }
} }
intToString.put(second, first); intToStringPut(second, first);
stringToInt.put(first, second); stringToInt.put(first, second);
} }
@@ -110,16 +120,15 @@ public class UniqueStringIntegerPairs {
return stringToInt.get(first); return stringToInt.get(first);
} }
public String getKey(final Integer second) { public String getKey(final int second) {
return intToString.get(second); return intToString.get(second);
} }
public Integer getHighestInteger() { public Integer getHighestInteger() {
return intToString.size() == 0 ? -1 : intToString.lastKey(); return intToString.size() == 0 ? -1 : intToString.size() - 1;
} }
public Integer computeIfAbsent(final String first, final Function<String, Integer> mappingFunction) { public Integer computeIfAbsent(final String first, final Function<String, Integer> mappingFunction) {
if (!stringToInt.containsKey(first)) { if (!stringToInt.containsKey(first)) {
synchronized (stringToInt) { synchronized (stringToInt) {
if (!stringToInt.containsKey(first)) { if (!stringToInt.containsKey(first)) {