From 5f70f34b6173ca667d19d9de914aab96836cec6b Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Tue, 5 Aug 2014 17:46:36 -0500 Subject: [PATCH] Additional performance tweaks in edge map implementations --- .../antlr/v4/runtime/dfa/ArrayEdgeMap.java | 2 +- .../v4/runtime/dfa/SingletonEdgeMap.java | 2 +- .../antlr/v4/runtime/dfa/SparseEdgeMap.java | 44 ++++++++----------- 3 files changed, 21 insertions(+), 27 deletions(-) diff --git a/runtime/Java/src/org/antlr/v4/runtime/dfa/ArrayEdgeMap.java b/runtime/Java/src/org/antlr/v4/runtime/dfa/ArrayEdgeMap.java index d3029bb415..e0ce35408a 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/dfa/ArrayEdgeMap.java +++ b/runtime/Java/src/org/antlr/v4/runtime/dfa/ArrayEdgeMap.java @@ -41,7 +41,7 @@ * * @author Sam Harwell */ -public class ArrayEdgeMap extends AbstractEdgeMap { +public final class ArrayEdgeMap extends AbstractEdgeMap { private final AtomicReferenceArray arrayData; private final AtomicInteger size; diff --git a/runtime/Java/src/org/antlr/v4/runtime/dfa/SingletonEdgeMap.java b/runtime/Java/src/org/antlr/v4/runtime/dfa/SingletonEdgeMap.java index 0062b422da..73fefc87c0 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/dfa/SingletonEdgeMap.java +++ b/runtime/Java/src/org/antlr/v4/runtime/dfa/SingletonEdgeMap.java @@ -37,7 +37,7 @@ * * @author Sam Harwell */ -public class SingletonEdgeMap extends AbstractEdgeMap { +public final class SingletonEdgeMap extends AbstractEdgeMap { private final int key; private final T value; diff --git a/runtime/Java/src/org/antlr/v4/runtime/dfa/SparseEdgeMap.java b/runtime/Java/src/org/antlr/v4/runtime/dfa/SparseEdgeMap.java index adad5e4a86..748f7fc51f 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/dfa/SparseEdgeMap.java +++ b/runtime/Java/src/org/antlr/v4/runtime/dfa/SparseEdgeMap.java @@ -41,7 +41,7 @@ * * @author Sam Harwell */ -public class SparseEdgeMap extends AbstractEdgeMap { +public final class SparseEdgeMap extends AbstractEdgeMap { private static final int DEFAULT_MAX_SIZE = 5; private final int[] keys; @@ -59,26 +59,26 @@ public SparseEdgeMap(int minIndex, int maxIndex, int maxSparseSize) { private SparseEdgeMap(@NotNull SparseEdgeMap map, int maxSparseSize) { super(map.minIndex, map.maxIndex); - if (maxSparseSize < map.values.size()) { - throw new IllegalArgumentException(); - } - synchronized (map) { + if (maxSparseSize < map.values.size()) { + throw new IllegalArgumentException(); + } + keys = Arrays.copyOf(map.keys, maxSparseSize); values = new ArrayList(maxSparseSize); values.addAll(map.values); } } - public int[] getKeys() { + public final int[] getKeys() { return keys; } - public List getValues() { + public final List getValues() { return values; } - public int getMaxSparseSize() { + public final int getMaxSparseSize() { return keys.length; } @@ -99,14 +99,15 @@ public boolean containsKey(int key) { @Override public T get(int key) { - synchronized (this) { - int index = Arrays.binarySearch(keys, 0, size(), key); - if (index < 0) { - return null; - } - - return values.get(index); + // Special property of this collection: values are only even added to + // the end, else a new object is returned from put(). Therefore no lock + // is required in this method. + int index = Arrays.binarySearch(keys, 0, size(), key); + if (index < 0) { + return null; } + + return values.get(index); } @Override @@ -147,7 +148,7 @@ public AbstractEdgeMap put(int key, T value) { } else { SparseEdgeMap resized = new SparseEdgeMap(this, desiredSize); - System.arraycopy(resized.keys, insertIndex, resized.keys, insertIndex + 1, resized.keys.length - insertIndex - 1); + System.arraycopy(resized.keys, insertIndex, resized.keys, insertIndex + 1, size() - insertIndex); resized.keys[insertIndex] = key; resized.values.add(insertIndex, value); return resized; @@ -163,11 +164,6 @@ public SparseEdgeMap remove(int key) { return this; } - if (index == values.size() - 1) { - values.remove(index); - return this; - } - SparseEdgeMap result = new SparseEdgeMap(this, getMaxSparseSize()); System.arraycopy(result.keys, index + 1, result.keys, index, size() - index - 1); result.values.remove(index); @@ -176,14 +172,12 @@ public SparseEdgeMap remove(int key) { } @Override - public SparseEdgeMap clear() { + public AbstractEdgeMap clear() { if (isEmpty()) { return this; } - SparseEdgeMap result = new SparseEdgeMap(this, getMaxSparseSize()); - result.values.clear(); - return result; + return new EmptyEdgeMap(minIndex, maxIndex); } @Override