diff --git a/src/builder/java/speiger/src/builder/GlobalVariables.java b/src/builder/java/speiger/src/builder/GlobalVariables.java
index cf6c1bb9..59a88c79 100644
--- a/src/builder/java/speiger/src/builder/GlobalVariables.java
+++ b/src/builder/java/speiger/src/builder/GlobalVariables.java
@@ -174,7 +174,7 @@ public class GlobalVariables
addBiClassMapper("LINKED_CUSTOM_HASH_MAP", "LinkedOpenCustomHashMap", "2");
addBiClassMapper("LINKED_HASH_MAP", "LinkedOpenHashMap", "2");
addBiClassMapper("CUSTOM_HASH_MAP", "OpenCustomHashMap", "2");
- addBiClassMapper("CONCURRENT_MAP", "ConcurrentOpenHashMap", "2");
+ addBiClassMapper("CONCURRENT_HASH_MAP", "ConcurrentOpenHashMap", "2");
addBiClassMapper("AVL_TREE_MAP", "AVLTreeMap", "2");
addBiClassMapper("RB_TREE_MAP", "RBTreeMap", "2");
addFunctionValueMappers("LINKED_ENUM_MAP", valueType.isObject() ? "LinkedEnum2ObjectMap" : "LinkedEnum2%sMap");
@@ -224,6 +224,7 @@ public class GlobalVariables
addBiClassMapper("NAVIGABLE_MAP", "NavigableMap", "2");
addBiClassMapper("ORDERED_MAP", "OrderedMap", "2");
addBiClassMapper("SORTED_MAP", "SortedMap", "2");
+ addBiClassMapper("CONCURRENT_MAP", "ConcurrentMap", "2");
addBiClassMapper("MAP", "Map", "2");
addClassMapper("NAVIGABLE_SET", "NavigableSet");
addBiClassMapper("PAIR", "Pair", "");
diff --git a/src/builder/java/speiger/src/builder/PrimitiveCollectionsBuilder.java b/src/builder/java/speiger/src/builder/PrimitiveCollectionsBuilder.java
index 1066531e..c2454921 100644
--- a/src/builder/java/speiger/src/builder/PrimitiveCollectionsBuilder.java
+++ b/src/builder/java/speiger/src/builder/PrimitiveCollectionsBuilder.java
@@ -83,7 +83,7 @@ public class PrimitiveCollectionsBuilder extends TemplateProcessor
biRequired.put("Pair", "");
biRequired.put("MutablePair", "");
biRequired.put("ImmutablePair", "");
- addBiClass("Function", "Maps", "Map", "SortedMap", "OrderedMap", "NavigableMap", "AbstractMap", "ConcurrentOpenHashMap", "ImmutableOpenHashMap", "OpenHashMap", "LinkedOpenHashMap", "OpenCustomHashMap", "LinkedOpenCustomHashMap", "ArrayMap", "RBTreeMap", "AVLTreeMap");
+ addBiClass("Function", "Maps", "Map", "SortedMap", "OrderedMap", "NavigableMap", "ConcurrentMap", "AbstractMap", "ConcurrentOpenHashMap", "ImmutableOpenHashMap", "OpenHashMap", "LinkedOpenHashMap", "OpenCustomHashMap", "LinkedOpenCustomHashMap", "ArrayMap", "RBTreeMap", "AVLTreeMap");
nameRemapper.put("BiConsumer", "%sConsumer");
nameRemapper.put("IArray", "I%sArray");
nameRemapper.put("AbstractMap", "Abstract%sMap");
@@ -100,7 +100,7 @@ public class PrimitiveCollectionsBuilder extends TemplateProcessor
addBlockage(ClassType.OBJECT, "Consumer", "Comparator", "Stack");
addBlockage(ClassType.BOOLEAN, "ArraySet", "AVLTreeSet", "RBTreeSet", "SortedSet", "OrderedSet", "NavigableSet", "OpenHashSet", "OpenCustomHashSet", "LinkedOpenHashSet", "LinkedOpenCustomHashSet");
- addBlockage(ClassType.BOOLEAN, "ConcurrentOpenHashMap", "ImmutableOpenHashMap", "ImmutableOpenHashSet", "SortedMap", "OrderedMap", "NavigableMap", "OpenHashMap", "LinkedOpenHashMap", "OpenCustomHashMap", "LinkedOpenCustomHashMap", "ArrayMap", "RBTreeMap", "AVLTreeMap");
+ addBlockage(ClassType.BOOLEAN, "ConcurrentOpenHashMap", "ImmutableOpenHashMap", "ImmutableOpenHashSet", "SortedMap", "OrderedMap", "NavigableMap", "ConcurrentMap", "OpenHashMap", "LinkedOpenHashMap", "OpenCustomHashMap", "LinkedOpenCustomHashMap", "ArrayMap", "RBTreeMap", "AVLTreeMap");
}
protected void create(ClassType mainType, ClassType subType)
diff --git a/src/builder/resources/speiger/assets/collections/templates/maps/impl/concurrent/ConcurrentOpenHashMap.template b/src/builder/resources/speiger/assets/collections/templates/maps/impl/concurrent/ConcurrentOpenHashMap.template
index db48b3c2..3d67c022 100644
--- a/src/builder/resources/speiger/assets/collections/templates/maps/impl/concurrent/ConcurrentOpenHashMap.template
+++ b/src/builder/resources/speiger/assets/collections/templates/maps/impl/concurrent/ConcurrentOpenHashMap.template
@@ -6,6 +6,7 @@ import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
+
import java.util.function.BiFunction;
#if !TYPE_OBJECT
@@ -27,6 +28,7 @@ import speiger.src.collections.PACKAGE.functions.function.PREDICATE;
#endif
import speiger.src.collections.PACKAGE.maps.abstracts.ABSTRACT_MAP;
import speiger.src.collections.PACKAGE.maps.interfaces.MAP;
+import speiger.src.collections.PACKAGE.maps.interfaces.CONCURRENT_MAP;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.SET;
@@ -72,13 +74,23 @@ import speiger.src.collections.objects.sets.AbstractObjectSet;
import speiger.src.collections.objects.sets.ObjectSet;
import speiger.src.collections.utils.HashUtil;
-@SuppressWarnings("javadoc")
-public class CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE
+/**
+ * A TypeSpecific ConcurrentHashMap implementation that is based on Guavas approach and backing array implementations.
+ * Like Guavas implementation this solution can be accessed by multiple threads, but it is not as flexible as Javas implementation.
+ * The concurrencyLevel decides how many pools exist, and each pool can be accessed by 1 thread for writing and as many threads for reading.
+ *
+ * @Type(T)
+ * @ValueType(V)
+ */
+public class CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GENERIC_TYPE implements CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE
{
+ /** Segment Limit */
private static final int MAX_SEGMENTS = 1 << 16;
-
+ /** Buckets of the ConcurrentMap */
protected transient Segment KEY_VALUE_GENERIC_TYPE[] segments;
+ /** Bitshift of the HashCode */
protected transient int segmentShift;
+ /** Max Bits thats used in the segments */
protected transient int segmentMask;
/** EntrySet cache */
protected transient FastEntrySet KEY_VALUE_GENERIC_TYPE entrySet;
@@ -87,12 +99,74 @@ public class CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALU
/** Values cache */
protected transient VALUE_COLLECTION VALUE_GENERIC_TYPE values;
- protected CONCURRENT_MAP(boolean unused) {}
+ /**
+ * Copy constructor that doesn't trigger the building of segments and allows to copy it faster.
+ * @param unused not used, Just to keep all constructors accessible.
+ */
+ protected CONCURRENT_HASH_MAP(boolean unused) {}
- public CONCURRENT_MAP(int minCapacity, float loadFactor, int concurrencyLevel) {
+ /**
+ * Default Constructor
+ */
+ public CONCURRENT_HASH_MAP() {
+ this(HashUtil.DEFAULT_MIN_CAPACITY, HashUtil.DEFAULT_LOAD_FACTOR, HashUtil.DEFAULT_MIN_CONCURRENCY);
+ }
+
+ /**
+ * Constructor that defines the minimum capacity
+ * @param minCapacity the minimum capacity the HashMap is allowed to be.
+ * @throws IllegalStateException if the minimum capacity is negative
+ */
+ public CONCURRENT_HASH_MAP(int minCapacity) {
+ this(minCapacity, HashUtil.DEFAULT_LOAD_FACTOR, HashUtil.DEFAULT_MIN_CONCURRENCY);
+ }
+
+ /**
+ * Constructor that defines the minimum capacity and load factor
+ * @param minCapacity the minimum capacity the HashMap is allowed to be.
+ * @param loadFactor the percentage of how full the backing array can be before they resize
+ * @throws IllegalStateException if the minimum capacity is negative
+ * @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
+ */
+ public CONCURRENT_HASH_MAP(int minCapacity, float loadFactor) {
+ this(minCapacity, loadFactor, HashUtil.DEFAULT_MIN_CONCURRENCY);
+ }
+
+ /**
+ * Constructor that defines the minimum capacity and concurrencyLevel
+ * @param minCapacity the minimum capacity the HashMap is allowed to be.
+ * @param concurrencyLevel decides how many operations can be performed at once.
+ * @throws IllegalStateException if the minimum capacity is negative
+ * @throws IllegalStateException if the concurrencyLevel is either below/equal to 0 or above/equal to 65535
+ */
+ public CONCURRENT_HASH_MAP(int minCapacity, int concurrencyLevel) {
+ this(minCapacity, HashUtil.DEFAULT_LOAD_FACTOR, concurrencyLevel);
+ }
+
+ /**
+ * Constructor that defines the load factor and concurrencyLevel
+ * @param loadFactor the percentage of how full the backing array can be before they resize
+ * @param concurrencyLevel decides how many operations can be performed at once.
+ * @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
+ * @throws IllegalStateException if the concurrencyLevel is either below/equal to 0 or above/equal to 65535
+ */
+ public CONCURRENT_HASH_MAP(float loadFactor, int concurrencyLevel) {
+ this(HashUtil.DEFAULT_MIN_CAPACITY, loadFactor, concurrencyLevel);
+ }
+
+ /**
+ * Constructor that defines the minimum capacity, load factor and concurrencyLevel
+ * @param minCapacity the minimum capacity the HashMap is allowed to be.
+ * @param loadFactor the percentage of how full the backing array can be before they resize
+ * @param concurrencyLevel decides how many operations can be performed at once.
+ * @throws IllegalStateException if the minimum capacity is negative
+ * @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
+ * @throws IllegalStateException if the concurrencyLevel is either below/equal to 0 or above/equal to 65535
+ */
+ public CONCURRENT_HASH_MAP(int minCapacity, float loadFactor, int concurrencyLevel) {
if(minCapacity < 0) throw new IllegalStateException("Minimum Capacity is negative. This is not allowed");
if(loadFactor <= 0 || loadFactor >= 1F) throw new IllegalStateException("Load Factor is not between 0 and 1");
- if(concurrencyLevel < 0 || concurrencyLevel >= MAX_SEGMENTS) throw new IllegalStateException("concurrencyLevel has to be between 0 and 65536");
+ if(concurrencyLevel <= 0 || concurrencyLevel >= MAX_SEGMENTS) throw new IllegalStateException("concurrencyLevel has to be between 0 and 65536");
int segmentCount = HashUtil.nextPowerOfTwo(concurrencyLevel);
int shift = Integer.numberOfTrailingZeros(segmentCount);
segments = new Segment[segmentCount];
@@ -108,6 +182,190 @@ public class CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALU
}
}
+#if !TYPE_OBJECT || !VALUE_OBJECT
+ /**
+ * Helper constructor that allow to create a map from boxed values (it will unbox them)
+ * @param keys the keys that should be put into the map
+ * @param values the values that should be put into the map.
+ * @throws IllegalStateException if the keys and values do not match in lenght
+ */
+ public CONCURRENT_HASH_MAP(CLASS_TYPE[] keys, CLASS_VALUE_TYPE[] values) {
+ this(keys, values, HashUtil.DEFAULT_LOAD_FACTOR, HashUtil.DEFAULT_MIN_CONCURRENCY);
+ }
+
+ /**
+ * Helper constructor that allow to create a map from boxed values (it will unbox them)
+ * @param keys the keys that should be put into the map
+ * @param values the values that should be put into the map.
+ * @param loadFactor the percentage of how full the backing array can be before they resize
+ * @throws IllegalStateException if the keys and values do not match in lenght
+ * @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
+ */
+ public CONCURRENT_HASH_MAP(CLASS_TYPE[] keys, CLASS_VALUE_TYPE[] values, float loadFactor) {
+ this(keys, values, loadFactor, HashUtil.DEFAULT_MIN_CONCURRENCY);
+ }
+
+ /**
+ * Helper constructor that allow to create a map from boxed values (it will unbox them)
+ * @param keys the keys that should be put into the map
+ * @param values the values that should be put into the map.
+ * @param concurrencyLevel decides how many operations can be performed at once.
+ * @throws IllegalStateException if the keys and values do not match in lenght
+ * @throws IllegalStateException if the concurrencyLevel is either below/equal to 0 or above/equal to 65535
+ */
+ public CONCURRENT_HASH_MAP(CLASS_TYPE[] keys, CLASS_VALUE_TYPE[] values, int concurrencyLevel) {
+ this(keys, values, HashUtil.DEFAULT_LOAD_FACTOR, concurrencyLevel);
+ }
+
+ /**
+ * Helper constructor that allow to create a map from boxed values (it will unbox them)
+ * @param keys the keys that should be put into the map
+ * @param values the values that should be put into the map.
+ * @param loadFactor the percentage of how full the backing array can be before they resize
+ * @param concurrencyLevel decides how many operations can be performed at once.
+ * @throws IllegalStateException if the keys and values do not match in lenght
+ * @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
+ * @throws IllegalStateException if the concurrencyLevel is either below/equal to 0 or above/equal to 65535
+ */
+ public CONCURRENT_HASH_MAP(CLASS_TYPE[] keys, CLASS_VALUE_TYPE[] values, float loadFactor, int concurrencyLevel) {
+ this(keys.length, loadFactor, concurrencyLevel);
+ if(keys.length != values.length) throw new IllegalStateException("Input Arrays are not equal size");
+ for(int i = 0,m=keys.length;i map) {
+ this(map, HashUtil.DEFAULT_LOAD_FACTOR, HashUtil.DEFAULT_MIN_CONCURRENCY);
+ }
+
+ /**
+ * A Helper constructor that allows to create a Map with exactly the same values as the provided map.
+ * @param map the values that should be present in the map
+ * @param loadFactor the percentage of how full the backing array can be before they resize
+ * @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
+ */
+ public CONCURRENT_HASH_MAP(Map extends CLASS_TYPE, ? extends CLASS_VALUE_TYPE> map, float loadFactor) {
+ this(map, loadFactor, HashUtil.DEFAULT_MIN_CONCURRENCY);
+ }
+
+ /**
+ * A Helper constructor that allows to create a Map with exactly the same values as the provided map.
+ * @param map the values that should be present in the map
+ * @param concurrencyLevel decides how many operations can be performed at once.
+ * @throws IllegalStateException if the concurrencyLevel is either below/equal to 0 or above/equal to 65535
+ */
+ public CONCURRENT_HASH_MAP(Map extends CLASS_TYPE, ? extends CLASS_VALUE_TYPE> map, int concurrencyLevel) {
+ this(map, HashUtil.DEFAULT_LOAD_FACTOR, concurrencyLevel);
+ }
+
+ /**
+ * A Helper constructor that allows to create a Map with exactly the same values as the provided map.
+ * @param map the values that should be present in the map
+ * @param loadFactor the percentage of how full the backing array can be before they resize
+ * @param concurrencyLevel decides how many operations can be performed at once.
+ * @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
+ * @throws IllegalStateException if the concurrencyLevel is either below/equal to 0 or above/equal to 65535
+ */
+ public CONCURRENT_HASH_MAP(Map extends CLASS_TYPE, ? extends CLASS_VALUE_TYPE> map, float loadFactor, int concurrencyLevel) {
+ this(map.size(), loadFactor, concurrencyLevel);
+ putAll(map);
+ }
+
+ /**
+ * A Type Specific Helper function that allows to create a new Map with exactly the same values as the provided map.
+ * @param map the values that should be present in the map
+ */
+ public CONCURRENT_HASH_MAP(MAP KEY_VALUE_GENERIC_TYPE map) {
+ this(map, HashUtil.DEFAULT_LOAD_FACTOR, HashUtil.DEFAULT_MIN_CONCURRENCY);
+ }
+
+ /**
+ * A Type Specific Helper function that allows to create a new Map with exactly the same values as the provided map.
+ * @param map the values that should be present in the map
+ * @param loadFactor the percentage of how full the backing array can be before they resize
+ * @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
+ */
+ public CONCURRENT_HASH_MAP(MAP KEY_VALUE_GENERIC_TYPE map, float loadFactor) {
+ this(map, loadFactor, HashUtil.DEFAULT_MIN_CONCURRENCY);
+ }
+
+ /**
+ * A Type Specific Helper function that allows to create a new Map with exactly the same values as the provided map.
+ * @param map the values that should be present in the map
+ * @param concurrencyLevel decides how many operations can be performed at once.
+ * @throws IllegalStateException if the concurrencyLevel is either below/equal to 0 or above/equal to 65535
+ */
+ public CONCURRENT_HASH_MAP(MAP KEY_VALUE_GENERIC_TYPE map, int concurrencyLevel) {
+ this(map, HashUtil.DEFAULT_LOAD_FACTOR, concurrencyLevel);
+ }
+
+ /**
+ * A Type Specific Helper function that allows to create a new Map with exactly the same values as the provided map.
+ * @param map the values that should be present in the map
+ * @param loadFactor the percentage of how full the backing array can be before they resize
+ * @param concurrencyLevel decides how many operations can be performed at once.
+ * @throws IllegalStateException if the loadfactor is either below/equal to 0 or above/equal to 1
+ * @throws IllegalStateException if the concurrencyLevel is either below/equal to 0 or above/equal to 65535
+ */
+ public CONCURRENT_HASH_MAP(MAP KEY_VALUE_GENERIC_TYPE map, float loadFactor, int concurrencyLevel) {
+ this(map.size(), loadFactor, concurrencyLevel);
+ putAll(map);
+ }
+
@Override
public VALUE_TYPE put(KEY_TYPE key, VALUE_TYPE value) {
int hash = getHashCode(key);
@@ -196,8 +454,8 @@ public class CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALU
}
@Override
- public CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE copy() {
- CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE copy = new CONCURRENT_MAPKV_BRACES(false);
+ public CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE copy() {
+ CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE copy = new CONCURRENT_HASH_MAPKV_BRACES(false);
copy.segmentShift = segmentShift;
copy.segmentMask = segmentMask;
copy.segments = new Segment[segments.length];
@@ -331,31 +589,17 @@ public class CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALU
return HashUtil.mix(Objects.hashCode(obj));
}
- public void test() {
-
- }
-
private class MapEntrySet extends AbstractObjectSet implements MAP.FastEntrySet KEY_VALUE_GENERIC_TYPE {
@Override
public ObjectBidirectionalIterator iterator() {
return new EntryIterator();
}
- //TODO implement?
- public ObjectBidirectionalIterator iterator(MAP.Entry KEY_VALUE_GENERIC_TYPE fromElement) {
- return new EntryIterator(fromElement.ENTRY_KEY());
- }
-
@Override
public ObjectBidirectionalIterator fastIterator() {
return new FastEntryIterator();
}
- //TODO implement?
- public ObjectBidirectionalIterator fastIterator(KEY_TYPE fromElement) {
- return new FastEntryIterator(fromElement);
- }
-
@Override
public MapEntrySet copy() { throw new UnsupportedOperationException(); }
@@ -546,22 +790,22 @@ public class CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALU
if(o instanceof Map.Entry) {
if(o instanceof MAP.Entry) {
MAP.Entry KEY_VALUE_GENERIC_TYPE entry = (MAP.Entry KEY_VALUE_GENERIC_TYPE)o;
- return CONCURRENT_MAP.this.remove(entry.ENTRY_KEY(), entry.ENTRY_VALUE());
+ return CONCURRENT_HASH_MAP.this.remove(entry.ENTRY_KEY(), entry.ENTRY_VALUE());
}
Map.Entry, ?> entry = (Map.Entry, ?>)o;
- return CONCURRENT_MAP.this.remove(entry.getKey(), entry.getValue());
+ return CONCURRENT_HASH_MAP.this.remove(entry.getKey(), entry.getValue());
}
return false;
}
@Override
public int size() {
- return CONCURRENT_MAP.this.size();
+ return CONCURRENT_HASH_MAP.this.size();
}
@Override
public void clear() {
- CONCURRENT_MAP.this.clear();
+ CONCURRENT_HASH_MAP.this.clear();
}
}
@@ -580,7 +824,7 @@ public class CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALU
@Override
public boolean remove(Object o) {
int oldSize = size();
- CONCURRENT_MAP.this.remove(o);
+ CONCURRENT_HASH_MAP.this.remove(o);
return size() != oldSize;
}
@@ -593,7 +837,7 @@ public class CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALU
@Override
public boolean remove(KEY_TYPE o) {
int oldSize = size();
- CONCURRENT_MAP.this.remove(o);
+ CONCURRENT_HASH_MAP.this.remove(o);
return size() != oldSize;
}
@@ -603,22 +847,17 @@ public class CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALU
return new KeyIterator();
}
- //TODO implement into interface?
- public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) {
- return new KeyIterator(fromElement);
- }
-
@Override
public KeySet copy() { throw new UnsupportedOperationException(); }
@Override
public int size() {
- return CONCURRENT_MAP.this.size();
+ return CONCURRENT_HASH_MAP.this.size();
}
@Override
public void clear() {
- CONCURRENT_MAP.this.clear();
+ CONCURRENT_HASH_MAP.this.clear();
}
@Override
@@ -801,12 +1040,12 @@ public class CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALU
@Override
public int size() {
- return CONCURRENT_MAP.this.size();
+ return CONCURRENT_HASH_MAP.this.size();
}
@Override
public void clear() {
- CONCURRENT_MAP.this.clear();
+ CONCURRENT_HASH_MAP.this.clear();
}
@Override
@@ -967,9 +1206,6 @@ public class CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALU
MapEntry entry = new MapEntry();
public FastEntryIterator() {}
- public FastEntryIterator(KEY_TYPE from) {
- super(from);
- }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
@@ -988,9 +1224,6 @@ public class CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALU
MapEntry entry;
public EntryIterator() {}
- public EntryIterator(KEY_TYPE from) {
- super(from);
- }
@Override
public MAP.Entry KEY_VALUE_GENERIC_TYPE next() {
@@ -1030,9 +1263,6 @@ public class CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALU
private class KeyIterator extends MapIterator implements BI_ITERATOR KEY_GENERIC_TYPE {
public KeyIterator() {}
- public KeyIterator(KEY_TYPE from) {
- super(from);
- }
@Override
public KEY_TYPE PREVIOUS() {
@@ -1062,17 +1292,6 @@ public class CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALU
if(nextSegment != -1) next = segments[nextSegment].firstIndex;
}
- MapIterator(KEY_TYPE from) {
- int hash = getHashCode(from);
- previousSegment = currentSegment = nextSegment = getSegmentIndex(hash);
- Segment KEY_VALUE_GENERIC_TYPE seg = segments[currentSegment];
- current = previous = seg.findIndex(hash, from);
- if(current == -1) throw new NoSuchElementException("The element was not found");
- findNextIndex();
- current = -1;
- currentSegment = -1;
- }
-
public boolean hasNext() {
return next != -1;
}
@@ -1267,7 +1486,7 @@ public class CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALU
protected static class Segment KEY_VALUE_GENERIC_TYPE extends ReentrantLock
{
private static final long serialVersionUID = -446894977795760975L;
- protected final CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE map;
+ protected final CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE map;
/** The Backing keys array */
protected transient KEY_TYPE[] keys;
/** The Backing values array */
@@ -1293,11 +1512,11 @@ public class CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALU
/** How full the Arrays are allowed to get before resize */
protected float loadFactor;
- protected Segment(CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE map) {
+ protected Segment(CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE map) {
this.map = map;
}
- protected Segment(CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE map, int minCapacity, float loadFactor, boolean isNullContainer) {
+ protected Segment(CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE map, int minCapacity, float loadFactor, boolean isNullContainer) {
this.map = map;
this.minCapacity = minCapacity;
this.loadFactor = loadFactor;
@@ -1310,21 +1529,28 @@ public class CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALU
links = new long[arraySize];
}
- protected Segment KEY_VALUE_GENERIC_TYPE copy(CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE newMap) {
- Segment KEY_VALUE_GENERIC_TYPE copy = new SegmentKV_BRACES(newMap);
- copy.keys = Arrays.copyOf(keys, keys.length);
- copy.values = Arrays.copyOf(values, values.length);
- copy.links = Arrays.copyOf(links, links.length);
- copy.firstIndex = firstIndex;
- copy.lastIndex = lastIndex;
- copy.containsNull = containsNull;
- copy.nullIndex = nullIndex;
- copy.maxFill = maxFill;
- copy.mask = mask;
- copy.size = size;
- copy.minCapacity = minCapacity;
- copy.loadFactor = loadFactor;
- return copy;
+ protected Segment KEY_VALUE_GENERIC_TYPE copy(CONCURRENT_HASH_MAP KEY_VALUE_GENERIC_TYPE newMap) {
+ lock();
+ try
+ {
+ Segment KEY_VALUE_GENERIC_TYPE copy = new SegmentKV_BRACES(newMap);
+ copy.keys = Arrays.copyOf(keys, keys.length);
+ copy.values = Arrays.copyOf(values, values.length);
+ copy.links = Arrays.copyOf(links, links.length);
+ copy.firstIndex = firstIndex;
+ copy.lastIndex = lastIndex;
+ copy.containsNull = containsNull;
+ copy.nullIndex = nullIndex;
+ copy.maxFill = maxFill;
+ copy.mask = mask;
+ copy.size = size;
+ copy.minCapacity = minCapacity;
+ copy.loadFactor = loadFactor;
+ return copy;
+ }
+ finally {
+ unlock();
+ }
}
protected VALUE_TYPE getDefaultReturnValue() {
diff --git a/src/builder/resources/speiger/assets/collections/templates/maps/interfaces/ConcurrentMap.template b/src/builder/resources/speiger/assets/collections/templates/maps/interfaces/ConcurrentMap.template
new file mode 100644
index 00000000..f38524c2
--- /dev/null
+++ b/src/builder/resources/speiger/assets/collections/templates/maps/interfaces/ConcurrentMap.template
@@ -0,0 +1,95 @@
+package speiger.src.collections.PACKAGE.maps.interfaces;
+
+import java.util.concurrent.ConcurrentMap;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+/**
+ * A type specific ConcurrentMap interface that reduces boxing/unboxing.
+ * Since the interface adds nothing new. It is there just for completion sake.
+ * @Type(T)
+ * @ValueType(V)
+ */
+public interface CONCURRENT_MAP KEY_VALUE_GENERIC_TYPE extends ConcurrentMap, MAP KEY_VALUE_GENERIC_TYPE
+{
+ @Override
+ @Primitive
+ public default CLASS_VALUE_TYPE compute(CLASS_TYPE key, BiFunction super CLASS_TYPE, ? super CLASS_VALUE_TYPE, ? extends CLASS_VALUE_TYPE> mappingFunction) {
+ return MAP.super.compute(key, mappingFunction);
+ }
+
+ @Override
+ @Primitive
+ public default CLASS_VALUE_TYPE computeIfAbsent(CLASS_TYPE key, Function super CLASS_TYPE, ? extends CLASS_VALUE_TYPE> mappingFunction) {
+ return MAP.super.computeIfAbsent(key, mappingFunction);
+ }
+
+ @Override
+ @Primitive
+ public default CLASS_VALUE_TYPE computeIfPresent(CLASS_TYPE key, BiFunction super CLASS_TYPE, ? super CLASS_VALUE_TYPE, ? extends CLASS_VALUE_TYPE> mappingFunction) {
+ return MAP.super.computeIfPresent(key, mappingFunction);
+ }
+
+ @Override
+ @Primitive
+ public default void forEach(BiConsumer super CLASS_TYPE, ? super CLASS_VALUE_TYPE> action) {
+ MAP.super.forEach(action);
+ }
+
+ @Override
+ @Primitive
+ public default CLASS_VALUE_TYPE merge(CLASS_TYPE key, CLASS_VALUE_TYPE value, BiFunction super CLASS_VALUE_TYPE, ? super CLASS_VALUE_TYPE, ? extends CLASS_VALUE_TYPE> mappingFunction) {
+ return MAP.super.merge(key, value, mappingFunction);
+ }
+
+#if TYPE_OBJECT && VALUE_OBJECT
+ @Override
+ public CLASS_VALUE_TYPE getOrDefault(Object key, CLASS_VALUE_TYPE defaultValue);
+ @Override
+ public CLASS_VALUE_TYPE putIfAbsent(CLASS_TYPE key, CLASS_VALUE_TYPE value);
+ @Override
+ public boolean remove(Object key, Object value);
+ @Override
+ public boolean replace(CLASS_TYPE key, CLASS_VALUE_TYPE oldValue, CLASS_VALUE_TYPE newValue);
+ @Override
+ public CLASS_VALUE_TYPE replace(CLASS_TYPE key, CLASS_VALUE_TYPE value);
+
+#else
+ @Primitive
+ @Override
+ public default CLASS_VALUE_TYPE getOrDefault(Object key, CLASS_VALUE_TYPE defaultValue) {
+ return MAP.super.getOrDefault(key, defaultValue);
+ }
+
+ @Override
+ @Primitive
+ public default CLASS_VALUE_TYPE putIfAbsent(CLASS_TYPE key, CLASS_VALUE_TYPE value) {
+ return MAP.super.putIfAbsent(key, value);
+ }
+
+ @Override
+ @Deprecated
+ public default boolean remove(Object key, Object value) {
+ return MAP.super.remove(key, value);
+ }
+
+ @Override
+ @Deprecated
+ public default boolean replace(CLASS_TYPE key, CLASS_VALUE_TYPE oldValue, CLASS_VALUE_TYPE newValue) {
+ return MAP.super.replace(key, oldValue, newValue);
+ }
+
+ @Override
+ @Deprecated
+ public default CLASS_VALUE_TYPE replace(CLASS_TYPE key, CLASS_VALUE_TYPE value) {
+ return MAP.super.replace(key, value);
+ }
+
+#endif
+ @Override
+ @Deprecated
+ public default void replaceAll(BiFunction super CLASS_TYPE, ? super CLASS_VALUE_TYPE, ? extends CLASS_VALUE_TYPE> mappingFunction) {
+ MAP.super.replaceAll(mappingFunction);
+ }
+}
\ No newline at end of file
diff --git a/src/builder/resources/speiger/assets/collections/templates/maps/interfaces/Map.template b/src/builder/resources/speiger/assets/collections/templates/maps/interfaces/Map.template
index 3af9b47e..80f96a3e 100644
--- a/src/builder/resources/speiger/assets/collections/templates/maps/interfaces/Map.template
+++ b/src/builder/resources/speiger/assets/collections/templates/maps/interfaces/Map.template
@@ -31,6 +31,7 @@ import speiger.src.collections.PACKAGE.maps.impl.immutable.IMMUTABLE_HASH_MAP;
import speiger.src.collections.PACKAGE.maps.impl.tree.AVL_TREE_MAP;
import speiger.src.collections.PACKAGE.maps.impl.tree.RB_TREE_MAP;
import speiger.src.collections.PACKAGE.maps.impl.misc.ARRAY_MAP;
+import speiger.src.collections.PACKAGE.maps.impl.concurrent.CONCURRENT_HASH_MAP;
#if TYPE_OBJECT
import speiger.src.collections.PACKAGE.maps.impl.misc.ENUM_MAP;
import speiger.src.collections.PACKAGE.maps.impl.misc.LINKED_ENUM_MAP;
@@ -1508,6 +1509,14 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map