@leventov I removed synchronized from read operation, and it worked fine. because there is only add operation to map and list, no delete operation, so IndexOutOfBoundsException is unlikely happen. >From the other side, current synchronized/rw lock can't actually do what it >means. like: 1. threadA getMinValue(), threadB add(), threadA now holds the outdated minValue.
As you can see, the lock behavior doesn't help in overall perspective. to remove synchronized to gain performance improve, I removed idForNull and fallback to 0.12.3 code. private static class DimensionDictionary { private String minValue = null; private String maxValue = null; private final Object2IntMap<String> valueToId = new Object2IntOpenHashMap<>(); private final List<String> idToValue = Lists.newArrayList(); private final Object lock; public DimensionDictionary() { this.lock = new Object(); valueToId.defaultReturnValue(-1); } public int getId(String value) { return valueToId.getInt(Strings.nullToEmpty(value)); } public String getValue(int id) { return Strings.emptyToNull(idToValue.get(id)); } public int size() { return valueToId.size(); } public int add(String originalValue) { String value = Strings.nullToEmpty(originalValue); synchronized (lock) { int prev = valueToId.getInt(value); if (prev >= 0) { return prev; } final int index = size(); valueToId.put(value, index); idToValue.add(value); minValue = minValue == null || minValue.compareTo(value) > 0 ? value : minValue; maxValue = maxValue == null || maxValue.compareTo(value) < 0 ? value : maxValue; return index; } } public String getMinValue() { return minValue; } public String getMaxValue() { return maxValue; } public SortedDimensionDictionary sort() { synchronized (lock) { return new SortedDimensionDictionary(idToValue, size()); } } } [ Full content available at: https://github.com/apache/incubator-druid/issues/6322 ] This message was relayed via gitbox.apache.org for devnull@infra.apache.org