diff --git a/README.md b/README.md
index cbb2abe..8d674f0 100644
--- a/README.md
+++ b/README.md
@@ -32,14 +32,14 @@ _Note_: currently the lib contains wrappers not for every primitive map. Feel fr
com.trivago
fastutil-concurrent-wrapper
- 0.2.2
+ 0.2.3
```
#### Gradle
```groovy
-implementation group: 'com.trivago', name: 'fastutil-concurrent-wrapper', version: '0.2.2'
+implementation group: 'com.trivago', name: 'fastutil-concurrent-wrapper', version: '0.2.3'
```
## Usage
@@ -135,3 +135,4 @@ A-Z surname order
- [@mchernyakov](https://github.com/mchernyakov)
- [@erdoganf](https://github.com/erdoganf)
- [@sarveswaran-m](https://github.com/sarveswaran-m)
+- [@p0nkr4t](https://github.com/p0nkr4t)
diff --git a/build.gradle b/build.gradle
index 1c8da32..c6e4010 100644
--- a/build.gradle
+++ b/build.gradle
@@ -16,7 +16,7 @@ allprojects {
}
group 'com.trivago'
-version '0.2.3-SNAPSHOT'
+version '0.2.4-SNAPSHOT'
mavenPublishing {
pom {
@@ -46,6 +46,11 @@ mavenPublishing {
name = "Sarveswaran Meenakshisundaram"
url = "https://github.com/sarveswaran-m"
}
+ developer {
+ id = "p0nkr4t"
+ name = "Ivan Korovin"
+ url = "https://github.com/p0nkr4t"
+ }
}
scm {
url = "https://github.com/trivago/fastutil-concurrent-wrapper"
diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/ConcurrentIntLongMapBuilder.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/ConcurrentIntLongMapBuilder.java
new file mode 100644
index 0000000..470f240
--- /dev/null
+++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/ConcurrentIntLongMapBuilder.java
@@ -0,0 +1,74 @@
+package com.trivago.fastutilconcurrentwrapper;
+
+import com.trivago.fastutilconcurrentwrapper.map.ConcurrentBusyWaitingIntLongMap;
+import com.trivago.fastutilconcurrentwrapper.map.ConcurrentIntLongMap;
+
+public final class ConcurrentIntLongMapBuilder {
+ private MapMode mapMode = MapMode.BLOCKING;
+ private int buckets = 8;
+ private int initialCapacity = 100_000;
+ private float loadFactor = 0.8f;
+ private long defaultValue = IntLongMap.DEFAULT_VALUE;
+
+ private ConcurrentIntLongMapBuilder() {
+
+ }
+
+ public static ConcurrentIntLongMapBuilder newBuilder() {
+ return new ConcurrentIntLongMapBuilder();
+ }
+
+ public ConcurrentIntLongMapBuilder withBuckets(int buckets) {
+ this.buckets = buckets;
+ return this;
+ }
+
+ public ConcurrentIntLongMapBuilder withInitialCapacity(int initialCapacity) {
+ this.initialCapacity = initialCapacity;
+ return this;
+ }
+
+ public ConcurrentIntLongMapBuilder withLoadFactor(float loadFactor) {
+ this.loadFactor = loadFactor;
+ return this;
+ }
+
+ public ConcurrentIntLongMapBuilder withMode(MapMode mapMode) {
+ this.mapMode = mapMode;
+ return this;
+ }
+
+ public ConcurrentIntLongMapBuilder withDefaultValue(long defaultValue) {
+ this.defaultValue = defaultValue;
+ return this;
+ }
+
+ public IntLongMap build() {
+ return mapMode.createMap(this);
+ }
+
+ public enum MapMode {
+ BUSY_WAITING {
+ @Override
+ IntLongMap createMap(ConcurrentIntLongMapBuilder builder) {
+ return new ConcurrentBusyWaitingIntLongMap(
+ builder.buckets,
+ builder.initialCapacity,
+ builder.loadFactor,
+ builder.defaultValue);
+ }
+ },
+ BLOCKING {
+ @Override
+ IntLongMap createMap(ConcurrentIntLongMapBuilder builder) {
+ return new ConcurrentIntLongMap(
+ builder.buckets,
+ builder.initialCapacity,
+ builder.loadFactor,
+ builder.defaultValue);
+ }
+ };
+
+ abstract IntLongMap createMap(ConcurrentIntLongMapBuilder builder);
+ }
+}
diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/IntLongMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/IntLongMap.java
new file mode 100644
index 0000000..08a3ad4
--- /dev/null
+++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/IntLongMap.java
@@ -0,0 +1,28 @@
+package com.trivago.fastutilconcurrentwrapper;
+
+import it.unimi.dsi.fastutil.ints.Int2LongFunction;
+
+import java.util.function.BiFunction;
+
+public interface IntLongMap extends PrimitiveIntKeyMap {
+
+ long DEFAULT_VALUE = 0;
+
+ /**
+ * @param key
+ * @return 0 if the key is not present
+ */
+ long get(int key);
+
+ long put(int key, long value);
+
+ long getDefaultValue();
+
+ long remove(int key);
+
+ boolean remove(int key, long value);
+
+ long computeIfAbsent(int key, Int2LongFunction mappingFunction);
+
+ long computeIfPresent(int key, BiFunction mappingFunction);
+}
diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentBusyWaitingIntLongMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentBusyWaitingIntLongMap.java
new file mode 100644
index 0000000..7bad306
--- /dev/null
+++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentBusyWaitingIntLongMap.java
@@ -0,0 +1,162 @@
+package com.trivago.fastutilconcurrentwrapper.map;
+
+import com.trivago.fastutilconcurrentwrapper.IntLongMap;
+import com.trivago.fastutilconcurrentwrapper.wrapper.PrimitiveFastutilIntLongWrapper;
+import it.unimi.dsi.fastutil.ints.Int2LongFunction;
+
+import java.util.concurrent.locks.Lock;
+import java.util.function.BiFunction;
+
+public class ConcurrentBusyWaitingIntLongMap extends PrimitiveConcurrentMap implements IntLongMap {
+
+ private final IntLongMap[] maps;
+ private final long defaultValue;
+
+ public ConcurrentBusyWaitingIntLongMap(int numBuckets,
+ int initialCapacity,
+ float loadFactor,
+ long defaultValue) {
+ super(numBuckets);
+
+ this.maps = new IntLongMap[numBuckets];
+ this.defaultValue = defaultValue;
+
+ for (int i = 0; i < numBuckets; i++) {
+ maps[i] = new PrimitiveFastutilIntLongWrapper(initialCapacity, loadFactor, defaultValue);
+ }
+ }
+
+ @Override
+ public int size() {
+ return super.size(maps);
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return super.isEmpty(maps);
+ }
+
+ @Override
+ public boolean containsKey(int key) {
+ int bucket = getBucket(key);
+
+ Lock readLock = locks[bucket].readLock();
+
+ while (true) {
+ if (readLock.tryLock()) {
+ try {
+ return maps[bucket].containsKey(key);
+ } finally {
+ readLock.unlock();
+ }
+ }
+ }
+ }
+
+ @Override
+ public long get(int key) {
+ int bucket = getBucket(key);
+
+ Lock readLock = locks[bucket].readLock();
+
+ while (true) {
+ if (readLock.tryLock()) {
+ try {
+ return maps[bucket].get(key);
+ } finally {
+ readLock.unlock();
+ }
+ }
+ }
+ }
+
+ @Override
+ public long put(int key, long value) {
+ int bucket = getBucket(key);
+
+ Lock writeLock = locks[bucket].writeLock();
+
+ while (true) {
+ if (writeLock.tryLock()) {
+ try {
+ return maps[bucket].put(key, value);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+ }
+ }
+
+ @Override
+ public long getDefaultValue() {
+ return defaultValue;
+ }
+
+ @Override
+ public long remove(int key) {
+ int bucket = getBucket(key);
+
+ Lock writeLock = locks[bucket].writeLock();
+
+ while (true) {
+ if (writeLock.tryLock()) {
+ try {
+ return maps[bucket].remove(key);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean remove(int key, long value) {
+ int bucket = getBucket(key);
+
+ Lock writeLock = locks[bucket].writeLock();
+
+ while (true) {
+ if (writeLock.tryLock()) {
+ try {
+ return maps[bucket].remove(key, value);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+ }
+ }
+
+ @Override
+ public long computeIfAbsent(int key, Int2LongFunction mappingFunction) {
+ int bucket = getBucket(key);
+
+ Lock writeLock = locks[bucket].writeLock();
+
+ while (true) {
+ if (writeLock.tryLock()) {
+ try {
+ return maps[bucket].computeIfAbsent(key, mappingFunction);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+ }
+ }
+
+ @Override
+ public long computeIfPresent(int key, BiFunction mappingFunction) {
+ int bucket = getBucket(key);
+
+ Lock writeLock = locks[bucket].writeLock();
+
+ while (true) {
+ if (writeLock.tryLock()) {
+ try {
+ return maps[bucket].computeIfPresent(key, mappingFunction);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentIntLongMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentIntLongMap.java
new file mode 100644
index 0000000..2844d35
--- /dev/null
+++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentIntLongMap.java
@@ -0,0 +1,142 @@
+package com.trivago.fastutilconcurrentwrapper.map;
+
+import com.trivago.fastutilconcurrentwrapper.IntLongMap;
+import com.trivago.fastutilconcurrentwrapper.wrapper.PrimitiveFastutilIntLongWrapper;
+import it.unimi.dsi.fastutil.ints.Int2LongFunction;
+
+import java.util.concurrent.locks.Lock;
+import java.util.function.BiFunction;
+
+public class ConcurrentIntLongMap extends PrimitiveConcurrentMap implements IntLongMap {
+
+ private final IntLongMap[] maps;
+ private final long defaultValue;
+
+ public ConcurrentIntLongMap(int numBuckets,
+ int initialCapacity,
+ float loadFactor,
+ long defaultValue) {
+ super(numBuckets);
+
+ this.maps = new IntLongMap[numBuckets];
+ this.defaultValue = defaultValue;
+
+ for (int i = 0; i < numBuckets; i++) {
+ maps[i] = new PrimitiveFastutilIntLongWrapper(initialCapacity, loadFactor, defaultValue);
+ }
+ }
+
+ @Override
+ public int size() {
+ return super.size(maps);
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return super.isEmpty(maps);
+ }
+
+ @Override
+ public boolean containsKey(int key) {
+ int bucket = getBucket(key);
+
+ Lock readLock = locks[bucket].readLock();
+ readLock.lock();
+ try {
+ return maps[bucket].containsKey(key);
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ @Override
+ public long get(int l) {
+ int bucket = getBucket(l);
+
+ long result;
+
+ Lock readLock = locks[bucket].readLock();
+ readLock.lock();
+ try {
+ result = maps[bucket].get(l);
+ } finally {
+ readLock.unlock();
+ }
+
+ return result;
+ }
+
+ @Override
+ public long put(int key, long value) {
+ int bucket = getBucket(key);
+
+ long result;
+
+ Lock writeLock = locks[bucket].writeLock();
+ writeLock.lock();
+ try {
+ result = maps[bucket].put(key, value);
+ } finally {
+ writeLock.unlock();
+ }
+
+ return result;
+ }
+
+ @Override
+ public long getDefaultValue() {
+ return defaultValue;
+ }
+
+ @Override
+ public long remove(int key) {
+ int bucket = getBucket(key);
+
+ Lock writeLock = locks[bucket].writeLock();
+ writeLock.lock();
+ try {
+ return maps[bucket].remove(key);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ @Override
+ public boolean remove(int key, long value) {
+ int bucket = getBucket(key);
+
+ Lock writeLock = locks[bucket].writeLock();
+ writeLock.lock();
+ try {
+ return maps[bucket].remove(key, value);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ @Override
+ public long computeIfAbsent(int key, Int2LongFunction mappingFunction) {
+ int bucket = getBucket(key);
+
+ Lock writeLock = locks[bucket].writeLock();
+ writeLock.lock();
+ try {
+ return maps[bucket].computeIfAbsent(key, mappingFunction);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ @Override
+ public long computeIfPresent(int key, BiFunction mappingFunction) {
+ int bucket = getBucket(key);
+
+ Lock writeLock = locks[bucket].writeLock();
+ writeLock.lock();
+ try {
+ return maps[bucket].computeIfPresent(key, mappingFunction);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+}
diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/wrapper/PrimitiveFastutilIntLongWrapper.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/wrapper/PrimitiveFastutilIntLongWrapper.java
new file mode 100644
index 0000000..1495d39
--- /dev/null
+++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/wrapper/PrimitiveFastutilIntLongWrapper.java
@@ -0,0 +1,71 @@
+package com.trivago.fastutilconcurrentwrapper.wrapper;
+
+import com.trivago.fastutilconcurrentwrapper.IntLongMap;
+import it.unimi.dsi.fastutil.ints.Int2LongFunction;
+import it.unimi.dsi.fastutil.ints.Int2LongOpenHashMap;
+
+import java.util.function.BiFunction;
+
+public class PrimitiveFastutilIntLongWrapper implements IntLongMap {
+ private final Int2LongOpenHashMap map;
+ private final long defaultValue;
+
+ public PrimitiveFastutilIntLongWrapper(int initialCapacity, float loadFactor) {
+ this(initialCapacity, loadFactor, IntLongMap.DEFAULT_VALUE);
+ }
+
+ public PrimitiveFastutilIntLongWrapper(int initialCapacity, float loadFactor, long defaultValue) {
+ this.defaultValue = defaultValue;
+ this.map = new Int2LongOpenHashMap(initialCapacity, loadFactor);
+ }
+
+ @Override
+ public long get(int key) {
+ return map.getOrDefault(key, defaultValue);
+ }
+
+ @Override
+ public long put(int key, long value) {
+ return map.put(key, value);
+ }
+
+ @Override
+ public long getDefaultValue() {
+ return defaultValue;
+ }
+
+ @Override
+ public long remove(int key) {
+ return map.remove(key);
+ }
+
+ @Override
+ public boolean remove(int key, long value) {
+ return map.remove(key, value);
+ }
+
+ @Override
+ public int size() {
+ return map.size();
+ }
+
+ @Override
+ public boolean containsKey(int key) {
+ return map.containsKey(key);
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return map.isEmpty();
+ }
+
+ @Override
+ public long computeIfAbsent(int key, Int2LongFunction mappingFunction) {
+ return map.computeIfAbsent(key, mappingFunction);
+ }
+
+ @Override
+ public long computeIfPresent(int key, BiFunction mappingFunction) {
+ return map.computeIfPresent(key, mappingFunction);
+ }
+}
diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentIntLongMapBuilderTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentIntLongMapBuilderTest.java
new file mode 100644
index 0000000..80b306a
--- /dev/null
+++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentIntLongMapBuilderTest.java
@@ -0,0 +1,49 @@
+package com.trivago.fastutilconcurrentwrapper;
+
+import com.trivago.fastutilconcurrentwrapper.map.ConcurrentBusyWaitingIntLongMap;
+import com.trivago.fastutilconcurrentwrapper.map.ConcurrentIntLongMap;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class ConcurrentIntLongMapBuilderTest {
+ private final long DEFAULT_VALUE = -1L;
+
+ @Test
+ public void simpleBuilderTest() {
+ ConcurrentIntLongMapBuilder b = ConcurrentIntLongMapBuilder.newBuilder()
+ .withBuckets(2)
+ .withDefaultValue(DEFAULT_VALUE)
+ .withInitialCapacity(100)
+ .withMode(ConcurrentIntLongMapBuilder.MapMode.BUSY_WAITING)
+ .withLoadFactor(0.9f);
+
+ IntLongMap map = b.build();
+
+ map.put(1, 10L);
+ long v = map.get(1);
+
+ assertInstanceOf(ConcurrentBusyWaitingIntLongMap.class, map);
+ assertEquals(10L, v);
+ assertEquals(map.get(2), map.getDefaultValue());
+ }
+
+ @Test
+ public void buildsBlockingMap() {
+ ConcurrentIntLongMapBuilder b = ConcurrentIntLongMapBuilder.newBuilder()
+ .withBuckets(2)
+ .withDefaultValue(DEFAULT_VALUE)
+ .withInitialCapacity(100)
+ .withMode(ConcurrentIntLongMapBuilder.MapMode.BLOCKING)
+ .withLoadFactor(0.9f);
+
+ IntLongMap map = b.build();
+
+ map.put(1, 10L);
+ long v = map.get(1);
+
+ assertInstanceOf(ConcurrentIntLongMap.class, map);
+ assertEquals(10L, v);
+ assertEquals(map.get(2), map.getDefaultValue());
+ }
+}
diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/intlong/AbstractIntLongMapTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/intlong/AbstractIntLongMapTest.java
new file mode 100644
index 0000000..7d5eb35
--- /dev/null
+++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/intlong/AbstractIntLongMapTest.java
@@ -0,0 +1,206 @@
+package com.trivago.fastutilconcurrentwrapper.intlong;
+
+import com.trivago.fastutilconcurrentwrapper.AbstractMapTest;
+import com.trivago.fastutilconcurrentwrapper.IntLongMap;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+abstract class AbstractIntLongMapTest extends AbstractMapTest {
+ private IntLongMap map;
+ // Keep the default value to easily verify that this value is returned.
+ protected long defaultValue;
+ // Some methods return the default value of the underlying Fastutil implementation.
+ private static final long FASTUTIL_DEFAULT_VALUE = 0L;
+
+ abstract IntLongMap createMap();
+
+ @BeforeEach
+ void initializeMap() {
+ defaultValue = nextLong();
+ map = createMap();
+ }
+
+ @Test
+ protected void containsKeyReturnsFalseIfMapIsEmpty() {
+ final int key = nextInt();
+
+ final boolean contains = map.containsKey(key);
+
+ assertFalse(contains);
+ }
+
+ @Test
+ protected void containsKeyReturnsTrueIfKeyExists() {
+ int key = nextInt();
+ long value = nextLong();
+ map.put(key, value);
+
+ final boolean contains = map.containsKey(key);
+
+ assertTrue(contains);
+ }
+
+ @Test
+ protected void containsKeyReturnsFalseIfKeyWasRemoved() {
+ int key = nextInt();
+ long value = nextLong();
+ map.put(key, value);
+ map.remove(key);
+
+ final boolean contains = map.containsKey(key);
+
+ assertFalse(contains);
+ }
+
+ @Test
+ protected void mapIsEmptyWhenNothingWasInserted() {
+ final boolean empty = map.isEmpty();
+
+ assertTrue(empty);
+ }
+
+ @Test
+ protected void mapIsEmptyWhenAllKeysAreDeleted() {
+ int entryCount = (Math.abs(nextInt()) % 100) + 1;
+ long value = nextLong();
+
+ for (int key = 1; key <= entryCount; key++) {
+ map.put(key, value);
+ }
+ for (int key = 1; key <= entryCount; key++) {
+ map.remove(key);
+ }
+
+ final boolean empty = map.isEmpty();
+
+ assertTrue(empty);
+ }
+
+ @Test
+ protected void sizeIsCorrect() {
+ int entries = (Math.abs(nextInt()) % 50) + 1;
+ long value = nextLong();
+
+ for (int key = 1; key <= entries; key++) {
+ map.put(key, value);
+ }
+
+ final int size = map.size();
+
+ assertEquals(entries, size);
+ }
+
+ @Test
+ protected void gettingExistingValueReturnsCorrectValue() {
+ int key = nextInt();
+ long value = nextLong();
+ map.put(key, value);
+ final long returnedValue = map.get(key);
+
+ assertEquals(value, returnedValue);
+ }
+
+ @Test
+ protected void gettingNonExistingValueReturnsCorrectValue() {
+ int key = nextInt();
+ final long returnedValue = map.get(key);
+
+ assertEquals(defaultValue, returnedValue);
+ }
+
+ @Test
+ protected void removingNonExistingKeyReturnsDefaultValue() {
+ int key = nextInt();
+ final long removedValue = map.remove(key);
+
+ assertEquals(FASTUTIL_DEFAULT_VALUE, removedValue);
+ }
+
+ @Test
+ protected void removingExistingKeyReturnsPreviousValue() {
+ int key = nextInt();
+ long value = nextLong();
+ map.put(key, value);
+ final long removedValue = map.remove(key);
+
+ assertEquals(value, removedValue);
+ }
+
+ @Test
+ protected void removingWithValueWhenKeyDoesNotExistReturnsFalse() {
+ int key = nextInt();
+ long value = nextLong();
+ final boolean result = map.remove(key, value);
+
+ assertFalse(result);
+ }
+
+ @Test
+ protected void removingWithValueWhenValueIsDifferentReturnsFalse() {
+ int key = nextInt();
+ long value = nextLong();
+ map.put(key, value);
+ final boolean result = map.remove(key, value - 1);
+
+ assertFalse(result);
+ }
+
+ @Test
+ protected void removingWithValueWhenValueIsSameReturnsTrue() {
+ int key = nextInt();
+ long value = nextLong();
+ map.put(key, value);
+ final boolean result = map.remove(key, value);
+
+ assertTrue(result);
+ }
+
+ @Test
+ protected void puttingValueIfAbsentReturnsSameValue() {
+ int key = nextInt();
+ long value = nextLong();
+ map.computeIfAbsent(key, l -> value);
+
+ long result = map.get(key);
+
+ assertEquals(result, value);
+ }
+
+ @Test
+ protected void checkingValueIfNotAbsentReturnsSameValue() {
+ int key = nextInt();
+ long value = nextLong();
+ map.put(key, value);
+ long returned = map.computeIfAbsent(key, l -> value);
+
+ long result = map.get(key);
+
+ assertEquals(result, value);
+ assertEquals(value, returned);
+ }
+
+ @Test
+ protected void replacingValueIfPresentReturnsNewValue() {
+ int key = nextInt();
+ long value = nextLong();
+ map.put(key, value);
+
+ map.computeIfPresent(key, Long::sum); // key + old value
+
+ long result = map.get(key);
+
+ assertEquals(result, key + value);
+ }
+
+ @Test
+ protected void checkingValueIfNotPresentReturnsDefaultValue() {
+ int key = nextInt();
+ map.computeIfPresent(key, Long::sum);
+
+ long result = map.get(key);
+
+ assertEquals(result, map.getDefaultValue());
+ }
+}
diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/intlong/ConcurrentBusyWaitingIntLongMapTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/intlong/ConcurrentBusyWaitingIntLongMapTest.java
new file mode 100644
index 0000000..390a6b5
--- /dev/null
+++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/intlong/ConcurrentBusyWaitingIntLongMapTest.java
@@ -0,0 +1,12 @@
+package com.trivago.fastutilconcurrentwrapper.intlong;
+
+import com.trivago.fastutilconcurrentwrapper.IntLongMap;
+import com.trivago.fastutilconcurrentwrapper.map.ConcurrentBusyWaitingIntLongMap;
+
+public class ConcurrentBusyWaitingIntLongMapTest extends AbstractIntLongMapTest {
+
+ @Override
+ IntLongMap createMap() {
+ return new ConcurrentBusyWaitingIntLongMap(16, 16, 0.9F, defaultValue);
+ }
+}
diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/intlong/ConcurrentIntLongMapTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/intlong/ConcurrentIntLongMapTest.java
new file mode 100644
index 0000000..aebc8c1
--- /dev/null
+++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/intlong/ConcurrentIntLongMapTest.java
@@ -0,0 +1,12 @@
+package com.trivago.fastutilconcurrentwrapper.intlong;
+
+import com.trivago.fastutilconcurrentwrapper.IntLongMap;
+import com.trivago.fastutilconcurrentwrapper.map.ConcurrentIntLongMap;
+
+public class ConcurrentIntLongMapTest extends AbstractIntLongMapTest {
+
+ @Override
+ IntLongMap createMap() {
+ return new ConcurrentIntLongMap(16, 16, 0.9F, defaultValue);
+ }
+}
diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/intlong/PrimitiveFastutilIntLongWrapperTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/intlong/PrimitiveFastutilIntLongWrapperTest.java
new file mode 100644
index 0000000..8814b1f
--- /dev/null
+++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/intlong/PrimitiveFastutilIntLongWrapperTest.java
@@ -0,0 +1,12 @@
+package com.trivago.fastutilconcurrentwrapper.intlong;
+
+import com.trivago.fastutilconcurrentwrapper.IntLongMap;
+import com.trivago.fastutilconcurrentwrapper.wrapper.PrimitiveFastutilIntLongWrapper;
+
+public class PrimitiveFastutilIntLongWrapperTest extends AbstractIntLongMapTest {
+
+ @Override
+ IntLongMap createMap() {
+ return new PrimitiveFastutilIntLongWrapper(5, 0.9F, defaultValue);
+ }
+}