Use ReentrantReadWriteLock in DimensionDictionary (#5883)

This commit is contained in:
陈春斌 2018-06-26 03:35:26 +08:00 committed by Jonathan Wei
parent a28314349c
commit 7649742943
1 changed files with 41 additions and 12 deletions

View File

@ -55,6 +55,7 @@ import java.util.Arrays;
import java.util.BitSet; import java.util.BitSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class StringDimensionIndexer implements DimensionIndexer<Integer, int[], String> public class StringDimensionIndexer implements DimensionIndexer<Integer, int[], String>
{ {
@ -79,48 +80,61 @@ public class StringDimensionIndexer implements DimensionIndexer<Integer, int[],
private final Object2IntMap<String> valueToId = new Object2IntOpenHashMap<>(); private final Object2IntMap<String> valueToId = new Object2IntOpenHashMap<>();
private final List<String> idToValue = Lists.newArrayList(); private final List<String> idToValue = Lists.newArrayList();
private final Object lock; private final ReentrantReadWriteLock lock;
public DimensionDictionary() public DimensionDictionary()
{ {
this.lock = new Object(); this.lock = new ReentrantReadWriteLock();
valueToId.defaultReturnValue(-1); valueToId.defaultReturnValue(-1);
} }
public int getId(String value) public int getId(String value)
{ {
synchronized (lock) { lock.readLock().lock();
try {
if (value == null) { if (value == null) {
return idForNull; return idForNull;
} }
return valueToId.getInt(value); return valueToId.getInt(value);
} }
finally {
lock.readLock().unlock();
}
} }
public String getValue(int id) public String getValue(int id)
{ {
synchronized (lock) { lock.readLock().lock();
try {
if (id == idForNull) { if (id == idForNull) {
return null; return null;
} }
return idToValue.get(id); return idToValue.get(id);
} }
finally {
lock.readLock().unlock();
}
} }
public int size() 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. // using idToValue rather than valueToId because the valueToId doesn't account null value, if it is present.
return idToValue.size(); return idToValue.size();
} }
finally {
lock.readLock().unlock();
}
} }
public int add(@Nullable String originalValue) public int add(@Nullable String originalValue)
{ {
synchronized (lock) { lock.writeLock().lock();
try {
if (originalValue == null) { if (originalValue == null) {
if (idForNull == ABSENT_VALUE_ID) { if (idForNull == ABSENT_VALUE_ID) {
idForNull = size(); idForNull = idToValue.size();
idToValue.add(null); idToValue.add(null);
} }
return idForNull; return idForNull;
@ -129,33 +143,48 @@ public class StringDimensionIndexer implements DimensionIndexer<Integer, int[],
if (prev >= 0) { if (prev >= 0) {
return prev; return prev;
} }
final int index = size(); final int index = idToValue.size();
valueToId.put(originalValue, index); valueToId.put(originalValue, index);
idToValue.add(originalValue); idToValue.add(originalValue);
minValue = minValue == null || minValue.compareTo(originalValue) > 0 ? originalValue : minValue; minValue = minValue == null || minValue.compareTo(originalValue) > 0 ? originalValue : minValue;
maxValue = maxValue == null || maxValue.compareTo(originalValue) < 0 ? originalValue : maxValue; maxValue = maxValue == null || maxValue.compareTo(originalValue) < 0 ? originalValue : maxValue;
return index; return index;
} }
finally {
lock.writeLock().unlock();
}
} }
public String getMinValue() public String getMinValue()
{ {
synchronized (lock) { lock.readLock().lock();
try {
return minValue; return minValue;
} }
finally {
lock.readLock().unlock();
}
} }
public String getMaxValue() public String getMaxValue()
{ {
synchronized (lock) { lock.readLock().lock();
try {
return maxValue; return maxValue;
} }
finally {
lock.readLock().unlock();
}
} }
public SortedDimensionDictionary sort() public SortedDimensionDictionary sort()
{ {
synchronized (lock) { lock.readLock().lock();
return new SortedDimensionDictionary(idToValue, size()); try {
return new SortedDimensionDictionary(idToValue, idToValue.size());
}
finally {
lock.readLock().unlock();
} }
} }
} }