You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by sn...@apache.org on 2017/03/03 18:02:46 UTC
cassandra git commit: Reduce lock contention for collection types and
serializers
Repository: cassandra
Updated Branches:
refs/heads/trunk a49cf2c6c -> b9b63925f
Reduce lock contention for collection types and serializers
patch by vincent royer; reviewed by Robert Stupp for CASSANDRA-13271
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/b9b63925
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/b9b63925
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/b9b63925
Branch: refs/heads/trunk
Commit: b9b63925f9b818637b986a300aee658df03a5500
Parents: a49cf2c
Author: vincent royer <vr...@vroyer.org>
Authored: Fri Mar 3 19:02:25 2017 +0100
Committer: Robert Stupp <sn...@snazy.de>
Committed: Fri Mar 3 19:02:25 2017 +0100
----------------------------------------------------------------------
CHANGES.txt | 1 +
.../cassandra/db/marshal/DynamicCompositeType.java | 11 +++++------
.../org/apache/cassandra/db/marshal/ListType.java | 15 +++++++--------
.../org/apache/cassandra/db/marshal/MapType.java | 15 +++++++--------
.../org/apache/cassandra/db/marshal/SetType.java | 15 +++++++--------
.../apache/cassandra/serializers/ListSerializer.java | 11 +++++------
.../apache/cassandra/serializers/MapSerializer.java | 11 +++++------
.../apache/cassandra/serializers/SetSerializer.java | 11 +++++------
8 files changed, 42 insertions(+), 48 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/b9b63925/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 9d07956..0ac9d50 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
4.0
+ * Reduce lock contention for collection types and serializers (CASSANDRA-13271)
* Make it possible to override MessagingService.Verb ids (CASSANDRA-13283)
* Avoid synchronized on prepareForRepair in ActiveRepairService (CASSANDRA-9292)
* Adds the ability to use uncompressed chunks in compressed files (CASSANDRA-10520)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/b9b63925/src/java/org/apache/cassandra/db/marshal/DynamicCompositeType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/DynamicCompositeType.java b/src/java/org/apache/cassandra/db/marshal/DynamicCompositeType.java
index d314bd9..cade725 100644
--- a/src/java/org/apache/cassandra/db/marshal/DynamicCompositeType.java
+++ b/src/java/org/apache/cassandra/db/marshal/DynamicCompositeType.java
@@ -21,6 +21,8 @@ import java.nio.charset.CharacterCodingException;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import org.apache.cassandra.cql3.Term;
import org.slf4j.Logger;
@@ -59,21 +61,18 @@ public class DynamicCompositeType extends AbstractCompositeType
private final Map<Byte, AbstractType<?>> aliases;
// interning instances
- private static final Map<Map<Byte, AbstractType<?>>, DynamicCompositeType> instances = new HashMap<Map<Byte, AbstractType<?>>, DynamicCompositeType>();
+ private static final ConcurrentMap<Map<Byte, AbstractType<?>>, DynamicCompositeType> instances = new ConcurrentHashMap<Map<Byte, AbstractType<?>>, DynamicCompositeType>();
public static synchronized DynamicCompositeType getInstance(TypeParser parser) throws ConfigurationException, SyntaxException
{
return getInstance(parser.getAliasParameters());
}
- public static synchronized DynamicCompositeType getInstance(Map<Byte, AbstractType<?>> aliases)
+ public static DynamicCompositeType getInstance(Map<Byte, AbstractType<?>> aliases)
{
DynamicCompositeType dct = instances.get(aliases);
if (dct == null)
- {
- dct = new DynamicCompositeType(aliases);
- instances.put(aliases, dct);
- }
+ dct = instances.computeIfAbsent(aliases, k -> new DynamicCompositeType(k));
return dct;
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/b9b63925/src/java/org/apache/cassandra/db/marshal/ListType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/ListType.java b/src/java/org/apache/cassandra/db/marshal/ListType.java
index e4c20e2..29ccaa5 100644
--- a/src/java/org/apache/cassandra/db/marshal/ListType.java
+++ b/src/java/org/apache/cassandra/db/marshal/ListType.java
@@ -19,6 +19,8 @@ package org.apache.cassandra.db.marshal;
import java.nio.ByteBuffer;
import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import org.apache.cassandra.cql3.Json;
import org.apache.cassandra.cql3.Lists;
@@ -39,8 +41,8 @@ public class ListType<T> extends CollectionType<List<T>>
private static final Logger logger = LoggerFactory.getLogger(ListType.class);
// interning instances
- private static final Map<AbstractType<?>, ListType> instances = new HashMap<>();
- private static final Map<AbstractType<?>, ListType> frozenInstances = new HashMap<>();
+ private static final ConcurrentMap<AbstractType<?>, ListType> instances = new ConcurrentHashMap<>();
+ private static final ConcurrentMap<AbstractType<?>, ListType> frozenInstances = new ConcurrentHashMap<>();
private final AbstractType<T> elements;
public final ListSerializer<T> serializer;
@@ -55,15 +57,12 @@ public class ListType<T> extends CollectionType<List<T>>
return getInstance(l.get(0), true);
}
- public static synchronized <T> ListType<T> getInstance(AbstractType<T> elements, boolean isMultiCell)
+ public static <T> ListType<T> getInstance(AbstractType<T> elements, final boolean isMultiCell)
{
- Map<AbstractType<?>, ListType> internMap = isMultiCell ? instances : frozenInstances;
+ ConcurrentMap<AbstractType<?>, ListType> internMap = isMultiCell ? instances : frozenInstances;
ListType<T> t = internMap.get(elements);
if (t == null)
- {
- t = new ListType<T>(elements, isMultiCell);
- internMap.put(elements, t);
- }
+ t = internMap.computeIfAbsent(elements, k -> new ListType<>(k, isMultiCell) );
return t;
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/b9b63925/src/java/org/apache/cassandra/db/marshal/MapType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/MapType.java b/src/java/org/apache/cassandra/db/marshal/MapType.java
index 48e90a0..1bfc044 100644
--- a/src/java/org/apache/cassandra/db/marshal/MapType.java
+++ b/src/java/org/apache/cassandra/db/marshal/MapType.java
@@ -19,6 +19,8 @@ package org.apache.cassandra.db.marshal;
import java.nio.ByteBuffer;
import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import org.apache.cassandra.cql3.Json;
import org.apache.cassandra.cql3.Maps;
@@ -35,8 +37,8 @@ import org.apache.cassandra.utils.Pair;
public class MapType<K, V> extends CollectionType<Map<K, V>>
{
// interning instances
- private static final Map<Pair<AbstractType<?>, AbstractType<?>>, MapType> instances = new HashMap<>();
- private static final Map<Pair<AbstractType<?>, AbstractType<?>>, MapType> frozenInstances = new HashMap<>();
+ private static final ConcurrentMap<Pair<AbstractType<?>, AbstractType<?>>, MapType> instances = new ConcurrentHashMap<>();
+ private static final ConcurrentMap<Pair<AbstractType<?>, AbstractType<?>>, MapType> frozenInstances = new ConcurrentHashMap<>();
private final AbstractType<K> keys;
private final AbstractType<V> values;
@@ -52,16 +54,13 @@ public class MapType<K, V> extends CollectionType<Map<K, V>>
return getInstance(l.get(0), l.get(1), true);
}
- public static synchronized <K, V> MapType<K, V> getInstance(AbstractType<K> keys, AbstractType<V> values, boolean isMultiCell)
+ public static <K, V> MapType<K, V> getInstance(AbstractType<K> keys, AbstractType<V> values, boolean isMultiCell)
{
- Map<Pair<AbstractType<?>, AbstractType<?>>, MapType> internMap = isMultiCell ? instances : frozenInstances;
+ ConcurrentMap<Pair<AbstractType<?>, AbstractType<?>>, MapType> internMap = isMultiCell ? instances : frozenInstances;
Pair<AbstractType<?>, AbstractType<?>> p = Pair.<AbstractType<?>, AbstractType<?>>create(keys, values);
MapType<K, V> t = internMap.get(p);
if (t == null)
- {
- t = new MapType<>(keys, values, isMultiCell);
- internMap.put(p, t);
- }
+ t = internMap.computeIfAbsent(p, k -> new MapType<>(k.left, k.right, isMultiCell) );
return t;
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/b9b63925/src/java/org/apache/cassandra/db/marshal/SetType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/SetType.java b/src/java/org/apache/cassandra/db/marshal/SetType.java
index fdd29ec..4374612 100644
--- a/src/java/org/apache/cassandra/db/marshal/SetType.java
+++ b/src/java/org/apache/cassandra/db/marshal/SetType.java
@@ -19,6 +19,8 @@ package org.apache.cassandra.db.marshal;
import java.nio.ByteBuffer;
import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import org.apache.cassandra.cql3.Json;
import org.apache.cassandra.cql3.Sets;
@@ -33,8 +35,8 @@ import org.apache.cassandra.transport.ProtocolVersion;
public class SetType<T> extends CollectionType<Set<T>>
{
// interning instances
- private static final Map<AbstractType<?>, SetType> instances = new HashMap<>();
- private static final Map<AbstractType<?>, SetType> frozenInstances = new HashMap<>();
+ private static final ConcurrentMap<AbstractType<?>, SetType> instances = new ConcurrentHashMap<>();
+ private static final ConcurrentMap<AbstractType<?>, SetType> frozenInstances = new ConcurrentHashMap<>();
private final AbstractType<T> elements;
private final SetSerializer<T> serializer;
@@ -49,15 +51,12 @@ public class SetType<T> extends CollectionType<Set<T>>
return getInstance(l.get(0), true);
}
- public static synchronized <T> SetType<T> getInstance(AbstractType<T> elements, boolean isMultiCell)
+ public static <T> SetType<T> getInstance(AbstractType<T> elements, boolean isMultiCell)
{
- Map<AbstractType<?>, SetType> internMap = isMultiCell ? instances : frozenInstances;
+ ConcurrentMap<AbstractType<?>, SetType> internMap = isMultiCell ? instances : frozenInstances;
SetType<T> t = internMap.get(elements);
if (t == null)
- {
- t = new SetType<T>(elements, isMultiCell);
- internMap.put(elements, t);
- }
+ t = internMap.computeIfAbsent(elements, k -> new SetType<>(k, isMultiCell) );
return t;
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/b9b63925/src/java/org/apache/cassandra/serializers/ListSerializer.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/serializers/ListSerializer.java b/src/java/org/apache/cassandra/serializers/ListSerializer.java
index 44c33a6..3a20cd5 100644
--- a/src/java/org/apache/cassandra/serializers/ListSerializer.java
+++ b/src/java/org/apache/cassandra/serializers/ListSerializer.java
@@ -23,22 +23,21 @@ import org.apache.cassandra.transport.ProtocolVersion;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
public class ListSerializer<T> extends CollectionSerializer<List<T>>
{
// interning instances
- private static final Map<TypeSerializer<?>, ListSerializer> instances = new HashMap<TypeSerializer<?>, ListSerializer>();
+ private static final ConcurrentMap<TypeSerializer<?>, ListSerializer> instances = new ConcurrentHashMap<TypeSerializer<?>, ListSerializer>();
public final TypeSerializer<T> elements;
- public static synchronized <T> ListSerializer<T> getInstance(TypeSerializer<T> elements)
+ public static <T> ListSerializer<T> getInstance(TypeSerializer<T> elements)
{
ListSerializer<T> t = instances.get(elements);
if (t == null)
- {
- t = new ListSerializer<T>(elements);
- instances.put(elements, t);
- }
+ t = instances.computeIfAbsent(elements, k -> new ListSerializer<>(k) );
return t;
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/b9b63925/src/java/org/apache/cassandra/serializers/MapSerializer.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/serializers/MapSerializer.java b/src/java/org/apache/cassandra/serializers/MapSerializer.java
index 1722832..7ba45d6 100644
--- a/src/java/org/apache/cassandra/serializers/MapSerializer.java
+++ b/src/java/org/apache/cassandra/serializers/MapSerializer.java
@@ -21,6 +21,8 @@ package org.apache.cassandra.serializers;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import org.apache.cassandra.db.marshal.AbstractType;
import org.apache.cassandra.transport.ProtocolVersion;
@@ -29,21 +31,18 @@ import org.apache.cassandra.utils.Pair;
public class MapSerializer<K, V> extends CollectionSerializer<Map<K, V>>
{
// interning instances
- private static final Map<Pair<TypeSerializer<?>, TypeSerializer<?>>, MapSerializer> instances = new HashMap<Pair<TypeSerializer<?>, TypeSerializer<?>>, MapSerializer>();
+ private static final ConcurrentMap<Pair<TypeSerializer<?>, TypeSerializer<?>>, MapSerializer> instances = new ConcurrentHashMap<Pair<TypeSerializer<?>, TypeSerializer<?>>, MapSerializer>();
public final TypeSerializer<K> keys;
public final TypeSerializer<V> values;
private final Comparator<Pair<ByteBuffer, ByteBuffer>> comparator;
- public static synchronized <K, V> MapSerializer<K, V> getInstance(TypeSerializer<K> keys, TypeSerializer<V> values, Comparator<ByteBuffer> comparator)
+ public static <K, V> MapSerializer<K, V> getInstance(TypeSerializer<K> keys, TypeSerializer<V> values, Comparator<ByteBuffer> comparator)
{
Pair<TypeSerializer<?>, TypeSerializer<?>> p = Pair.<TypeSerializer<?>, TypeSerializer<?>>create(keys, values);
MapSerializer<K, V> t = instances.get(p);
if (t == null)
- {
- t = new MapSerializer<K, V>(keys, values, comparator);
- instances.put(p, t);
- }
+ t = instances.computeIfAbsent(p, k -> new MapSerializer<>(k.left, k.right, comparator) );
return t;
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/b9b63925/src/java/org/apache/cassandra/serializers/SetSerializer.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/serializers/SetSerializer.java b/src/java/org/apache/cassandra/serializers/SetSerializer.java
index a440234..b874978 100644
--- a/src/java/org/apache/cassandra/serializers/SetSerializer.java
+++ b/src/java/org/apache/cassandra/serializers/SetSerializer.java
@@ -21,25 +21,24 @@ package org.apache.cassandra.serializers;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import org.apache.cassandra.transport.ProtocolVersion;
public class SetSerializer<T> extends CollectionSerializer<Set<T>>
{
// interning instances
- private static final Map<TypeSerializer<?>, SetSerializer> instances = new HashMap<TypeSerializer<?>, SetSerializer>();
+ private static final ConcurrentMap<TypeSerializer<?>, SetSerializer> instances = new ConcurrentHashMap<TypeSerializer<?>, SetSerializer>();
public final TypeSerializer<T> elements;
private final Comparator<ByteBuffer> comparator;
- public static synchronized <T> SetSerializer<T> getInstance(TypeSerializer<T> elements, Comparator<ByteBuffer> elementComparator)
+ public static <T> SetSerializer<T> getInstance(TypeSerializer<T> elements, Comparator<ByteBuffer> elementComparator)
{
SetSerializer<T> t = instances.get(elements);
if (t == null)
- {
- t = new SetSerializer<T>(elements, elementComparator);
- instances.put(elements, t);
- }
+ t = instances.computeIfAbsent(elements, k -> new SetSerializer<>(k, elementComparator) );
return t;
}