From 7649742943a4a355e223be9284716e3fd177c14c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=98=A5=E6=96=8C?= Date: Tue, 26 Jun 2018 03:35:26 +0800 Subject: [PATCH] Use ReentrantReadWriteLock in DimensionDictionary (#5883) --- .../druid/segment/StringDimensionIndexer.java | 53 ++++++++++++++----- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/processing/src/main/java/io/druid/segment/StringDimensionIndexer.java b/processing/src/main/java/io/druid/segment/StringDimensionIndexer.java index e36b223731f..75ca57bf07f 100644 --- a/processing/src/main/java/io/druid/segment/StringDimensionIndexer.java +++ b/processing/src/main/java/io/druid/segment/StringDimensionIndexer.java @@ -55,6 +55,7 @@ import java.util.Arrays; import java.util.BitSet; import java.util.Iterator; import java.util.List; +import java.util.concurrent.locks.ReentrantReadWriteLock; public class StringDimensionIndexer implements DimensionIndexer { @@ -79,48 +80,61 @@ public class StringDimensionIndexer implements DimensionIndexer valueToId = new Object2IntOpenHashMap<>(); private final List idToValue = Lists.newArrayList(); - private final Object lock; + private final ReentrantReadWriteLock lock; public DimensionDictionary() { - this.lock = new Object(); + this.lock = new ReentrantReadWriteLock(); valueToId.defaultReturnValue(-1); } public int getId(String value) { - synchronized (lock) { + lock.readLock().lock(); + try { if (value == null) { return idForNull; } return valueToId.getInt(value); } + finally { + lock.readLock().unlock(); + } } public String getValue(int id) { - synchronized (lock) { + lock.readLock().lock(); + try { if (id == idForNull) { return null; } return idToValue.get(id); } + finally { + lock.readLock().unlock(); + } } public int size() { - synchronized (lock) { + lock.readLock().lock(); + try { // using idToValue rather than valueToId because the valueToId doesn't account null value, if it is present. return idToValue.size(); } + finally { + lock.readLock().unlock(); + } } public int add(@Nullable String originalValue) { - synchronized (lock) { + lock.writeLock().lock(); + try { if (originalValue == null) { if (idForNull == ABSENT_VALUE_ID) { - idForNull = size(); + idForNull = idToValue.size(); idToValue.add(null); } return idForNull; @@ -129,33 +143,48 @@ public class StringDimensionIndexer implements DimensionIndexer= 0) { return prev; } - final int index = size(); + final int index = idToValue.size(); valueToId.put(originalValue, index); idToValue.add(originalValue); minValue = minValue == null || minValue.compareTo(originalValue) > 0 ? originalValue : minValue; maxValue = maxValue == null || maxValue.compareTo(originalValue) < 0 ? originalValue : maxValue; return index; } + finally { + lock.writeLock().unlock(); + } } public String getMinValue() { - synchronized (lock) { + lock.readLock().lock(); + try { return minValue; } + finally { + lock.readLock().unlock(); + } } public String getMaxValue() { - synchronized (lock) { + lock.readLock().lock(); + try { return maxValue; } + finally { + lock.readLock().unlock(); + } } public SortedDimensionDictionary sort() { - synchronized (lock) { - return new SortedDimensionDictionary(idToValue, size()); + lock.readLock().lock(); + try { + return new SortedDimensionDictionary(idToValue, idToValue.size()); + } + finally { + lock.readLock().unlock(); } } }