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.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.function.Function;
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.
* <p>
* (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"
*/
private final SortedMap<Integer, String> intToString = new TreeMap<>();
private final List<String> intToString = new ArrayList<>();
private final Path file;
@@ -75,7 +75,7 @@ public class UniqueStringIntegerPairs {
if (tokens.length == 2) {
final String string = tokens[0];
final int value = Integer.parseInt(tokens[1]);
intToString.put(value, string);
intToStringPut(value, string);
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 + ")");
}
if (file != null) {
@@ -101,7 +111,7 @@ public class UniqueStringIntegerPairs {
}
}
intToString.put(second, first);
intToStringPut(second, first);
stringToInt.put(first, second);
}
@@ -110,16 +120,15 @@ public class UniqueStringIntegerPairs {
return stringToInt.get(first);
}
public String getKey(final Integer second) {
public String getKey(final int second) {
return intToString.get(second);
}
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) {
if (!stringToInt.containsKey(first)) {
synchronized (stringToInt) {
if (!stringToInt.containsKey(first)) {