From 0487c30582c16b7b32f3e0526897fce3d9a71ab9 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Sat, 22 Dec 2018 10:07:19 +0100 Subject: [PATCH] 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. --- .../pdb/api/UniqueStringIntegerPairs.java | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/pdb-api/src/main/java/org/lucares/pdb/api/UniqueStringIntegerPairs.java b/pdb-api/src/main/java/org/lucares/pdb/api/UniqueStringIntegerPairs.java index ff987a9..da483f3 100644 --- a/pdb-api/src/main/java/org/lucares/pdb/api/UniqueStringIntegerPairs.java +++ b/pdb-api/src/main/java/org/lucares/pdb/api/UniqueStringIntegerPairs.java @@ -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. *

* (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 intToString = new TreeMap<>(); + private final List 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 mappingFunction) { - if (!stringToInt.containsKey(first)) { synchronized (stringToInt) { if (!stringToInt.containsKey(first)) {