diff --git a/README.md b/README.md index cbb2abe..05075b5 100644 --- a/README.md +++ b/README.md @@ -85,48 +85,105 @@ For running JMH tests just execute: ./gradlew jmh ``` -Results for `FastutilWrapper BusyWaiting mode` vs `FastutilWrapper Default mode` vs [java.util wrappers](https://docs.oracle.com/javase/tutorial/collections/implementations/wrapper.html) +Results for `FastutilWrapper BusyWaiting mode` vs `FastutilWrapper Default mode` vs [java.util wrappers](https://docs.oracle.com/javase/tutorial/collections/implementations/wrapper.html) vs [java.util.concurrent](https://docs.oracle.com/javase/tutorial/collections/implementations/map.html) + +#### LongLongMap + +Throughput (more is better) + +```shell +Benchmark Mode Cnt Score Error Units + +FastutilWrapperBusyWaitingLongLongBenchmark.testRandomAllOpsThroughput thrpt 15 14890349.957 ± 2041249.822 ops/s +FastutilWrapperBusyWaitingLongLongBenchmark.testRandomGetThroughput thrpt 15 25449527.963 ± 2600729.022 ops/s +FastutilWrapperBusyWaitingLongLongBenchmark.testRandomPutThroughput thrpt 14 11351650.286 ± 3324513.684 ops/s + +FastutilWrapperDefaultLongLongBenchmark.testRandomAllOpsThroughput thrpt 15 9241548.296 ± 1501812.910 ops/s +FastutilWrapperDefaultLongLongBenchmark.testRandomGetThroughput thrpt 15 23205312.991 ± 2243533.089 ops/s +FastutilWrapperDefaultLongLongBenchmark.testRandomPutThroughput thrpt 15 8705378.516 ± 2193254.025 ops/s + +JavaUtilWrapperLongLongBenchmark.testRandomAllOpsThroughput thrpt 15 4807759.211 ± 235212.245 ops/s +JavaUtilWrapperLongLongBenchmark.testRandomGetThroughput thrpt 15 10518803.436 ± 343489.210 ops/s +JavaUtilWrapperLongLongBenchmark.testRandomPutThroughput thrpt 15 3893033.361 ± 1091839.389 ops/s + +JavaConcurrentLongLongBenchmark.testRandomAllOpsThroughput thrpt 15 8338702.617 ± 2339627.650 ops/s +JavaConcurrentLongLongBenchmark.testRandomGetThroughput thrpt 15 115734084.910 ± 1021773.718 ops/s +JavaConcurrentLongLongBenchmark.testRandomPutThroughput thrpt 15 2120419.422 ± 1616120.572 ops/s +``` +AverageTime per ops (less is better) + +```shell +Benchmark Mode Cnt Score Error Units + +FastutilWrapperBusyWaitingLongLongBenchmark.testRandomAllOpsAvgTime avgt 15 271.732 ± 23.990 ns/op +FastutilWrapperBusyWaitingLongLongBenchmark.testRandomGetAvgTime avgt 15 152.339 ± 20.281 ns/op +FastutilWrapperBusyWaitingLongLongBenchmark.testRandomPutAvgTime avgt 15 376.696 ± 104.558 ns/op + +FastutilWrapperDefaultLongLongBenchmark.testRandomAllOpsAvgTime avgt 15 450.080 ± 74.515 ns/op +FastutilWrapperDefaultLongLongBenchmark.testRandomGetAvgTime avgt 15 158.247 ± 12.916 ns/op +FastutilWrapperDefaultLongLongBenchmark.testRandomPutAvgTime avgt 15 480.561 ± 142.326 ns/op + +JavaUtilWrapperLongLongBenchmark.testRandomAllOpsAvgTime avgt 15 848.636 ± 37.767 ns/op +JavaUtilWrapperLongLongBenchmark.testRandomGetAvgTime avgt 15 380.703 ± 18.391 ns/op +JavaUtilWrapperLongLongBenchmark.testRandomPutAvgTime avgt 15 1083.204 ± 323.376 ns/op + +JavaConcurrentLongLongBenchmark.testRandomAllOpsAvgTime avgt 15 511.132 ± 166.567 ns/op +JavaConcurrentLongLongBenchmark.testRandomGetAvgTime avgt 15 34.583 ± 0.301 ns/op +JavaConcurrentLongLongBenchmark.testRandomPutAvgTime avgt 15 16723.754 ± 24368.274 ns/op +``` + +#### ObjectLongMap Throughput (more is better) ```shell -Benchmark Mode Cnt Score Error Units +Benchmark Mode Cnt Score Error Units + +FastutilWrapperBusyWaitingObjectLongBenchmark.testRandomAllOpsThroughput thrpt 15 12560651.390 ± 2610919.005 ops/s +FastutilWrapperBusyWaitingObjectLongBenchmark.testRandomGetThroughput thrpt 15 26366394.724 ± 2433787.656 ops/s +FastutilWrapperBusyWaitingObjectLongBenchmark.testRandomPutThroughput thrpt 15 5633586.398 ± 2592634.909 ops/s -FastutilWrapperBusyWaitingBenchmark.testRandomAllOpsThroughput thrpt 15 14517457,055 ? 795637,784 ops/s -FastutilWrapperBusyWaitingBenchmark.testRandomGetThroughput thrpt 15 16610181,320 ? 1456776,589 ops/s -FastutilWrapperBusyWaitingBenchmark.testRandomPutThroughput thrpt 13 11706178,916 ? 2547333,524 ops/s +FastutilWrapperDefaultObjectLongBenchmark.testRandomAllOpsThroughput thrpt 15 8107579.700 ± 1356806.057 ops/s +FastutilWrapperDefaultObjectLongBenchmark.testRandomGetThroughput thrpt 15 22899340.190 ± 2745129.956 ops/s +FastutilWrapperDefaultObjectLongBenchmark.testRandomPutThroughput thrpt 15 5115575.519 ± 1510259.367 ops/s -FastutilWrapperDefaultBenchmark.testRandomAllOpsThroughput thrpt 15 7385357,514 ? 1127356,032 ops/s -FastutilWrapperDefaultBenchmark.testRandomGetThroughput thrpt 15 16190621,923 ? 1836415,022 ops/s -FastutilWrapperDefaultBenchmark.testRandomPutThroughput thrpt 15 8945369,395 ? 1225460,217 ops/s +JavaUtilWrapperObjectLongBenchmark.testRandomAllOpsThroughput thrpt 15 5146475.879 ± 876528.313 ops/s +JavaUtilWrapperObjectLongBenchmark.testRandomGetThroughput thrpt 15 15354340.310 ± 413172.576 ops/s +JavaUtilWrapperObjectLongBenchmark.testRandomPutThroughput thrpt 15 3349970.826 ± 466818.411 ops/s -JavaUtilWrapperBenchmark.testRandomAllOpsThroughput thrpt 15 4921201,916 ? 410471,239 ops/s -JavaUtilWrapperBenchmark.testRandomGetThroughput thrpt 15 7827123,690 ? 557193,670 ops/s -JavaUtilWrapperBenchmark.testRandomPutThroughput thrpt 15 4832517,371 ? 1122344,647 ops/s +JavaConcurrentObjectLongBenchmark.testRandomAllOpsThroughput thrpt 15 9802597.556 ± 845121.891 ops/s +JavaConcurrentObjectLongBenchmark.testRandomGetThroughput thrpt 15 144324735.489 ± 3072330.160 ops/s +JavaConcurrentObjectLongBenchmark.testRandomPutThroughput thrpt 15 2717410.407 ± 1995361.332 ops/s ``` AverageTime per ops (less is better) ```shell -Benchmark Mode Cnt Score Error Units +Benchmark Mode Cnt Score Error Units -FastutilWrapperBusyWaitingBenchmark.testRandomAllOpsAvgTime avgt 15 268,790 ? 22,526 ns/op -FastutilWrapperBusyWaitingBenchmark.testRandomGetAvgTime avgt 15 231,552 ? 16,116 ns/op -FastutilWrapperBusyWaitingBenchmark.testRandomPutAvgTime avgt 10 292,246 ? 49,757 ns/op +FastutilWrapperBusyWaitingObjectLongBenchmark.testRandomAllOpsAvgTime avgt 15 339.809 ± 80.612 ns/op +FastutilWrapperBusyWaitingObjectLongBenchmark.testRandomGetAvgTime avgt 15 193.411 ± 26.775 ns/op +FastutilWrapperBusyWaitingObjectLongBenchmark.testRandomPutAvgTime avgt 15 951.206 ± 617.310 ns/op -FastutilWrapperDefaultBenchmark.testRandomAllOpsAvgTime avgt 15 467,381 ? 9,790 ns/op -FastutilWrapperDefaultBenchmark.testRandomGetAvgTime avgt 15 237,683 ? 14,167 ns/op -FastutilWrapperDefaultBenchmark.testRandomPutAvgTime avgt 15 427,441 ? 25,116 ns/op +FastutilWrapperDefaultObjectLongBenchmark.testRandomAllOpsAvgTime avgt 15 496.373 ± 70.106 ns/op +FastutilWrapperDefaultObjectLongBenchmark.testRandomGetAvgTime avgt 15 179.065 ± 18.389 ns/op +FastutilWrapperDefaultObjectLongBenchmark.testRandomPutAvgTime avgt 15 831.579 ± 268.410 ns/op -JavaUtilWrapperBenchmark.testRandomAllOpsAvgTime avgt 15 781,869 ? 191,081 ns/op -JavaUtilWrapperBenchmark.testRandomGetAvgTime avgt 15 470,869 ? 33,198 ns/op -JavaUtilWrapperBenchmark.testRandomPutAvgTime avgt 15 964,613 ? 422,648 ns/op +JavaUtilWrapperObjectLongBenchmark.testRandomAllOpsAvgTime avgt 15 785.415 ± 153.079 ns/op +JavaUtilWrapperObjectLongBenchmark.testRandomGetAvgTime avgt 15 251.149 ± 10.494 ns/op +JavaUtilWrapperObjectLongBenchmark.testRandomPutAvgTime avgt 15 1211.072 ± 152.786 ns/op + +JavaConcurrentObjectLongBenchmark.testRandomAllOpsAvgTime avgt 15 418.897 ± 35.770 ns/op +JavaConcurrentObjectLongBenchmark.testRandomGetAvgTime avgt 15 27.664 ± 0.125 ns/op +JavaConcurrentObjectLongBenchmark.testRandomPutAvgTime avgt 15 7039.788 ± 10679.090 ns/op ``` +#### Info + The machine ```shell -MacBook Pro (15-inch, 2019) -Processor 2,6 GHz 6-Core Intel Core i7 -Memory 16 GB 2400 MHz DDR4 +OS Kubuntu 24.10 +Processor 3,4 GHz 16-Core AMD Ryzen 9 5950X +Memory 64 GB 3600 MHz DDR4 ``` ## Maintainers diff --git a/build.gradle b/build.gradle index 1c8da32..8fac76a 100644 --- a/build.gradle +++ b/build.gradle @@ -55,8 +55,8 @@ mavenPublishing { } } -sourceCompatibility = 11 -targetCompatibility = 11 +sourceCompatibility = 14 +targetCompatibility = 14 sourceSets { jmh { diff --git a/src/jmh/java/com/trivago/kangaroo/AbstractBenchHelper.java b/src/jmh/java/com/trivago/kangaroo/long2long/AbstractLongLongBenchHelper.java similarity index 54% rename from src/jmh/java/com/trivago/kangaroo/AbstractBenchHelper.java rename to src/jmh/java/com/trivago/kangaroo/long2long/AbstractLongLongBenchHelper.java index f44b21d..0053bfd 100644 --- a/src/jmh/java/com/trivago/kangaroo/AbstractBenchHelper.java +++ b/src/jmh/java/com/trivago/kangaroo/long2long/AbstractLongLongBenchHelper.java @@ -1,31 +1,25 @@ -package com.trivago.kangaroo; +package com.trivago.kangaroo.long2long; -import com.trivago.fastutilconcurrentwrapper.ConcurrentLongLongMapBuilder; -import com.trivago.fastutilconcurrentwrapper.LongLongMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.ConcurrentLongLongMapBuilder; +import com.trivago.fastutilconcurrentwrapper.ConcurrentMapBuilder; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongLongMap; +import com.trivago.kangaroo.AbstractCommonBenchHelper; import java.util.concurrent.ThreadLocalRandom; -public abstract class AbstractBenchHelper extends AbstractCommonBenchHelper { +public abstract class AbstractLongLongBenchHelper extends AbstractCommonBenchHelper { protected static final int NUM_VALUES = 1_000_000; protected LongLongMap map; - public void initAndLoadData(ConcurrentLongLongMapBuilder.MapMode mode) { - if (mode.equals(ConcurrentLongLongMapBuilder.MapMode.BUSY_WAITING)) { - map = ConcurrentLongLongMapBuilder.newBuilder() - .withBuckets(16) - .withInitialCapacity(NUM_VALUES) - .withMode(ConcurrentLongLongMapBuilder.MapMode.BUSY_WAITING) - .withLoadFactor(0.8f) - .build(); - } else { - map = ConcurrentLongLongMapBuilder.newBuilder() - .withBuckets(16) - .withInitialCapacity(NUM_VALUES) - .withLoadFactor(0.8f) - .build(); - } + public void initAndLoadData(ConcurrentMapBuilder.MapMode mode) { + map = ConcurrentLongLongMapBuilder.newBuilder() + .withBuckets(16) + .withInitialCapacity(NUM_VALUES) + .withMode(mode) + .withLoadFactor(0.8f) + .build(); for (int i = 0; i < NUM_VALUES; i++) { long key = ThreadLocalRandom.current().nextLong(); diff --git a/src/jmh/java/com/trivago/kangaroo/FastutilWrapperDefaultBenchmark.java b/src/jmh/java/com/trivago/kangaroo/long2long/FastutilWrapperBusyWaitingLongLongBenchmark.java similarity index 60% rename from src/jmh/java/com/trivago/kangaroo/FastutilWrapperDefaultBenchmark.java rename to src/jmh/java/com/trivago/kangaroo/long2long/FastutilWrapperBusyWaitingLongLongBenchmark.java index 34e3ce6..5129ba9 100644 --- a/src/jmh/java/com/trivago/kangaroo/FastutilWrapperDefaultBenchmark.java +++ b/src/jmh/java/com/trivago/kangaroo/long2long/FastutilWrapperBusyWaitingLongLongBenchmark.java @@ -1,6 +1,6 @@ -package com.trivago.kangaroo; +package com.trivago.kangaroo.long2long; -import com.trivago.fastutilconcurrentwrapper.ConcurrentLongLongMapBuilder; +import com.trivago.fastutilconcurrentwrapper.ConcurrentMapBuilder; import org.openjdk.jmh.annotations.Level; import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Scope; @@ -11,10 +11,10 @@ @State(Scope.Benchmark) @Warmup(iterations = 3, time = 1) @Measurement(iterations = 3, time = 2) -public class FastutilWrapperDefaultBenchmark extends AbstractBenchHelper { +public class FastutilWrapperBusyWaitingLongLongBenchmark extends AbstractLongLongBenchHelper { @Setup(Level.Trial) public void loadData() { - super.initAndLoadData(ConcurrentLongLongMapBuilder.MapMode.BLOCKING); + super.initAndLoadData(ConcurrentMapBuilder.MapMode.BUSY_WAITING); } } diff --git a/src/jmh/java/com/trivago/kangaroo/FastutilWrapperBusyWaitingBenchmark.java b/src/jmh/java/com/trivago/kangaroo/long2long/FastutilWrapperDefaultLongLongBenchmark.java similarity index 61% rename from src/jmh/java/com/trivago/kangaroo/FastutilWrapperBusyWaitingBenchmark.java rename to src/jmh/java/com/trivago/kangaroo/long2long/FastutilWrapperDefaultLongLongBenchmark.java index aafb2e2..4a1ed5f 100644 --- a/src/jmh/java/com/trivago/kangaroo/FastutilWrapperBusyWaitingBenchmark.java +++ b/src/jmh/java/com/trivago/kangaroo/long2long/FastutilWrapperDefaultLongLongBenchmark.java @@ -1,6 +1,6 @@ -package com.trivago.kangaroo; +package com.trivago.kangaroo.long2long; -import com.trivago.fastutilconcurrentwrapper.ConcurrentLongLongMapBuilder; +import com.trivago.fastutilconcurrentwrapper.ConcurrentMapBuilder; import org.openjdk.jmh.annotations.Level; import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Scope; @@ -11,10 +11,10 @@ @State(Scope.Benchmark) @Warmup(iterations = 3, time = 1) @Measurement(iterations = 3, time = 2) -public class FastutilWrapperBusyWaitingBenchmark extends AbstractBenchHelper { +public class FastutilWrapperDefaultLongLongBenchmark extends AbstractLongLongBenchHelper { @Setup(Level.Trial) public void loadData() { - super.initAndLoadData(ConcurrentLongLongMapBuilder.MapMode.BUSY_WAITING); + super.initAndLoadData(ConcurrentMapBuilder.MapMode.BLOCKING); } } diff --git a/src/jmh/java/com/trivago/kangaroo/long2long/JavaConcurrentLongLongBenchmark.java b/src/jmh/java/com/trivago/kangaroo/long2long/JavaConcurrentLongLongBenchmark.java new file mode 100644 index 0000000..0be4a05 --- /dev/null +++ b/src/jmh/java/com/trivago/kangaroo/long2long/JavaConcurrentLongLongBenchmark.java @@ -0,0 +1,54 @@ +package com.trivago.kangaroo.long2long; + +import com.trivago.kangaroo.AbstractCommonBenchHelper; +import org.openjdk.jmh.annotations.*; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ThreadLocalRandom; + +@State(Scope.Benchmark) +@Warmup(iterations = 3, time = 1) +@Measurement(iterations = 3, time = 2) +public class JavaConcurrentLongLongBenchmark extends AbstractCommonBenchHelper { + + Map map; + + @Setup(Level.Trial) + public void loadData() { + map = new ConcurrentHashMap<>(AbstractLongLongBenchHelper.NUM_VALUES, 0.8f); + for (int i = 0; i < AbstractLongLongBenchHelper.NUM_VALUES; i++) { + long key = ThreadLocalRandom.current().nextLong(); + long value = ThreadLocalRandom.current().nextLong(); + map.put(key, value); + } + } + + public void testGet() { + long key = ThreadLocalRandom.current().nextLong(); + map.get(key); + } + + public void testPut() { + long key = ThreadLocalRandom.current().nextLong(); + long value = ThreadLocalRandom.current().nextLong(); + map.put(key, value); + } + + public void testAllOps() { + int op = ThreadLocalRandom.current().nextInt(3); + long key = ThreadLocalRandom.current().nextLong(); + switch (op) { + case 1: + long value = ThreadLocalRandom.current().nextLong(); + map.put(key, value); + break; + case 2: + map.remove(key); + break; + default: + map.get(key); + break; + } + } +} diff --git a/src/jmh/java/com/trivago/kangaroo/JavaUtilWrapperBenchmark.java b/src/jmh/java/com/trivago/kangaroo/long2long/JavaUtilWrapperLongLongBenchmark.java similarity index 85% rename from src/jmh/java/com/trivago/kangaroo/JavaUtilWrapperBenchmark.java rename to src/jmh/java/com/trivago/kangaroo/long2long/JavaUtilWrapperLongLongBenchmark.java index 695a6b8..858f1cf 100644 --- a/src/jmh/java/com/trivago/kangaroo/JavaUtilWrapperBenchmark.java +++ b/src/jmh/java/com/trivago/kangaroo/long2long/JavaUtilWrapperLongLongBenchmark.java @@ -1,5 +1,6 @@ -package com.trivago.kangaroo; +package com.trivago.kangaroo.long2long; +import com.trivago.kangaroo.AbstractCommonBenchHelper; import it.unimi.dsi.fastutil.longs.Long2LongOpenHashMap; import org.openjdk.jmh.annotations.Level; import org.openjdk.jmh.annotations.Measurement; @@ -15,14 +16,14 @@ @State(Scope.Benchmark) @Warmup(iterations = 3, time = 1) @Measurement(iterations = 3, time = 2) -public class JavaUtilWrapperBenchmark extends AbstractCommonBenchHelper { +public class JavaUtilWrapperLongLongBenchmark extends AbstractCommonBenchHelper { Map map; @Setup(Level.Trial) public void loadData() { - Long2LongOpenHashMap m = new Long2LongOpenHashMap(AbstractBenchHelper.NUM_VALUES, 0.8f); - for (int i = 0; i < AbstractBenchHelper.NUM_VALUES; i++) { + Long2LongOpenHashMap m = new Long2LongOpenHashMap(AbstractLongLongBenchHelper.NUM_VALUES, 0.8f); + for (int i = 0; i < AbstractLongLongBenchHelper.NUM_VALUES; i++) { long key = ThreadLocalRandom.current().nextLong(); long value = ThreadLocalRandom.current().nextLong(); m.put(key, value); diff --git a/src/jmh/java/com/trivago/kangaroo/object2long/AbstractObjectLongBenchHelper.java b/src/jmh/java/com/trivago/kangaroo/object2long/AbstractObjectLongBenchHelper.java new file mode 100644 index 0000000..766828f --- /dev/null +++ b/src/jmh/java/com/trivago/kangaroo/object2long/AbstractObjectLongBenchHelper.java @@ -0,0 +1,59 @@ +package com.trivago.kangaroo.object2long; + +import com.trivago.fastutilconcurrentwrapper.ConcurrentMapBuilder; +import com.trivago.fastutilconcurrentwrapper.objectkeys.ConcurrentObjectLongMapBuilder; +import com.trivago.fastutilconcurrentwrapper.objectkeys.ObjectLongMap; +import com.trivago.kangaroo.AbstractCommonBenchHelper; + +import java.util.concurrent.ThreadLocalRandom; + +public abstract class AbstractObjectLongBenchHelper extends AbstractCommonBenchHelper { + + protected static final int NUM_VALUES = 1_000_000; + + protected ObjectLongMap map; + + public void initAndLoadData(ConcurrentMapBuilder.MapMode mode) { + map = ConcurrentObjectLongMapBuilder.newBuilder() + .withBuckets(16) + .withInitialCapacity(NUM_VALUES) + .withMode(mode) + .withLoadFactor(0.8f) + .build(); + + for (int i = 0; i < NUM_VALUES; i++) { + TestObjectKey key = new TestObjectKey(); + long value = ThreadLocalRandom.current().nextLong(); + map.put(key, value); + } + } + + public void testGet() { + TestObjectKey key = new TestObjectKey(); + map.get(key); + } + + public void testPut() { + TestObjectKey key = new TestObjectKey(); + long value = ThreadLocalRandom.current().nextLong(); + map.put(key, value); + } + + public void testAllOps() { + int op = ThreadLocalRandom.current().nextInt(3); + TestObjectKey key = new TestObjectKey(); + switch (op) { + case 1: + long value = ThreadLocalRandom.current().nextLong(); + map.put(key, value); + break; + case 2: + map.remove(key); + break; + default: + map.get(key); + break; + } + } + +} diff --git a/src/jmh/java/com/trivago/kangaroo/object2long/FastutilWrapperBusyWaitingObjectLongBenchmark.java b/src/jmh/java/com/trivago/kangaroo/object2long/FastutilWrapperBusyWaitingObjectLongBenchmark.java new file mode 100644 index 0000000..7d117a7 --- /dev/null +++ b/src/jmh/java/com/trivago/kangaroo/object2long/FastutilWrapperBusyWaitingObjectLongBenchmark.java @@ -0,0 +1,15 @@ +package com.trivago.kangaroo.object2long; + +import com.trivago.fastutilconcurrentwrapper.ConcurrentMapBuilder; +import org.openjdk.jmh.annotations.*; + +@State(Scope.Benchmark) +@Warmup(iterations = 3, time = 1) +@Measurement(iterations = 3, time = 2) +public class FastutilWrapperBusyWaitingObjectLongBenchmark extends AbstractObjectLongBenchHelper { + + @Setup(Level.Trial) + public void loadData() { + super.initAndLoadData(ConcurrentMapBuilder.MapMode.BUSY_WAITING); + } +} diff --git a/src/jmh/java/com/trivago/kangaroo/object2long/FastutilWrapperDefaultObjectLongBenchmark.java b/src/jmh/java/com/trivago/kangaroo/object2long/FastutilWrapperDefaultObjectLongBenchmark.java new file mode 100644 index 0000000..8ecf204 --- /dev/null +++ b/src/jmh/java/com/trivago/kangaroo/object2long/FastutilWrapperDefaultObjectLongBenchmark.java @@ -0,0 +1,15 @@ +package com.trivago.kangaroo.object2long; + +import com.trivago.fastutilconcurrentwrapper.ConcurrentMapBuilder; +import org.openjdk.jmh.annotations.*; + +@State(Scope.Benchmark) +@Warmup(iterations = 3, time = 1) +@Measurement(iterations = 3, time = 2) +public class FastutilWrapperDefaultObjectLongBenchmark extends AbstractObjectLongBenchHelper { + + @Setup(Level.Trial) + public void loadData() { + super.initAndLoadData(ConcurrentMapBuilder.MapMode.BLOCKING); + } +} diff --git a/src/jmh/java/com/trivago/kangaroo/object2long/JavaConcurrentObjectLongBenchmark.java b/src/jmh/java/com/trivago/kangaroo/object2long/JavaConcurrentObjectLongBenchmark.java new file mode 100644 index 0000000..adf0580 --- /dev/null +++ b/src/jmh/java/com/trivago/kangaroo/object2long/JavaConcurrentObjectLongBenchmark.java @@ -0,0 +1,53 @@ +package com.trivago.kangaroo.object2long; + +import com.trivago.kangaroo.AbstractCommonBenchHelper; +import org.openjdk.jmh.annotations.*; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ThreadLocalRandom; + +@State(Scope.Benchmark) +@Warmup(iterations = 3, time = 1) +@Measurement(iterations = 3, time = 2) +public class JavaConcurrentObjectLongBenchmark extends AbstractCommonBenchHelper { + + Map map; + + @Setup(Level.Trial) + public void loadData() { + map = new ConcurrentHashMap<>(AbstractObjectLongBenchHelper.NUM_VALUES, 0.8f); + for (int i = 0; i < AbstractObjectLongBenchHelper.NUM_VALUES; i++) { + TestObjectKey key = new TestObjectKey(); + long value = ThreadLocalRandom.current().nextLong(); + map.put(key, value); + } + } + + public void testGet() { + map.get(new TestObjectKey()); + } + + public void testPut() { + TestObjectKey key = new TestObjectKey(); + long value = ThreadLocalRandom.current().nextLong(); + map.put(key, value); + } + + public void testAllOps() { + int op = ThreadLocalRandom.current().nextInt(3); + TestObjectKey key = new TestObjectKey(); + switch (op) { + case 1: + long value = ThreadLocalRandom.current().nextLong(); + map.put(key, value); + break; + case 2: + map.remove(key); + break; + default: + map.get(key); + break; + } + } +} diff --git a/src/jmh/java/com/trivago/kangaroo/object2long/JavaUtilWrapperObjectLongBenchmark.java b/src/jmh/java/com/trivago/kangaroo/object2long/JavaUtilWrapperObjectLongBenchmark.java new file mode 100644 index 0000000..eca1ffe --- /dev/null +++ b/src/jmh/java/com/trivago/kangaroo/object2long/JavaUtilWrapperObjectLongBenchmark.java @@ -0,0 +1,55 @@ +package com.trivago.kangaroo.object2long; + +import com.trivago.kangaroo.AbstractCommonBenchHelper; +import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; +import org.openjdk.jmh.annotations.*; + +import java.util.Collections; +import java.util.Map; +import java.util.concurrent.ThreadLocalRandom; + +@State(Scope.Benchmark) +@Warmup(iterations = 3, time = 1) +@Measurement(iterations = 3, time = 2) +public class JavaUtilWrapperObjectLongBenchmark extends AbstractCommonBenchHelper { + + Map map; + + @Setup(Level.Trial) + public void loadData() { + Object2LongOpenHashMap m = new Object2LongOpenHashMap<>(AbstractObjectLongBenchHelper.NUM_VALUES, 0.8f); + for (int i = 0; i < AbstractObjectLongBenchHelper.NUM_VALUES; i++) { + TestObjectKey key = new TestObjectKey(); + long value = ThreadLocalRandom.current().nextLong(); + m.put(key, value); + } + map = Collections.synchronizedMap(m); + } + + public void testGet() { + map.get(new TestObjectKey()); + } + + public void testPut() { + TestObjectKey key = new TestObjectKey(); + long value = ThreadLocalRandom.current().nextLong(); + map.put(key, value); + } + + public void testAllOps() { + int op = ThreadLocalRandom.current().nextInt(3); + TestObjectKey key = new TestObjectKey(); + switch (op) { + case 1: + long value = ThreadLocalRandom.current().nextLong(); + map.put(key, value); + break; + case 2: + map.remove(key); + break; + default: + map.get(key); + break; + } + } +} diff --git a/src/jmh/java/com/trivago/kangaroo/object2long/TestObjectKey.java b/src/jmh/java/com/trivago/kangaroo/object2long/TestObjectKey.java new file mode 100644 index 0000000..2957802 --- /dev/null +++ b/src/jmh/java/com/trivago/kangaroo/object2long/TestObjectKey.java @@ -0,0 +1,13 @@ +package com.trivago.kangaroo.object2long; + +import java.util.concurrent.ThreadLocalRandom; + +public class TestObjectKey { + + private final int id = ThreadLocalRandom.current().nextInt(); + + @Override + public int hashCode() { + return Integer.hashCode(id); + } +} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/ConcurrentIntFloatMapBuilder.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/ConcurrentIntFloatMapBuilder.java deleted file mode 100644 index 28e5fe8..0000000 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/ConcurrentIntFloatMapBuilder.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.trivago.fastutilconcurrentwrapper; - -import com.trivago.fastutilconcurrentwrapper.map.ConcurrentBusyWaitingIntFloatMap; -import com.trivago.fastutilconcurrentwrapper.map.ConcurrentIntFloatMap; - -public final class ConcurrentIntFloatMapBuilder { - - private MapMode mapMode = MapMode.BUSY_WAITING; - private int buckets = 8; - private float defaultValue = 0.0f; - private int initialCapacity = 100_000; - private float loadFactor = 0.8f; - - private ConcurrentIntFloatMapBuilder() { - } - - public static ConcurrentIntFloatMapBuilder newBuilder() { - return new ConcurrentIntFloatMapBuilder(); - } - - public ConcurrentIntFloatMapBuilder withBuckets(int buckets) { - this.buckets = buckets; - return this; - } - - public ConcurrentIntFloatMapBuilder withDefaultValue(float defaultValue) { - this.defaultValue = defaultValue; - return this; - } - - public ConcurrentIntFloatMapBuilder withInitialCapacity(int initialCapacity) { - this.initialCapacity = initialCapacity; - return this; - } - - public ConcurrentIntFloatMapBuilder withLoadFactor(float loadFactor) { - this.loadFactor = loadFactor; - return this; - } - - public ConcurrentIntFloatMapBuilder withMode(MapMode mapMode) { - this.mapMode = mapMode; - return this; - } - - public IntFloatMap build() { - return mapMode.createMap(this); - } - - public enum MapMode { - BUSY_WAITING { - @Override - IntFloatMap createMap(ConcurrentIntFloatMapBuilder builder) { - return new ConcurrentBusyWaitingIntFloatMap( - builder.buckets, - builder.initialCapacity, - builder.loadFactor, - builder.defaultValue); - } - }, - BLOCKING { - @Override - IntFloatMap createMap(ConcurrentIntFloatMapBuilder builder) { - return new ConcurrentIntFloatMap( - builder.buckets, - builder.initialCapacity, - builder.loadFactor, - builder.defaultValue); - } - }; - - abstract IntFloatMap createMap(ConcurrentIntFloatMapBuilder builder); - } -} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/ConcurrentIntIntMapBuilder.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/ConcurrentIntIntMapBuilder.java deleted file mode 100644 index 090407c..0000000 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/ConcurrentIntIntMapBuilder.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.trivago.fastutilconcurrentwrapper; - -import com.trivago.fastutilconcurrentwrapper.map.ConcurrentBusyWaitingIntIntMap; -import com.trivago.fastutilconcurrentwrapper.map.ConcurrentIntIntMap; - -public final class ConcurrentIntIntMapBuilder { - - private MapMode mapMode = MapMode.BLOCKING; - private int buckets = 8; - private int defaultValue = 0; - private int initialCapacity = 100_000; - private float loadFactor = 0.8f; - - private ConcurrentIntIntMapBuilder() { - } - - public static ConcurrentIntIntMapBuilder newBuilder() { - return new ConcurrentIntIntMapBuilder(); - } - - public ConcurrentIntIntMapBuilder withBuckets(int buckets) { - this.buckets = buckets; - return this; - } - - public ConcurrentIntIntMapBuilder withDefaultValue(int defaultValue) { - this.defaultValue = defaultValue; - return this; - } - - public ConcurrentIntIntMapBuilder withInitialCapacity(int initialCapacity) { - this.initialCapacity = initialCapacity; - return this; - } - - public ConcurrentIntIntMapBuilder withLoadFactor(float loadFactor) { - this.loadFactor = loadFactor; - return this; - } - - public ConcurrentIntIntMapBuilder withMode(MapMode mapMode) { - this.mapMode = mapMode; - return this; - } - - public IntIntMap build() { - return mapMode.createMap(this); - } - - public enum MapMode { - BLOCKING { - @Override - IntIntMap createMap(ConcurrentIntIntMapBuilder builder) { - return new ConcurrentIntIntMap( - builder.buckets, - builder.initialCapacity, - builder.loadFactor, - builder.defaultValue); - } - }, - BUSY_WAITING { - @Override - IntIntMap createMap(ConcurrentIntIntMapBuilder builder) { - return new ConcurrentBusyWaitingIntIntMap( - builder.buckets, - builder.initialCapacity, - builder.loadFactor, - builder.defaultValue); - } - }; - - abstract IntIntMap createMap(ConcurrentIntIntMapBuilder builder); - } -} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/ConcurrentLongFloatMapBuilder.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/ConcurrentLongFloatMapBuilder.java deleted file mode 100644 index 353a2bd..0000000 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/ConcurrentLongFloatMapBuilder.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.trivago.fastutilconcurrentwrapper; - -import com.trivago.fastutilconcurrentwrapper.map.ConcurrentBusyWaitingLongFloatMap; -import com.trivago.fastutilconcurrentwrapper.map.ConcurrentLongFloatMap; - -public final class ConcurrentLongFloatMapBuilder { - - private MapMode mapMode = MapMode.BLOCKING; - private int buckets = 8; - private int initialCapacity = 100_000; - private float loadFactor = 0.8f; - private float defaultValue = LongFloatMap.DEFAULT_VALUE; - - private ConcurrentLongFloatMapBuilder() { - } - - public static ConcurrentLongFloatMapBuilder newBuilder() { - return new ConcurrentLongFloatMapBuilder(); - } - - public ConcurrentLongFloatMapBuilder withBuckets(int buckets) { - this.buckets = buckets; - return this; - } - - public ConcurrentLongFloatMapBuilder withInitialCapacity(int initialCapacity) { - this.initialCapacity = initialCapacity; - return this; - } - - public ConcurrentLongFloatMapBuilder withLoadFactor(float loadFactor) { - this.loadFactor = loadFactor; - return this; - } - - public ConcurrentLongFloatMapBuilder withDefaultValue(float defaultValue) { - this.defaultValue = defaultValue; - return this; - } - - public ConcurrentLongFloatMapBuilder withMode(MapMode mapMode) { - this.mapMode = mapMode; - return this; - } - - public LongFloatMap build() { - return mapMode.createMap(this); - } - - public enum MapMode { - BLOCKING { - @Override - LongFloatMap createMap(ConcurrentLongFloatMapBuilder builder) { - return new ConcurrentLongFloatMap( - builder.buckets, - builder.initialCapacity, - builder.loadFactor, - builder.defaultValue); - } - }, - BUSY_WAITING { - @Override - LongFloatMap createMap(ConcurrentLongFloatMapBuilder builder) { - return new ConcurrentBusyWaitingLongFloatMap( - builder.buckets, - builder.initialCapacity, - builder.loadFactor, - builder.defaultValue); - } - }; - - abstract LongFloatMap createMap(ConcurrentLongFloatMapBuilder builder); - } -} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/ConcurrentLongIntMapBuilder.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/ConcurrentLongIntMapBuilder.java deleted file mode 100644 index f4823b2..0000000 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/ConcurrentLongIntMapBuilder.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.trivago.fastutilconcurrentwrapper; - -import com.trivago.fastutilconcurrentwrapper.map.ConcurrentBusyWaitingLongIntMap; -import com.trivago.fastutilconcurrentwrapper.map.ConcurrentLongIntMap; - -public final class ConcurrentLongIntMapBuilder { - private MapMode mapMode = MapMode.BLOCKING; - private int buckets = 8; - private int initialCapacity = 100_000; - private float loadFactor = 0.8f; - private int defaultValue = LongIntMap.DEFAULT_VALUE; - - private ConcurrentLongIntMapBuilder() { - - } - - public static ConcurrentLongIntMapBuilder newBuilder() { - return new ConcurrentLongIntMapBuilder(); - } - - public ConcurrentLongIntMapBuilder withBuckets(int buckets) { - this.buckets = buckets; - return this; - } - - public ConcurrentLongIntMapBuilder withInitialCapacity(int initialCapacity) { - this.initialCapacity = initialCapacity; - return this; - } - - public ConcurrentLongIntMapBuilder withLoadFactor(float loadFactor) { - this.loadFactor = loadFactor; - return this; - } - - public ConcurrentLongIntMapBuilder withMode(MapMode mapMode) { - this.mapMode = mapMode; - return this; - } - - public ConcurrentLongIntMapBuilder withDefaultValue(int defaultValue) { - this.defaultValue = defaultValue; - return this; - } - - public LongIntMap build() { - return mapMode.createMap(this); - } - - public enum MapMode { - BUSY_WAITING { - @Override - LongIntMap createMap(ConcurrentLongIntMapBuilder builder) { - return new ConcurrentBusyWaitingLongIntMap( - builder.buckets, - builder.initialCapacity, - builder.loadFactor, - builder.defaultValue); - } - }, - BLOCKING { - @Override - LongIntMap createMap(ConcurrentLongIntMapBuilder builder) { - return new ConcurrentLongIntMap( - builder.buckets, - builder.initialCapacity, - builder.loadFactor, - builder.defaultValue); - } - }; - - abstract LongIntMap createMap(ConcurrentLongIntMapBuilder builder); - } -} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/ConcurrentLongLongMapBuilder.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/ConcurrentLongLongMapBuilder.java deleted file mode 100644 index 0b3cdcc..0000000 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/ConcurrentLongLongMapBuilder.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.trivago.fastutilconcurrentwrapper; - -import com.trivago.fastutilconcurrentwrapper.map.ConcurrentBusyWaitingLongLongMap; -import com.trivago.fastutilconcurrentwrapper.map.ConcurrentLongLongMap; - -public final class ConcurrentLongLongMapBuilder { - private MapMode mapMode = MapMode.BLOCKING; - private int buckets = 8; - private int initialCapacity = 100_000; - private float loadFactor = 0.8f; - private long defaultValue = LongLongMap.DEFAULT_VALUE; - - private ConcurrentLongLongMapBuilder() { - - } - - public static ConcurrentLongLongMapBuilder newBuilder() { - return new ConcurrentLongLongMapBuilder(); - } - - public ConcurrentLongLongMapBuilder withBuckets(int buckets) { - this.buckets = buckets; - return this; - } - - public ConcurrentLongLongMapBuilder withInitialCapacity(int initialCapacity) { - this.initialCapacity = initialCapacity; - return this; - } - - public ConcurrentLongLongMapBuilder withLoadFactor(float loadFactor) { - this.loadFactor = loadFactor; - return this; - } - - public ConcurrentLongLongMapBuilder withMode(MapMode mapMode) { - this.mapMode = mapMode; - return this; - } - - public ConcurrentLongLongMapBuilder withDefaultValue(long defaultValue) { - this.defaultValue = defaultValue; - return this; - } - - public LongLongMap build() { - return mapMode.createMap(this); - } - - public enum MapMode { - BUSY_WAITING { - @Override - LongLongMap createMap(ConcurrentLongLongMapBuilder builder) { - return new ConcurrentBusyWaitingLongLongMap( - builder.buckets, - builder.initialCapacity, - builder.loadFactor, - builder.defaultValue); - } - }, - BLOCKING { - @Override - LongLongMap createMap(ConcurrentLongLongMapBuilder builder) { - return new ConcurrentLongLongMap( - builder.buckets, - builder.initialCapacity, - builder.loadFactor, - builder.defaultValue); - } - }; - - abstract LongLongMap createMap(ConcurrentLongLongMapBuilder builder); - } -} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/ConcurrentMapBuilder.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/ConcurrentMapBuilder.java new file mode 100644 index 0000000..a46684e --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/ConcurrentMapBuilder.java @@ -0,0 +1,40 @@ +package com.trivago.fastutilconcurrentwrapper; + +@SuppressWarnings("unchecked") +public abstract class ConcurrentMapBuilder, K extends KeyMap> { + + protected MapMode mapMode; + protected int buckets = 8; + protected int initialCapacity = 100_000; + protected float loadFactor = 0.8f; + + protected ConcurrentMapBuilder() { + } + + public B withBuckets(int buckets) { + this.buckets = buckets; + return (B) this; + } + + public B withInitialCapacity(int initialCapacity) { + this.initialCapacity = initialCapacity; + return (B) this; + } + + public B withLoadFactor(float loadFactor) { + this.loadFactor = loadFactor; + return (B) this; + } + + public B withMode(MapMode mapMode) { + this.mapMode = mapMode; + return (B) this; + } + + public abstract K build(); + + public enum MapMode { + BUSY_WAITING, + BLOCKING + } +} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/PrimitiveKeyMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/KeyMap.java similarity index 72% rename from src/main/java/com/trivago/fastutilconcurrentwrapper/PrimitiveKeyMap.java rename to src/main/java/com/trivago/fastutilconcurrentwrapper/KeyMap.java index b903d58..055ab37 100644 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/PrimitiveKeyMap.java +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/KeyMap.java @@ -1,6 +1,6 @@ package com.trivago.fastutilconcurrentwrapper; -public interface PrimitiveKeyMap { +public interface KeyMap { int size(); boolean isEmpty(); diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/PrimitiveIntKeyMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/PrimitiveIntKeyMap.java deleted file mode 100644 index 86f8bd8..0000000 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/PrimitiveIntKeyMap.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.trivago.fastutilconcurrentwrapper; - -public interface PrimitiveIntKeyMap extends PrimitiveKeyMap { - boolean containsKey(int key); -} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/PrimitiveLongKeyMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/PrimitiveLongKeyMap.java deleted file mode 100644 index f01b048..0000000 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/PrimitiveLongKeyMap.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.trivago.fastutilconcurrentwrapper; - -public interface PrimitiveLongKeyMap extends PrimitiveKeyMap { - boolean containsKey(long key); -} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/ConcurrentObjectFloatMapBuilder.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/ConcurrentObjectFloatMapBuilder.java new file mode 100644 index 0000000..d562e5e --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/ConcurrentObjectFloatMapBuilder.java @@ -0,0 +1,41 @@ +package com.trivago.fastutilconcurrentwrapper.objectkeys; + +import com.trivago.fastutilconcurrentwrapper.ConcurrentMapBuilder; +import com.trivago.fastutilconcurrentwrapper.objectkeys.map.ConcurrentBusyWaitingObjectFloatMap; +import com.trivago.fastutilconcurrentwrapper.objectkeys.map.ConcurrentObjectFloatMap; + +public final class ConcurrentObjectFloatMapBuilder extends ConcurrentMapBuilder< + ConcurrentObjectFloatMapBuilder, ObjectFloatMap> { + + private float defaultValue = ObjectFloatMap.DEFAULT_VALUE; + + private ConcurrentObjectFloatMapBuilder() { + } + + public static ConcurrentObjectFloatMapBuilder newBuilder() { + return new ConcurrentObjectFloatMapBuilder<>(); + } + + public ConcurrentObjectFloatMapBuilder withDefaultValue(float defaultValue) { + this.defaultValue = defaultValue; + return this; + } + + @Override + public ObjectFloatMap build() { + return switch (mapMode) { + case BUSY_WAITING -> new ConcurrentBusyWaitingObjectFloatMap<>( + this.buckets, + this.initialCapacity, + this.loadFactor, + this.defaultValue + ); + case BLOCKING -> new ConcurrentObjectFloatMap<>( + this.buckets, + this.initialCapacity, + this.loadFactor, + this.defaultValue + ); + }; + } +} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/ConcurrentObjectIntMapBuilder.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/ConcurrentObjectIntMapBuilder.java new file mode 100644 index 0000000..d1dcc07 --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/ConcurrentObjectIntMapBuilder.java @@ -0,0 +1,41 @@ +package com.trivago.fastutilconcurrentwrapper.objectkeys; + +import com.trivago.fastutilconcurrentwrapper.ConcurrentMapBuilder; +import com.trivago.fastutilconcurrentwrapper.objectkeys.map.ConcurrentBusyWaitingObjectIntMap; +import com.trivago.fastutilconcurrentwrapper.objectkeys.map.ConcurrentObjectIntMap; + +public final class ConcurrentObjectIntMapBuilder extends ConcurrentMapBuilder< + ConcurrentObjectIntMapBuilder, ObjectIntMap> { + + private int defaultValue = ObjectIntMap.DEFAULT_VALUE; + + private ConcurrentObjectIntMapBuilder() { + } + + public static ConcurrentObjectIntMapBuilder newBuilder() { + return new ConcurrentObjectIntMapBuilder<>(); + } + + public ConcurrentObjectIntMapBuilder withDefaultValue(int defaultValue) { + this.defaultValue = defaultValue; + return this; + } + + @Override + public ObjectIntMap build() { + return switch (mapMode) { + case BUSY_WAITING -> new ConcurrentBusyWaitingObjectIntMap<>( + this.buckets, + this.initialCapacity, + this.loadFactor, + this.defaultValue + ); + case BLOCKING -> new ConcurrentObjectIntMap<>( + this.buckets, + this.initialCapacity, + this.loadFactor, + this.defaultValue + ); + }; + } +} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/ConcurrentObjectLongMapBuilder.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/ConcurrentObjectLongMapBuilder.java new file mode 100644 index 0000000..f70c713 --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/ConcurrentObjectLongMapBuilder.java @@ -0,0 +1,41 @@ +package com.trivago.fastutilconcurrentwrapper.objectkeys; + +import com.trivago.fastutilconcurrentwrapper.ConcurrentMapBuilder; +import com.trivago.fastutilconcurrentwrapper.objectkeys.map.ConcurrentBusyWaitingObjectLongMap; +import com.trivago.fastutilconcurrentwrapper.objectkeys.map.ConcurrentObjectLongMap; + +public final class ConcurrentObjectLongMapBuilder extends ConcurrentMapBuilder< + ConcurrentObjectLongMapBuilder, ObjectLongMap> { + + private long defaultValue = ObjectLongMap.DEFAULT_VALUE; + + private ConcurrentObjectLongMapBuilder() { + } + + public static ConcurrentObjectLongMapBuilder newBuilder() { + return new ConcurrentObjectLongMapBuilder<>(); + } + + public ConcurrentObjectLongMapBuilder withDefaultValue(long defaultValue) { + this.defaultValue = defaultValue; + return this; + } + + @Override + public ObjectLongMap build() { + return switch (mapMode) { + case BUSY_WAITING -> new ConcurrentBusyWaitingObjectLongMap<>( + this.buckets, + this.initialCapacity, + this.loadFactor, + this.defaultValue + ); + case BLOCKING -> new ConcurrentObjectLongMap<>( + this.buckets, + this.initialCapacity, + this.loadFactor, + this.defaultValue + ); + }; + } +} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/ObjectFloatMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/ObjectFloatMap.java new file mode 100644 index 0000000..f409241 --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/ObjectFloatMap.java @@ -0,0 +1,28 @@ +package com.trivago.fastutilconcurrentwrapper.objectkeys; + +import it.unimi.dsi.fastutil.objects.Object2FloatFunction; + +import java.util.function.BiFunction; + +public interface ObjectFloatMap extends ObjectKeyMap { + + float DEFAULT_VALUE = 0F; + + /** + * @param key + * @return 0 if the key is not present + */ + float get(K key); + + float put(K key, float value); + + float getDefaultValue(); + + float remove(K key); + + boolean remove(K key, float value); + + float computeIfAbsent(K key, Object2FloatFunction mappingFunction); + + float computeIfPresent(K key, BiFunction mappingFunction); +} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/ObjectIntMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/ObjectIntMap.java new file mode 100644 index 0000000..dc9593e --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/ObjectIntMap.java @@ -0,0 +1,28 @@ +package com.trivago.fastutilconcurrentwrapper.objectkeys; + +import it.unimi.dsi.fastutil.objects.Object2IntFunction; + +import java.util.function.BiFunction; + +public interface ObjectIntMap extends ObjectKeyMap { + + int DEFAULT_VALUE = 0; + + /** + * @param key + * @return 0 if the key is not present + */ + int get(K key); + + int put(K key, int value); + + int getDefaultValue(); + + int remove(K key); + + boolean remove(K key, int value); + + int computeIfAbsent(K key, Object2IntFunction mappingFunction); + + int computeIfPresent(K key, BiFunction mappingFunction); +} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/ObjectKeyMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/ObjectKeyMap.java new file mode 100644 index 0000000..63718d9 --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/ObjectKeyMap.java @@ -0,0 +1,7 @@ +package com.trivago.fastutilconcurrentwrapper.objectkeys; + +import com.trivago.fastutilconcurrentwrapper.KeyMap; + +public interface ObjectKeyMap extends KeyMap { + boolean containsKey(K key); +} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/ObjectLongMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/ObjectLongMap.java new file mode 100644 index 0000000..7258087 --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/ObjectLongMap.java @@ -0,0 +1,28 @@ +package com.trivago.fastutilconcurrentwrapper.objectkeys; + +import it.unimi.dsi.fastutil.objects.Object2LongFunction; + +import java.util.function.BiFunction; + +public interface ObjectLongMap extends ObjectKeyMap { + + long DEFAULT_VALUE = 0L; + + /** + * @param key + * @return 0 if the key is not present + */ + long get(K key); + + long put(K key, long value); + + long getDefaultValue(); + + long remove(K key); + + boolean remove(K key, long value); + + long computeIfAbsent(K key, Object2LongFunction mappingFunction); + + long computeIfPresent(K key, BiFunction mappingFunction); +} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/map/ConcurrentBusyWaitingObjectFloatMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/map/ConcurrentBusyWaitingObjectFloatMap.java new file mode 100644 index 0000000..6b69a3f --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/map/ConcurrentBusyWaitingObjectFloatMap.java @@ -0,0 +1,163 @@ +package com.trivago.fastutilconcurrentwrapper.objectkeys.map; + +import com.trivago.fastutilconcurrentwrapper.objectkeys.ObjectFloatMap; +import com.trivago.fastutilconcurrentwrapper.objectkeys.wrapper.PrimitiveFastutilObjectFloatWrapper; +import it.unimi.dsi.fastutil.objects.Object2FloatFunction; + +import java.util.concurrent.locks.Lock; +import java.util.function.BiFunction; + +public class ConcurrentBusyWaitingObjectFloatMap extends ObjectConcurrentMap implements ObjectFloatMap { + + private final ObjectFloatMap[] maps; + private final float defaultValue; + + public ConcurrentBusyWaitingObjectFloatMap(int numBuckets, + int initialCapacity, + float loadFactor, + float defaultValue) { + super(numBuckets); + + //noinspection unchecked + this.maps = new ObjectFloatMap[numBuckets]; + this.defaultValue = defaultValue; + + for (int i = 0; i < numBuckets; i++) { + maps[i] = new PrimitiveFastutilObjectFloatWrapper<>(initialCapacity, loadFactor, defaultValue); + } + } + + @Override + public int size() { + return super.size(maps); + } + + @Override + public boolean isEmpty() { + return super.isEmpty(maps); + } + + @Override + public boolean containsKey(K 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 float get(K 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 float put(K key, float 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 float getDefaultValue() { + return defaultValue; + } + + @Override + public float remove(K 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(K key, float 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 float computeIfAbsent(K key, Object2FloatFunction 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 float computeIfPresent(K 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/objectkeys/map/ConcurrentBusyWaitingObjectIntMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/map/ConcurrentBusyWaitingObjectIntMap.java new file mode 100644 index 0000000..e542eca --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/map/ConcurrentBusyWaitingObjectIntMap.java @@ -0,0 +1,163 @@ +package com.trivago.fastutilconcurrentwrapper.objectkeys.map; + +import com.trivago.fastutilconcurrentwrapper.objectkeys.ObjectIntMap; +import com.trivago.fastutilconcurrentwrapper.objectkeys.wrapper.PrimitiveFastutilObjectIntWrapper; +import it.unimi.dsi.fastutil.objects.Object2IntFunction; + +import java.util.concurrent.locks.Lock; +import java.util.function.BiFunction; + +public class ConcurrentBusyWaitingObjectIntMap extends ObjectConcurrentMap implements ObjectIntMap { + + private final ObjectIntMap[] maps; + private final int defaultValue; + + public ConcurrentBusyWaitingObjectIntMap(int numBuckets, + int initialCapacity, + float loadFactor, + int defaultValue) { + super(numBuckets); + + //noinspection unchecked + this.maps = new ObjectIntMap[numBuckets]; + this.defaultValue = defaultValue; + + for (int i = 0; i < numBuckets; i++) { + maps[i] = new PrimitiveFastutilObjectIntWrapper<>(initialCapacity, loadFactor, defaultValue); + } + } + + @Override + public int size() { + return super.size(maps); + } + + @Override + public boolean isEmpty() { + return super.isEmpty(maps); + } + + @Override + public boolean containsKey(K 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 int get(K 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 int put(K key, int 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 int getDefaultValue() { + return defaultValue; + } + + @Override + public int remove(K 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(K key, int 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 int computeIfAbsent(K key, Object2IntFunction 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 int computeIfPresent(K 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/objectkeys/map/ConcurrentBusyWaitingObjectLongMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/map/ConcurrentBusyWaitingObjectLongMap.java new file mode 100644 index 0000000..aae6f9c --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/map/ConcurrentBusyWaitingObjectLongMap.java @@ -0,0 +1,163 @@ +package com.trivago.fastutilconcurrentwrapper.objectkeys.map; + +import com.trivago.fastutilconcurrentwrapper.objectkeys.ObjectLongMap; +import com.trivago.fastutilconcurrentwrapper.objectkeys.wrapper.PrimitiveFastutilObjectLongWrapper; +import it.unimi.dsi.fastutil.objects.Object2LongFunction; + +import java.util.concurrent.locks.Lock; +import java.util.function.BiFunction; + +public class ConcurrentBusyWaitingObjectLongMap extends ObjectConcurrentMap implements ObjectLongMap { + + private final ObjectLongMap[] maps; + private final long defaultValue; + + public ConcurrentBusyWaitingObjectLongMap(int numBuckets, + int initialCapacity, + float loadFactor, + long defaultValue) { + super(numBuckets); + + //noinspection unchecked + this.maps = new ObjectLongMap[numBuckets]; + this.defaultValue = defaultValue; + + for (int i = 0; i < numBuckets; i++) { + maps[i] = new PrimitiveFastutilObjectLongWrapper<>(initialCapacity, loadFactor, defaultValue); + } + } + + @Override + public int size() { + return super.size(maps); + } + + @Override + public boolean isEmpty() { + return super.isEmpty(maps); + } + + @Override + public boolean containsKey(K 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(K 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(K 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(K 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(K 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(K key, Object2LongFunction 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(K 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/objectkeys/map/ConcurrentObjectFloatMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/map/ConcurrentObjectFloatMap.java new file mode 100644 index 0000000..f14af0f --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/map/ConcurrentObjectFloatMap.java @@ -0,0 +1,146 @@ +package com.trivago.fastutilconcurrentwrapper.objectkeys.map; + +import com.trivago.fastutilconcurrentwrapper.objectkeys.ObjectFloatMap; +import com.trivago.fastutilconcurrentwrapper.objectkeys.ObjectIntMap; +import com.trivago.fastutilconcurrentwrapper.objectkeys.wrapper.PrimitiveFastutilObjectFloatWrapper; +import com.trivago.fastutilconcurrentwrapper.objectkeys.wrapper.PrimitiveFastutilObjectIntWrapper; +import it.unimi.dsi.fastutil.objects.Object2FloatFunction; +import it.unimi.dsi.fastutil.objects.Object2IntFunction; + +import java.util.concurrent.locks.Lock; +import java.util.function.BiFunction; + +public class ConcurrentObjectFloatMap extends ObjectConcurrentMap implements ObjectFloatMap { + + private final ObjectFloatMap[] maps; + private final float defaultValue; + + public ConcurrentObjectFloatMap(int numBuckets, + int initialCapacity, + float loadFactor, + float defaultValue) { + super(numBuckets); + + //noinspection unchecked + this.maps = new ObjectFloatMap[numBuckets]; + this.defaultValue = defaultValue; + + for (int i = 0; i < numBuckets; i++) { + maps[i] = new PrimitiveFastutilObjectFloatWrapper<>(initialCapacity, loadFactor, defaultValue); + } + } + + @Override + public int size() { + return super.size(maps); + } + + @Override + public boolean isEmpty() { + return super.isEmpty(maps); + } + + @Override + public boolean containsKey(K key) { + int bucket = getBucket(key); + + Lock readLock = locks[bucket].readLock(); + readLock.lock(); + try { + return maps[bucket].containsKey(key); + } finally { + readLock.unlock(); + } + } + + @Override + public float get(K l) { + int bucket = getBucket(l); + + float result; + + Lock readLock = locks[bucket].readLock(); + readLock.lock(); + try { + result = maps[bucket].get(l); + } finally { + readLock.unlock(); + } + + return result; + } + + @Override + public float put(K key, float value) { + int bucket = getBucket(key); + + float result; + + Lock writeLock = locks[bucket].writeLock(); + writeLock.lock(); + try { + result = maps[bucket].put(key, value); + } finally { + writeLock.unlock(); + } + + return result; + } + + @Override + public float getDefaultValue() { + return defaultValue; + } + + @Override + public float remove(K 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(K key, float value) { + int bucket = getBucket(key); + + Lock writeLock = locks[bucket].writeLock(); + writeLock.lock(); + try { + return maps[bucket].remove(key, value); + } finally { + writeLock.unlock(); + } + } + + @Override + public float computeIfAbsent(K key, Object2FloatFunction mappingFunction) { + int bucket = getBucket(key); + + Lock writeLock = locks[bucket].writeLock(); + writeLock.lock(); + try { + return maps[bucket].computeIfAbsent(key, mappingFunction); + } finally { + writeLock.unlock(); + } + } + + @Override + public float computeIfPresent(K 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/objectkeys/map/ConcurrentObjectIntMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/map/ConcurrentObjectIntMap.java new file mode 100644 index 0000000..4e23ec6 --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/map/ConcurrentObjectIntMap.java @@ -0,0 +1,146 @@ +package com.trivago.fastutilconcurrentwrapper.objectkeys.map; + +import com.trivago.fastutilconcurrentwrapper.objectkeys.ObjectIntMap; +import com.trivago.fastutilconcurrentwrapper.objectkeys.ObjectLongMap; +import com.trivago.fastutilconcurrentwrapper.objectkeys.wrapper.PrimitiveFastutilObjectIntWrapper; +import com.trivago.fastutilconcurrentwrapper.objectkeys.wrapper.PrimitiveFastutilObjectLongWrapper; +import it.unimi.dsi.fastutil.objects.Object2IntFunction; +import it.unimi.dsi.fastutil.objects.Object2LongFunction; + +import java.util.concurrent.locks.Lock; +import java.util.function.BiFunction; + +public class ConcurrentObjectIntMap extends ObjectConcurrentMap implements ObjectIntMap { + + private final ObjectIntMap[] maps; + private final int defaultValue; + + public ConcurrentObjectIntMap(int numBuckets, + int initialCapacity, + float loadFactor, + int defaultValue) { + super(numBuckets); + + //noinspection unchecked + this.maps = new ObjectIntMap[numBuckets]; + this.defaultValue = defaultValue; + + for (int i = 0; i < numBuckets; i++) { + maps[i] = new PrimitiveFastutilObjectIntWrapper<>(initialCapacity, loadFactor, defaultValue); + } + } + + @Override + public int size() { + return super.size(maps); + } + + @Override + public boolean isEmpty() { + return super.isEmpty(maps); + } + + @Override + public boolean containsKey(K key) { + int bucket = getBucket(key); + + Lock readLock = locks[bucket].readLock(); + readLock.lock(); + try { + return maps[bucket].containsKey(key); + } finally { + readLock.unlock(); + } + } + + @Override + public int get(K l) { + int bucket = getBucket(l); + + int result; + + Lock readLock = locks[bucket].readLock(); + readLock.lock(); + try { + result = maps[bucket].get(l); + } finally { + readLock.unlock(); + } + + return result; + } + + @Override + public int put(K key, int value) { + int bucket = getBucket(key); + + int result; + + Lock writeLock = locks[bucket].writeLock(); + writeLock.lock(); + try { + result = maps[bucket].put(key, value); + } finally { + writeLock.unlock(); + } + + return result; + } + + @Override + public int getDefaultValue() { + return defaultValue; + } + + @Override + public int remove(K 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(K key, int value) { + int bucket = getBucket(key); + + Lock writeLock = locks[bucket].writeLock(); + writeLock.lock(); + try { + return maps[bucket].remove(key, value); + } finally { + writeLock.unlock(); + } + } + + @Override + public int computeIfAbsent(K key, Object2IntFunction mappingFunction) { + int bucket = getBucket(key); + + Lock writeLock = locks[bucket].writeLock(); + writeLock.lock(); + try { + return maps[bucket].computeIfAbsent(key, mappingFunction); + } finally { + writeLock.unlock(); + } + } + + @Override + public int computeIfPresent(K 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/objectkeys/map/ConcurrentObjectLongMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/map/ConcurrentObjectLongMap.java new file mode 100644 index 0000000..ae9c0b2 --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/map/ConcurrentObjectLongMap.java @@ -0,0 +1,143 @@ +package com.trivago.fastutilconcurrentwrapper.objectkeys.map; + +import com.trivago.fastutilconcurrentwrapper.objectkeys.ObjectLongMap; +import com.trivago.fastutilconcurrentwrapper.objectkeys.wrapper.PrimitiveFastutilObjectLongWrapper; +import it.unimi.dsi.fastutil.objects.Object2LongFunction; + +import java.util.concurrent.locks.Lock; +import java.util.function.BiFunction; + +public class ConcurrentObjectLongMap extends ObjectConcurrentMap implements ObjectLongMap { + + private final ObjectLongMap[] maps; + private final long defaultValue; + + public ConcurrentObjectLongMap(int numBuckets, + int initialCapacity, + float loadFactor, + long defaultValue) { + super(numBuckets); + + //noinspection unchecked + this.maps = new ObjectLongMap[numBuckets]; + this.defaultValue = defaultValue; + + for (int i = 0; i < numBuckets; i++) { + maps[i] = new PrimitiveFastutilObjectLongWrapper<>(initialCapacity, loadFactor, defaultValue); + } + } + + @Override + public int size() { + return super.size(maps); + } + + @Override + public boolean isEmpty() { + return super.isEmpty(maps); + } + + @Override + public boolean containsKey(K 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(K 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(K 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(K 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(K 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(K key, Object2LongFunction 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(K 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/objectkeys/map/ObjectConcurrentMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/map/ObjectConcurrentMap.java new file mode 100644 index 0000000..5cfcd03 --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/map/ObjectConcurrentMap.java @@ -0,0 +1,66 @@ +package com.trivago.fastutilconcurrentwrapper.objectkeys.map; + +import com.trivago.fastutilconcurrentwrapper.KeyMap; + +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +public abstract class ObjectConcurrentMap { + + protected final int numBuckets; + protected final ReadWriteLock[] locks; + + protected ObjectConcurrentMap(int numBuckets) { + this.numBuckets = numBuckets; + this.locks = new ReadWriteLock[numBuckets]; + for (int i = 0; i < numBuckets; i++) { + locks[i] = new ReentrantReadWriteLock(); + } + } + + protected int size(KeyMap[] maps) { + int sum = 0; + for (int i = 0; i < numBuckets; i++) { + sum = sum + sizeOfMap(i, maps); + } + return sum; + } + + private int sizeOfMap(int index, KeyMap[] maps) { + Lock readLock = locks[index].readLock(); + readLock.lock(); + try { + return maps[index].size(); + } finally { + readLock.unlock(); + } + } + + protected boolean isEmpty(KeyMap[] maps) { + for (int i = 0; i < numBuckets; i++) { + if (!isMapEmpty(i, maps)) { + return false; + } + } + return true; + } + + private boolean isMapEmpty(int index, KeyMap[] maps) { + Lock readLock = locks[index].readLock(); + readLock.lock(); + try { + return maps[index].isEmpty(); + } finally { + readLock.unlock(); + } + } + + protected int getBucket(K key) { + return getBucketCheckMinValue(key.hashCode()); + } + + private int getBucketCheckMinValue(int hash) { + return Math.abs(hash == Integer.MIN_VALUE ? 0 : hash) % numBuckets; + } +} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/wrapper/PrimitiveFastutilObjectFloatWrapper.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/wrapper/PrimitiveFastutilObjectFloatWrapper.java new file mode 100644 index 0000000..b3a7bc9 --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/wrapper/PrimitiveFastutilObjectFloatWrapper.java @@ -0,0 +1,71 @@ +package com.trivago.fastutilconcurrentwrapper.objectkeys.wrapper; + +import com.trivago.fastutilconcurrentwrapper.objectkeys.ObjectFloatMap; +import it.unimi.dsi.fastutil.objects.Object2FloatFunction; +import it.unimi.dsi.fastutil.objects.Object2FloatOpenHashMap; + +import java.util.function.BiFunction; + +public class PrimitiveFastutilObjectFloatWrapper implements ObjectFloatMap { + private final Object2FloatOpenHashMap map; + private final float defaultValue; + + public PrimitiveFastutilObjectFloatWrapper(int initialCapacity, float loadFactor) { + this(initialCapacity, loadFactor, ObjectFloatMap.DEFAULT_VALUE); + } + + public PrimitiveFastutilObjectFloatWrapper(int initialCapacity, float loadFactor, float defaultValue) { + this.defaultValue = defaultValue; + this.map = new Object2FloatOpenHashMap<>(initialCapacity, loadFactor); + } + + @Override + public float get(K key) { + return map.getOrDefault(key, defaultValue); + } + + @Override + public float put(K key, float value) { + return map.put(key, value); + } + + @Override + public float getDefaultValue() { + return defaultValue; + } + + @Override + public float remove(K key) { + return map.removeFloat(key); + } + + @Override + public boolean remove(K key, float value) { + return map.remove(key, value); + } + + @Override + public int size() { + return map.size(); + } + + @Override + public boolean containsKey(K key) { + return map.containsKey(key); + } + + @Override + public boolean isEmpty() { + return map.isEmpty(); + } + + @Override + public float computeIfAbsent(K key, Object2FloatFunction mappingFunction) { + return map.computeIfAbsent(key, mappingFunction); + } + + @Override + public float computeIfPresent(K key, BiFunction mappingFunction) { + return map.computeFloatIfPresent(key, mappingFunction); + } +} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/wrapper/PrimitiveFastutilObjectIntWrapper.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/wrapper/PrimitiveFastutilObjectIntWrapper.java new file mode 100644 index 0000000..6b773af --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/wrapper/PrimitiveFastutilObjectIntWrapper.java @@ -0,0 +1,71 @@ +package com.trivago.fastutilconcurrentwrapper.objectkeys.wrapper; + +import com.trivago.fastutilconcurrentwrapper.objectkeys.ObjectIntMap; +import it.unimi.dsi.fastutil.objects.Object2IntFunction; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; + +import java.util.function.BiFunction; + +public class PrimitiveFastutilObjectIntWrapper implements ObjectIntMap { + private final Object2IntOpenHashMap map; + private final int defaultValue; + + public PrimitiveFastutilObjectIntWrapper(int initialCapacity, float loadFactor) { + this(initialCapacity, loadFactor, ObjectIntMap.DEFAULT_VALUE); + } + + public PrimitiveFastutilObjectIntWrapper(int initialCapacity, float loadFactor, int defaultValue) { + this.defaultValue = defaultValue; + this.map = new Object2IntOpenHashMap<>(initialCapacity, loadFactor); + } + + @Override + public int get(K key) { + return map.getOrDefault(key, defaultValue); + } + + @Override + public int put(K key, int value) { + return map.put(key, value); + } + + @Override + public int getDefaultValue() { + return defaultValue; + } + + @Override + public int remove(K key) { + return map.removeInt(key); + } + + @Override + public boolean remove(K key, int value) { + return map.remove(key, value); + } + + @Override + public int size() { + return map.size(); + } + + @Override + public boolean containsKey(K key) { + return map.containsKey(key); + } + + @Override + public boolean isEmpty() { + return map.isEmpty(); + } + + @Override + public int computeIfAbsent(K key, Object2IntFunction mappingFunction) { + return map.computeIfAbsent(key, mappingFunction); + } + + @Override + public int computeIfPresent(K key, BiFunction mappingFunction) { + return map.computeIntIfPresent(key, mappingFunction); + } +} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/wrapper/PrimitiveFastutilObjectLongWrapper.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/wrapper/PrimitiveFastutilObjectLongWrapper.java new file mode 100644 index 0000000..5c1c065 --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/objectkeys/wrapper/PrimitiveFastutilObjectLongWrapper.java @@ -0,0 +1,71 @@ +package com.trivago.fastutilconcurrentwrapper.objectkeys.wrapper; + +import com.trivago.fastutilconcurrentwrapper.objectkeys.ObjectLongMap; +import it.unimi.dsi.fastutil.objects.Object2LongFunction; +import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; + +import java.util.function.BiFunction; + +public class PrimitiveFastutilObjectLongWrapper implements ObjectLongMap { + private final Object2LongOpenHashMap map; + private final long defaultValue; + + public PrimitiveFastutilObjectLongWrapper(int initialCapacity, float loadFactor) { + this(initialCapacity, loadFactor, ObjectLongMap.DEFAULT_VALUE); + } + + public PrimitiveFastutilObjectLongWrapper(int initialCapacity, float loadFactor, long defaultValue) { + this.defaultValue = defaultValue; + this.map = new Object2LongOpenHashMap<>(initialCapacity, loadFactor); + } + + @Override + public long get(K key) { + return map.getOrDefault(key, defaultValue); + } + + @Override + public long put(K key, long value) { + return map.put(key, value); + } + + @Override + public long getDefaultValue() { + return defaultValue; + } + + @Override + public long remove(K key) { + return map.removeLong(key); + } + + @Override + public boolean remove(K key, long value) { + return map.remove(key, value); + } + + @Override + public int size() { + return map.size(); + } + + @Override + public boolean containsKey(K key) { + return map.containsKey(key); + } + + @Override + public boolean isEmpty() { + return map.isEmpty(); + } + + @Override + public long computeIfAbsent(K key, Object2LongFunction mappingFunction) { + return map.computeIfAbsent(key, mappingFunction); + } + + @Override + public long computeIfPresent(K key, BiFunction mappingFunction) { + return map.computeLongIfPresent(key, mappingFunction); + } +} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/ConcurrentIntFloatMapBuilder.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/ConcurrentIntFloatMapBuilder.java new file mode 100644 index 0000000..b6b4fc5 --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/ConcurrentIntFloatMapBuilder.java @@ -0,0 +1,41 @@ +package com.trivago.fastutilconcurrentwrapper.primitivekeys; + +import com.trivago.fastutilconcurrentwrapper.ConcurrentMapBuilder; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentBusyWaitingIntFloatMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentIntFloatMap; + +public final class ConcurrentIntFloatMapBuilder + extends ConcurrentMapBuilder { + + private float defaultValue = 0.0f; + + private ConcurrentIntFloatMapBuilder() { + } + + public static ConcurrentIntFloatMapBuilder newBuilder() { + return new ConcurrentIntFloatMapBuilder(); + } + + public ConcurrentIntFloatMapBuilder withDefaultValue(float defaultValue) { + this.defaultValue = defaultValue; + return this; + } + + @Override + public IntFloatMap build() { + return switch (mapMode) { + case BUSY_WAITING -> new ConcurrentBusyWaitingIntFloatMap( + this.buckets, + this.initialCapacity, + this.loadFactor, + this.defaultValue + ); + case BLOCKING -> new ConcurrentIntFloatMap( + this.buckets, + this.initialCapacity, + this.loadFactor, + this.defaultValue + ); + }; + } +} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/ConcurrentIntIntMapBuilder.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/ConcurrentIntIntMapBuilder.java new file mode 100644 index 0000000..0681dae --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/ConcurrentIntIntMapBuilder.java @@ -0,0 +1,40 @@ +package com.trivago.fastutilconcurrentwrapper.primitivekeys; + +import com.trivago.fastutilconcurrentwrapper.ConcurrentMapBuilder; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentBusyWaitingIntIntMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentIntIntMap; + +public final class ConcurrentIntIntMapBuilder extends ConcurrentMapBuilder { + + private int defaultValue = 0; + + private ConcurrentIntIntMapBuilder() { + } + + public static ConcurrentIntIntMapBuilder newBuilder() { + return new ConcurrentIntIntMapBuilder(); + } + + public ConcurrentIntIntMapBuilder withDefaultValue(int defaultValue) { + this.defaultValue = defaultValue; + return this; + } + + @Override + public IntIntMap build() { + return switch (mapMode) { + case BUSY_WAITING -> new ConcurrentBusyWaitingIntIntMap( + this.buckets, + this.initialCapacity, + this.loadFactor, + this.defaultValue + ); + case BLOCKING -> new ConcurrentIntIntMap( + this.buckets, + this.initialCapacity, + this.loadFactor, + this.defaultValue + ); + }; + } +} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/ConcurrentLongFloatMapBuilder.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/ConcurrentLongFloatMapBuilder.java new file mode 100644 index 0000000..25b086d --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/ConcurrentLongFloatMapBuilder.java @@ -0,0 +1,41 @@ +package com.trivago.fastutilconcurrentwrapper.primitivekeys; + +import com.trivago.fastutilconcurrentwrapper.ConcurrentMapBuilder; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentBusyWaitingLongFloatMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentLongFloatMap; + +public final class ConcurrentLongFloatMapBuilder + extends ConcurrentMapBuilder { + + private float defaultValue = LongFloatMap.DEFAULT_VALUE; + + private ConcurrentLongFloatMapBuilder() { + } + + public static ConcurrentLongFloatMapBuilder newBuilder() { + return new ConcurrentLongFloatMapBuilder(); + } + + public ConcurrentLongFloatMapBuilder withDefaultValue(float defaultValue) { + this.defaultValue = defaultValue; + return this; + } + + @Override + public LongFloatMap build() { + return switch (mapMode) { + case BUSY_WAITING -> new ConcurrentBusyWaitingLongFloatMap( + this.buckets, + this.initialCapacity, + this.loadFactor, + this.defaultValue + ); + case BLOCKING -> new ConcurrentLongFloatMap( + this.buckets, + this.initialCapacity, + this.loadFactor, + this.defaultValue + ); + }; + } +} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/ConcurrentLongIntMapBuilder.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/ConcurrentLongIntMapBuilder.java new file mode 100644 index 0000000..87d5732 --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/ConcurrentLongIntMapBuilder.java @@ -0,0 +1,40 @@ +package com.trivago.fastutilconcurrentwrapper.primitivekeys; + +import com.trivago.fastutilconcurrentwrapper.ConcurrentMapBuilder; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentBusyWaitingLongIntMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentLongIntMap; + +public final class ConcurrentLongIntMapBuilder extends ConcurrentMapBuilder { + + private int defaultValue = LongIntMap.DEFAULT_VALUE; + + private ConcurrentLongIntMapBuilder() { + } + + public static ConcurrentLongIntMapBuilder newBuilder() { + return new ConcurrentLongIntMapBuilder(); + } + + public ConcurrentLongIntMapBuilder withDefaultValue(int defaultValue) { + this.defaultValue = defaultValue; + return this; + } + + @Override + public LongIntMap build() { + return switch (mapMode) { + case BUSY_WAITING -> new ConcurrentBusyWaitingLongIntMap( + this.buckets, + this.initialCapacity, + this.loadFactor, + this.defaultValue + ); + case BLOCKING -> new ConcurrentLongIntMap( + this.buckets, + this.initialCapacity, + this.loadFactor, + this.defaultValue + ); + }; + } +} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/ConcurrentLongLongMapBuilder.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/ConcurrentLongLongMapBuilder.java new file mode 100644 index 0000000..c39720b --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/ConcurrentLongLongMapBuilder.java @@ -0,0 +1,41 @@ +package com.trivago.fastutilconcurrentwrapper.primitivekeys; + +import com.trivago.fastutilconcurrentwrapper.ConcurrentMapBuilder; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentBusyWaitingLongLongMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentLongLongMap; + +public final class ConcurrentLongLongMapBuilder + extends ConcurrentMapBuilder { + + private long defaultValue = LongLongMap.DEFAULT_VALUE; + + private ConcurrentLongLongMapBuilder() { + } + + public static ConcurrentLongLongMapBuilder newBuilder() { + return new ConcurrentLongLongMapBuilder(); + } + + public ConcurrentLongLongMapBuilder withDefaultValue(long defaultValue) { + this.defaultValue = defaultValue; + return this; + } + + @Override + public LongLongMap build() { + return switch (mapMode) { + case BUSY_WAITING -> new ConcurrentBusyWaitingLongLongMap( + this.buckets, + this.initialCapacity, + this.loadFactor, + this.defaultValue + ); + case BLOCKING -> new ConcurrentLongLongMap( + this.buckets, + this.initialCapacity, + this.loadFactor, + this.defaultValue + ); + }; + } +} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/ConcurrentLongObjectMapBuilder.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/ConcurrentLongObjectMapBuilder.java new file mode 100644 index 0000000..40a91f6 --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/ConcurrentLongObjectMapBuilder.java @@ -0,0 +1,41 @@ +package com.trivago.fastutilconcurrentwrapper.primitivekeys; + +import com.trivago.fastutilconcurrentwrapper.ConcurrentMapBuilder; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentBusyWaitingLongObjectMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentLongObjectMap; + +public final class ConcurrentLongObjectMapBuilder + extends ConcurrentMapBuilder, LongObjectMap> { + + private V defaultValue = null; + + private ConcurrentLongObjectMapBuilder() { + } + + public static ConcurrentLongObjectMapBuilder newBuilder() { + return new ConcurrentLongObjectMapBuilder<>(); + } + + public ConcurrentLongObjectMapBuilder withDefaultValue(V defaultValue) { + this.defaultValue = defaultValue; + return this; + } + + @Override + public LongObjectMap build() { + return switch (mapMode) { + case BUSY_WAITING -> new ConcurrentBusyWaitingLongObjectMap<>( + this.buckets, + this.initialCapacity, + this.loadFactor, + this.defaultValue + ); + case BLOCKING -> new ConcurrentLongObjectMap<>( + this.buckets, + this.initialCapacity, + this.loadFactor, + this.defaultValue + ); + }; + } +} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/IntFloatMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/IntFloatMap.java similarity index 89% rename from src/main/java/com/trivago/fastutilconcurrentwrapper/IntFloatMap.java rename to src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/IntFloatMap.java index a46cb18..fcdd275 100644 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/IntFloatMap.java +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/IntFloatMap.java @@ -1,4 +1,4 @@ -package com.trivago.fastutilconcurrentwrapper; +package com.trivago.fastutilconcurrentwrapper.primitivekeys; import it.unimi.dsi.fastutil.ints.Int2FloatFunction; diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/IntIntMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/IntIntMap.java similarity index 90% rename from src/main/java/com/trivago/fastutilconcurrentwrapper/IntIntMap.java rename to src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/IntIntMap.java index 446c7db..cc0505e 100644 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/IntIntMap.java +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/IntIntMap.java @@ -1,4 +1,4 @@ -package com.trivago.fastutilconcurrentwrapper; +package com.trivago.fastutilconcurrentwrapper.primitivekeys; import it.unimi.dsi.fastutil.ints.Int2IntFunction; diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/IntObjectMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/IntObjectMap.java new file mode 100644 index 0000000..59d88b9 --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/IntObjectMap.java @@ -0,0 +1,22 @@ +package com.trivago.fastutilconcurrentwrapper.primitivekeys; + +import it.unimi.dsi.fastutil.ints.Int2ObjectFunction; + +import java.util.function.BiFunction; + +public interface IntObjectMap extends PrimitiveIntKeyMap { + + V get(int key); + + V put(int key, V value); + + V getDefaultValue(); + + V remove(int key); + + boolean remove(int key, V value); + + V computeIfAbsent(int key, Int2ObjectFunction mappingFunction); + + V computeIfPresent(int key, BiFunction mappingFunction); +} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/LongFloatMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/LongFloatMap.java similarity index 92% rename from src/main/java/com/trivago/fastutilconcurrentwrapper/LongFloatMap.java rename to src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/LongFloatMap.java index 83be062..6ab927d 100644 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/LongFloatMap.java +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/LongFloatMap.java @@ -1,4 +1,4 @@ -package com.trivago.fastutilconcurrentwrapper; +package com.trivago.fastutilconcurrentwrapper.primitivekeys; import it.unimi.dsi.fastutil.longs.Long2FloatFunction; diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/LongIntMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/LongIntMap.java similarity index 91% rename from src/main/java/com/trivago/fastutilconcurrentwrapper/LongIntMap.java rename to src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/LongIntMap.java index 59a2474..65e42f1 100644 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/LongIntMap.java +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/LongIntMap.java @@ -1,4 +1,4 @@ -package com.trivago.fastutilconcurrentwrapper; +package com.trivago.fastutilconcurrentwrapper.primitivekeys; import it.unimi.dsi.fastutil.longs.Long2IntFunction; diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/LongLongMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/LongLongMap.java similarity index 90% rename from src/main/java/com/trivago/fastutilconcurrentwrapper/LongLongMap.java rename to src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/LongLongMap.java index d8b1fe6..5bff3aa 100644 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/LongLongMap.java +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/LongLongMap.java @@ -1,4 +1,4 @@ -package com.trivago.fastutilconcurrentwrapper; +package com.trivago.fastutilconcurrentwrapper.primitivekeys; import it.unimi.dsi.fastutil.longs.Long2LongFunction; diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/LongObjectMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/LongObjectMap.java new file mode 100644 index 0000000..057addd --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/LongObjectMap.java @@ -0,0 +1,22 @@ +package com.trivago.fastutilconcurrentwrapper.primitivekeys; + +import it.unimi.dsi.fastutil.longs.Long2ObjectFunction; + +import java.util.function.BiFunction; + +public interface LongObjectMap extends PrimitiveLongKeyMap { + + V get(long key); + + V put(long key, V value); + + V getDefaultValue(); + + V remove(long key); + + boolean remove(long key, V value); + + V computeIfAbsent(long key, Long2ObjectFunction mappingFunction); + + V computeIfPresent(long key, BiFunction mappingFunction); +} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/PrimitiveIntKeyMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/PrimitiveIntKeyMap.java new file mode 100644 index 0000000..1244bd8 --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/PrimitiveIntKeyMap.java @@ -0,0 +1,7 @@ +package com.trivago.fastutilconcurrentwrapper.primitivekeys; + +import com.trivago.fastutilconcurrentwrapper.KeyMap; + +public interface PrimitiveIntKeyMap extends KeyMap { + boolean containsKey(int key); +} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/PrimitiveLongKeyMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/PrimitiveLongKeyMap.java new file mode 100644 index 0000000..754362e --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/PrimitiveLongKeyMap.java @@ -0,0 +1,7 @@ +package com.trivago.fastutilconcurrentwrapper.primitivekeys; + +import com.trivago.fastutilconcurrentwrapper.KeyMap; + +public interface PrimitiveLongKeyMap extends KeyMap { + boolean containsKey(long key); +} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentBusyWaitingIntFloatMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentBusyWaitingIntFloatMap.java similarity index 94% rename from src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentBusyWaitingIntFloatMap.java rename to src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentBusyWaitingIntFloatMap.java index b751f66..8a292a7 100644 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentBusyWaitingIntFloatMap.java +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentBusyWaitingIntFloatMap.java @@ -1,7 +1,7 @@ -package com.trivago.fastutilconcurrentwrapper.map; +package com.trivago.fastutilconcurrentwrapper.primitivekeys.map; -import com.trivago.fastutilconcurrentwrapper.IntFloatMap; -import com.trivago.fastutilconcurrentwrapper.wrapper.PrimitiveFastutilIntFloatWrapper; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.IntFloatMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.wrapper.PrimitiveFastutilIntFloatWrapper; import it.unimi.dsi.fastutil.ints.Int2FloatFunction; import java.util.concurrent.locks.Lock; diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentBusyWaitingIntIntMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentBusyWaitingIntIntMap.java similarity index 94% rename from src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentBusyWaitingIntIntMap.java rename to src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentBusyWaitingIntIntMap.java index b4c5447..c748c49 100644 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentBusyWaitingIntIntMap.java +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentBusyWaitingIntIntMap.java @@ -1,7 +1,7 @@ -package com.trivago.fastutilconcurrentwrapper.map; +package com.trivago.fastutilconcurrentwrapper.primitivekeys.map; -import com.trivago.fastutilconcurrentwrapper.IntIntMap; -import com.trivago.fastutilconcurrentwrapper.wrapper.PrimitiveFastutilIntIntWrapper; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.IntIntMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.wrapper.PrimitiveFastutilIntIntWrapper; import it.unimi.dsi.fastutil.ints.Int2IntFunction; import java.util.concurrent.locks.Lock; diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentBusyWaitingIntObjectMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentBusyWaitingIntObjectMap.java new file mode 100644 index 0000000..0ac480b --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentBusyWaitingIntObjectMap.java @@ -0,0 +1,160 @@ +package com.trivago.fastutilconcurrentwrapper.primitivekeys.map; + +import com.trivago.fastutilconcurrentwrapper.primitivekeys.IntObjectMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.wrapper.PrimitiveFastutilIntObjectWrapper; +import it.unimi.dsi.fastutil.ints.Int2ObjectFunction; + +import java.util.concurrent.locks.Lock; +import java.util.function.BiFunction; + +public class ConcurrentBusyWaitingIntObjectMap extends PrimitiveConcurrentMap implements IntObjectMap { + + private final IntObjectMap[] maps; + private final V defaultValue; + + public ConcurrentBusyWaitingIntObjectMap(int numBuckets, int initialCapacity, float loadFactor, V defaultValue) { + super(numBuckets); + + //noinspection unchecked + this.maps = new IntObjectMap[numBuckets]; + this.defaultValue = defaultValue; + + for (int i = 0; i < numBuckets; i++) { + maps[i] = new PrimitiveFastutilIntObjectWrapper<>(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 V 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 V put(int key, V 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 V getDefaultValue() { + return defaultValue; + } + + @Override + public V 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, V 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 V computeIfAbsent(int key, Int2ObjectFunction 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 V 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/ConcurrentBusyWaitingLongFloatMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentBusyWaitingLongFloatMap.java similarity index 94% rename from src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentBusyWaitingLongFloatMap.java rename to src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentBusyWaitingLongFloatMap.java index 4f68212..2a517da 100644 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentBusyWaitingLongFloatMap.java +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentBusyWaitingLongFloatMap.java @@ -1,7 +1,7 @@ -package com.trivago.fastutilconcurrentwrapper.map; +package com.trivago.fastutilconcurrentwrapper.primitivekeys.map; -import com.trivago.fastutilconcurrentwrapper.LongFloatMap; -import com.trivago.fastutilconcurrentwrapper.wrapper.PrimitiveFastutilLongFloatWrapper; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongFloatMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.wrapper.PrimitiveFastutilLongFloatWrapper; import it.unimi.dsi.fastutil.longs.Long2FloatFunction; import java.util.concurrent.locks.Lock; diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentBusyWaitingLongIntMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentBusyWaitingLongIntMap.java similarity index 91% rename from src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentBusyWaitingLongIntMap.java rename to src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentBusyWaitingLongIntMap.java index 9fdc732..350fc14 100644 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentBusyWaitingLongIntMap.java +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentBusyWaitingLongIntMap.java @@ -1,11 +1,8 @@ -package com.trivago.fastutilconcurrentwrapper.map; +package com.trivago.fastutilconcurrentwrapper.primitivekeys.map; -import com.trivago.fastutilconcurrentwrapper.LongIntMap; -import com.trivago.fastutilconcurrentwrapper.LongLongMap; -import com.trivago.fastutilconcurrentwrapper.wrapper.PrimitiveFastutilLongIntWrapper; -import com.trivago.fastutilconcurrentwrapper.wrapper.PrimitiveFastutilLongLongWrapper; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongIntMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.wrapper.PrimitiveFastutilLongIntWrapper; import it.unimi.dsi.fastutil.longs.Long2IntFunction; -import it.unimi.dsi.fastutil.longs.Long2LongFunction; import java.util.concurrent.locks.Lock; import java.util.function.BiFunction; diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentBusyWaitingLongLongMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentBusyWaitingLongLongMap.java similarity index 94% rename from src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentBusyWaitingLongLongMap.java rename to src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentBusyWaitingLongLongMap.java index 334207d..ae923fb 100644 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentBusyWaitingLongLongMap.java +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentBusyWaitingLongLongMap.java @@ -1,7 +1,7 @@ -package com.trivago.fastutilconcurrentwrapper.map; +package com.trivago.fastutilconcurrentwrapper.primitivekeys.map; -import com.trivago.fastutilconcurrentwrapper.LongLongMap; -import com.trivago.fastutilconcurrentwrapper.wrapper.PrimitiveFastutilLongLongWrapper; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongLongMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.wrapper.PrimitiveFastutilLongLongWrapper; import it.unimi.dsi.fastutil.longs.Long2LongFunction; import java.util.concurrent.locks.Lock; diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentBusyWaitingLongObjectMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentBusyWaitingLongObjectMap.java new file mode 100644 index 0000000..140c2e8 --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentBusyWaitingLongObjectMap.java @@ -0,0 +1,160 @@ +package com.trivago.fastutilconcurrentwrapper.primitivekeys.map; + +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongObjectMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.wrapper.PrimitiveFastutilLongObjectWrapper; +import it.unimi.dsi.fastutil.longs.Long2ObjectFunction; + +import java.util.concurrent.locks.Lock; +import java.util.function.BiFunction; + +public class ConcurrentBusyWaitingLongObjectMap extends PrimitiveConcurrentMap implements LongObjectMap { + + private final LongObjectMap[] maps; + private final V defaultValue; + + public ConcurrentBusyWaitingLongObjectMap(int numBuckets, int initialCapacity, float loadFactor, V defaultValue) { + super(numBuckets); + + //noinspection unchecked + this.maps = new LongObjectMap[numBuckets]; + this.defaultValue = defaultValue; + + for (int i = 0; i < numBuckets; i++) { + maps[i] = new PrimitiveFastutilLongObjectWrapper<>(initialCapacity, loadFactor, defaultValue); + } + } + + @Override + public int size() { + return super.size(maps); + } + + @Override + public boolean isEmpty() { + return super.isEmpty(maps); + } + + @Override + public boolean containsKey(long 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 V get(long 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 V put(long key, V 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 V getDefaultValue() { + return defaultValue; + } + + @Override + public V remove(long 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(long key, V 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 V computeIfAbsent(long key, Long2ObjectFunction 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 V computeIfPresent(long 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/ConcurrentIntFloatMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentIntFloatMap.java similarity index 93% rename from src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentIntFloatMap.java rename to src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentIntFloatMap.java index 831f9b6..e19f4de 100644 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentIntFloatMap.java +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentIntFloatMap.java @@ -1,7 +1,7 @@ -package com.trivago.fastutilconcurrentwrapper.map; +package com.trivago.fastutilconcurrentwrapper.primitivekeys.map; -import com.trivago.fastutilconcurrentwrapper.IntFloatMap; -import com.trivago.fastutilconcurrentwrapper.wrapper.PrimitiveFastutilIntFloatWrapper; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.IntFloatMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.wrapper.PrimitiveFastutilIntFloatWrapper; import it.unimi.dsi.fastutil.ints.Int2FloatFunction; import java.util.concurrent.locks.Lock; diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentIntIntMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentIntIntMap.java similarity index 93% rename from src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentIntIntMap.java rename to src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentIntIntMap.java index f737ae1..372e5ad 100644 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentIntIntMap.java +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentIntIntMap.java @@ -1,7 +1,7 @@ -package com.trivago.fastutilconcurrentwrapper.map; +package com.trivago.fastutilconcurrentwrapper.primitivekeys.map; -import com.trivago.fastutilconcurrentwrapper.IntIntMap; -import com.trivago.fastutilconcurrentwrapper.wrapper.PrimitiveFastutilIntIntWrapper; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.IntIntMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.wrapper.PrimitiveFastutilIntIntWrapper; import it.unimi.dsi.fastutil.ints.Int2IntFunction; import java.util.concurrent.locks.Lock; diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentIntObjectMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentIntObjectMap.java new file mode 100644 index 0000000..d01d662 --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentIntObjectMap.java @@ -0,0 +1,140 @@ +package com.trivago.fastutilconcurrentwrapper.primitivekeys.map; + +import com.trivago.fastutilconcurrentwrapper.primitivekeys.IntObjectMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.wrapper.PrimitiveFastutilIntObjectWrapper; +import it.unimi.dsi.fastutil.ints.Int2ObjectFunction; + +import java.util.concurrent.locks.Lock; +import java.util.function.BiFunction; + +public class ConcurrentIntObjectMap extends PrimitiveConcurrentMap implements IntObjectMap { + + private final IntObjectMap[] maps; + private final V defaultValue; + + public ConcurrentIntObjectMap(int numBuckets, int initialCapacity, float loadFactor, V defaultValue) { + super(numBuckets); + + //noinspection unchecked + this.maps = new IntObjectMap[numBuckets]; + this.defaultValue = defaultValue; + + for (int i = 0; i < numBuckets; i++) { + maps[i] = new PrimitiveFastutilIntObjectWrapper<>(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 V get(int l) { + int bucket = getBucket(l); + + V result; + + Lock readLock = locks[bucket].readLock(); + readLock.lock(); + try { + result = maps[bucket].get(l); + } finally { + readLock.unlock(); + } + + return result; + } + + @Override + public V put(int key, V value) { + int bucket = getBucket(key); + + V result; + + Lock writeLock = locks[bucket].writeLock(); + writeLock.lock(); + try { + result = maps[bucket].put(key, value); + } finally { + writeLock.unlock(); + } + + return result; + } + + @Override + public V getDefaultValue() { + return defaultValue; + } + + @Override + public V 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, V value) { + int bucket = getBucket(key); + + Lock writeLock = locks[bucket].writeLock(); + writeLock.lock(); + try { + return maps[bucket].remove(key, value); + } finally { + writeLock.unlock(); + } + } + + @Override + public V computeIfAbsent(int key, Int2ObjectFunction mappingFunction) { + int bucket = getBucket(key); + + Lock writeLock = locks[bucket].writeLock(); + writeLock.lock(); + try { + return maps[bucket].computeIfAbsent(key, mappingFunction); + } finally { + writeLock.unlock(); + } + } + + @Override + public V 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/map/ConcurrentLongFloatMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentLongFloatMap.java similarity index 93% rename from src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentLongFloatMap.java rename to src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentLongFloatMap.java index 9232f2e..934de8d 100644 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentLongFloatMap.java +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentLongFloatMap.java @@ -1,7 +1,7 @@ -package com.trivago.fastutilconcurrentwrapper.map; +package com.trivago.fastutilconcurrentwrapper.primitivekeys.map; -import com.trivago.fastutilconcurrentwrapper.LongFloatMap; -import com.trivago.fastutilconcurrentwrapper.wrapper.PrimitiveFastutilLongFloatWrapper; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongFloatMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.wrapper.PrimitiveFastutilLongFloatWrapper; import it.unimi.dsi.fastutil.longs.Long2FloatFunction; import java.util.concurrent.locks.Lock; diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentLongIntMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentLongIntMap.java similarity index 89% rename from src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentLongIntMap.java rename to src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentLongIntMap.java index 915096f..a2736eb 100644 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentLongIntMap.java +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentLongIntMap.java @@ -1,10 +1,7 @@ -package com.trivago.fastutilconcurrentwrapper.map; +package com.trivago.fastutilconcurrentwrapper.primitivekeys.map; -import com.trivago.fastutilconcurrentwrapper.IntIntMap; -import com.trivago.fastutilconcurrentwrapper.LongIntMap; -import com.trivago.fastutilconcurrentwrapper.wrapper.PrimitiveFastutilIntIntWrapper; -import com.trivago.fastutilconcurrentwrapper.wrapper.PrimitiveFastutilLongIntWrapper; -import it.unimi.dsi.fastutil.ints.Int2IntFunction; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongIntMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.wrapper.PrimitiveFastutilLongIntWrapper; import it.unimi.dsi.fastutil.longs.Long2IntFunction; import java.util.concurrent.locks.Lock; diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentLongLongMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentLongLongMap.java similarity index 93% rename from src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentLongLongMap.java rename to src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentLongLongMap.java index f69c3f2..51de9cb 100644 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentLongLongMap.java +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentLongLongMap.java @@ -1,7 +1,7 @@ -package com.trivago.fastutilconcurrentwrapper.map; +package com.trivago.fastutilconcurrentwrapper.primitivekeys.map; -import com.trivago.fastutilconcurrentwrapper.LongLongMap; -import com.trivago.fastutilconcurrentwrapper.wrapper.PrimitiveFastutilLongLongWrapper; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongLongMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.wrapper.PrimitiveFastutilLongLongWrapper; import it.unimi.dsi.fastutil.longs.Long2LongFunction; import java.util.concurrent.locks.Lock; diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentLongObjectMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentLongObjectMap.java new file mode 100644 index 0000000..e1054ea --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/ConcurrentLongObjectMap.java @@ -0,0 +1,140 @@ +package com.trivago.fastutilconcurrentwrapper.primitivekeys.map; + +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongObjectMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.wrapper.PrimitiveFastutilLongObjectWrapper; +import it.unimi.dsi.fastutil.longs.Long2ObjectFunction; + +import java.util.concurrent.locks.Lock; +import java.util.function.BiFunction; + +public class ConcurrentLongObjectMap extends PrimitiveConcurrentMap implements LongObjectMap { + + private final LongObjectMap[] maps; + private final V defaultValue; + + public ConcurrentLongObjectMap(int numBuckets, int initialCapacity, float loadFactor, V defaultValue) { + super(numBuckets); + + //noinspection unchecked + this.maps = new LongObjectMap[numBuckets]; + this.defaultValue = defaultValue; + + for (int i = 0; i < numBuckets; i++) { + maps[i] = new PrimitiveFastutilLongObjectWrapper<>(initialCapacity, loadFactor, defaultValue); + } + } + + @Override + public int size() { + return super.size(maps); + } + + @Override + public boolean isEmpty() { + return super.isEmpty(maps); + } + + @Override + public boolean containsKey(long key) { + int bucket = getBucket(key); + + Lock readLock = locks[bucket].readLock(); + readLock.lock(); + try { + return maps[bucket].containsKey(key); + } finally { + readLock.unlock(); + } + } + + @Override + public V get(long l) { + int bucket = getBucket(l); + + V result; + + Lock readLock = locks[bucket].readLock(); + readLock.lock(); + try { + result = maps[bucket].get(l); + } finally { + readLock.unlock(); + } + + return result; + } + + @Override + public V put(long key, V value) { + int bucket = getBucket(key); + + V result; + + Lock writeLock = locks[bucket].writeLock(); + writeLock.lock(); + try { + result = maps[bucket].put(key, value); + } finally { + writeLock.unlock(); + } + + return result; + } + + @Override + public V getDefaultValue() { + return defaultValue; + } + + @Override + public V remove(long 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(long key, V value) { + int bucket = getBucket(key); + + Lock writeLock = locks[bucket].writeLock(); + writeLock.lock(); + try { + return maps[bucket].remove(key, value); + } finally { + writeLock.unlock(); + } + } + + @Override + public V computeIfAbsent(long key, Long2ObjectFunction mappingFunction) { + int bucket = getBucket(key); + + Lock writeLock = locks[bucket].writeLock(); + writeLock.lock(); + try { + return maps[bucket].computeIfAbsent(key, mappingFunction); + } finally { + writeLock.unlock(); + } + } + + @Override + public V computeIfPresent(long 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/map/PrimitiveConcurrentMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/PrimitiveConcurrentMap.java similarity index 82% rename from src/main/java/com/trivago/fastutilconcurrentwrapper/map/PrimitiveConcurrentMap.java rename to src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/PrimitiveConcurrentMap.java index 68147e8..621cbfa 100644 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/map/PrimitiveConcurrentMap.java +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/map/PrimitiveConcurrentMap.java @@ -1,6 +1,6 @@ -package com.trivago.fastutilconcurrentwrapper.map; +package com.trivago.fastutilconcurrentwrapper.primitivekeys.map; -import com.trivago.fastutilconcurrentwrapper.PrimitiveKeyMap; +import com.trivago.fastutilconcurrentwrapper.KeyMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; @@ -19,7 +19,7 @@ protected PrimitiveConcurrentMap(int numBuckets) { } } - protected int size(PrimitiveKeyMap[] maps) { + protected int size(KeyMap[] maps) { int sum = 0; for (int i = 0; i < numBuckets; i++) { sum = sum + sizeOfMap(i, maps); @@ -27,7 +27,7 @@ protected int size(PrimitiveKeyMap[] maps) { return sum; } - private int sizeOfMap(int index, PrimitiveKeyMap[] maps) { + private int sizeOfMap(int index, KeyMap[] maps) { Lock readLock = locks[index].readLock(); readLock.lock(); try { @@ -37,7 +37,7 @@ private int sizeOfMap(int index, PrimitiveKeyMap[] maps) { } } - protected boolean isEmpty(PrimitiveKeyMap[] maps) { + protected boolean isEmpty(KeyMap[] maps) { for (int i = 0; i < numBuckets; i++) { if (!isMapEmpty(i, maps)) { return false; @@ -46,7 +46,7 @@ protected boolean isEmpty(PrimitiveKeyMap[] maps) { return true; } - private boolean isMapEmpty(int index, PrimitiveKeyMap[] maps) { + private boolean isMapEmpty(int index, KeyMap[] maps) { Lock readLock = locks[index].readLock(); readLock.lock(); try { diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/wrapper/PrimitiveFastutilIntFloatWrapper.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/wrapper/PrimitiveFastutilIntFloatWrapper.java similarity index 91% rename from src/main/java/com/trivago/fastutilconcurrentwrapper/wrapper/PrimitiveFastutilIntFloatWrapper.java rename to src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/wrapper/PrimitiveFastutilIntFloatWrapper.java index 34b17aa..72b1a67 100644 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/wrapper/PrimitiveFastutilIntFloatWrapper.java +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/wrapper/PrimitiveFastutilIntFloatWrapper.java @@ -1,6 +1,6 @@ -package com.trivago.fastutilconcurrentwrapper.wrapper; +package com.trivago.fastutilconcurrentwrapper.primitivekeys.wrapper; -import com.trivago.fastutilconcurrentwrapper.IntFloatMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.IntFloatMap; import it.unimi.dsi.fastutil.ints.Int2FloatFunction; import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap; diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/wrapper/PrimitiveFastutilIntIntWrapper.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/wrapper/PrimitiveFastutilIntIntWrapper.java similarity index 91% rename from src/main/java/com/trivago/fastutilconcurrentwrapper/wrapper/PrimitiveFastutilIntIntWrapper.java rename to src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/wrapper/PrimitiveFastutilIntIntWrapper.java index 5e01f17..c0246f5 100644 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/wrapper/PrimitiveFastutilIntIntWrapper.java +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/wrapper/PrimitiveFastutilIntIntWrapper.java @@ -1,6 +1,6 @@ -package com.trivago.fastutilconcurrentwrapper.wrapper; +package com.trivago.fastutilconcurrentwrapper.primitivekeys.wrapper; -import com.trivago.fastutilconcurrentwrapper.IntIntMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.IntIntMap; import it.unimi.dsi.fastutil.ints.Int2IntFunction; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/wrapper/PrimitiveFastutilIntObjectWrapper.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/wrapper/PrimitiveFastutilIntObjectWrapper.java new file mode 100644 index 0000000..0c358f4 --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/wrapper/PrimitiveFastutilIntObjectWrapper.java @@ -0,0 +1,67 @@ +package com.trivago.fastutilconcurrentwrapper.primitivekeys.wrapper; + +import com.trivago.fastutilconcurrentwrapper.primitivekeys.IntObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectFunction; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; + +import java.util.function.BiFunction; + +public class PrimitiveFastutilIntObjectWrapper implements IntObjectMap { + private final V defaultValue; + private final Int2ObjectOpenHashMap map; + + public PrimitiveFastutilIntObjectWrapper(int initialCapacity, float loadFactor, V defaultValue) { + this.defaultValue = defaultValue; + this.map = new Int2ObjectOpenHashMap<>(initialCapacity, loadFactor); + } + + @Override + public V get(int key) { + return map.getOrDefault(key, defaultValue); + } + + @Override + public V put(int key, V value) { + return map.put(key, value); + } + + @Override + public V getDefaultValue() { + return defaultValue; + } + + @Override + public V remove(int key) { + return map.remove(key); + } + + @Override + public boolean remove(int key, V 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 V computeIfAbsent(int key, Int2ObjectFunction mappingFunction) { + return map.computeIfAbsent(key, mappingFunction); + } + + @Override + public V computeIfPresent(int key, BiFunction mappingFunction) { + return map.computeIfPresent(key, mappingFunction); + } +} diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/wrapper/PrimitiveFastutilLongFloatWrapper.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/wrapper/PrimitiveFastutilLongFloatWrapper.java similarity index 91% rename from src/main/java/com/trivago/fastutilconcurrentwrapper/wrapper/PrimitiveFastutilLongFloatWrapper.java rename to src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/wrapper/PrimitiveFastutilLongFloatWrapper.java index bf99b6d..e317ce9 100644 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/wrapper/PrimitiveFastutilLongFloatWrapper.java +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/wrapper/PrimitiveFastutilLongFloatWrapper.java @@ -1,6 +1,6 @@ -package com.trivago.fastutilconcurrentwrapper.wrapper; +package com.trivago.fastutilconcurrentwrapper.primitivekeys.wrapper; -import com.trivago.fastutilconcurrentwrapper.LongFloatMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongFloatMap; import it.unimi.dsi.fastutil.longs.Long2FloatFunction; import it.unimi.dsi.fastutil.longs.Long2FloatOpenHashMap; diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/wrapper/PrimitiveFastutilLongIntWrapper.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/wrapper/PrimitiveFastutilLongIntWrapper.java similarity index 86% rename from src/main/java/com/trivago/fastutilconcurrentwrapper/wrapper/PrimitiveFastutilLongIntWrapper.java rename to src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/wrapper/PrimitiveFastutilLongIntWrapper.java index 5b33508..f4cbb6a 100644 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/wrapper/PrimitiveFastutilLongIntWrapper.java +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/wrapper/PrimitiveFastutilLongIntWrapper.java @@ -1,11 +1,8 @@ -package com.trivago.fastutilconcurrentwrapper.wrapper; +package com.trivago.fastutilconcurrentwrapper.primitivekeys.wrapper; -import com.trivago.fastutilconcurrentwrapper.LongIntMap; -import com.trivago.fastutilconcurrentwrapper.LongLongMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongIntMap; import it.unimi.dsi.fastutil.longs.Long2IntFunction; import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap; -import it.unimi.dsi.fastutil.longs.Long2LongFunction; -import it.unimi.dsi.fastutil.longs.Long2LongOpenHashMap; import java.util.function.BiFunction; diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/wrapper/PrimitiveFastutilLongLongWrapper.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/wrapper/PrimitiveFastutilLongLongWrapper.java similarity index 92% rename from src/main/java/com/trivago/fastutilconcurrentwrapper/wrapper/PrimitiveFastutilLongLongWrapper.java rename to src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/wrapper/PrimitiveFastutilLongLongWrapper.java index 1f446a7..438657b 100644 --- a/src/main/java/com/trivago/fastutilconcurrentwrapper/wrapper/PrimitiveFastutilLongLongWrapper.java +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/wrapper/PrimitiveFastutilLongLongWrapper.java @@ -1,6 +1,6 @@ -package com.trivago.fastutilconcurrentwrapper.wrapper; +package com.trivago.fastutilconcurrentwrapper.primitivekeys.wrapper; -import com.trivago.fastutilconcurrentwrapper.LongLongMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongLongMap; import it.unimi.dsi.fastutil.longs.Long2LongFunction; import it.unimi.dsi.fastutil.longs.Long2LongOpenHashMap; diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/wrapper/PrimitiveFastutilLongObjectWrapper.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/wrapper/PrimitiveFastutilLongObjectWrapper.java new file mode 100644 index 0000000..af2b3ea --- /dev/null +++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/primitivekeys/wrapper/PrimitiveFastutilLongObjectWrapper.java @@ -0,0 +1,71 @@ +package com.trivago.fastutilconcurrentwrapper.primitivekeys.wrapper; + +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectFunction; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; + +import java.util.function.BiFunction; + +public class PrimitiveFastutilLongObjectWrapper implements LongObjectMap { + private final Long2ObjectOpenHashMap map; + private final V defaultValue; + + public PrimitiveFastutilLongObjectWrapper(int initialCapacity, float loadFactor) { + this(initialCapacity, loadFactor, null); + } + + public PrimitiveFastutilLongObjectWrapper(int initialCapacity, float loadFactor, V defaultValue) { + this.defaultValue = defaultValue; + this.map = new Long2ObjectOpenHashMap<>(initialCapacity, loadFactor); + } + + @Override + public V get(long key) { + return map.getOrDefault(key, defaultValue); + } + + @Override + public V put(long key, V value) { + return map.put(key, value); + } + + @Override + public V getDefaultValue() { + return defaultValue; + } + + @Override + public V remove(long key) { + return map.remove(key); + } + + @Override + public boolean remove(long key, V value) { + return map.remove(key, value); + } + + @Override + public int size() { + return map.size(); + } + + @Override + public boolean containsKey(long key) { + return map.containsKey(key); + } + + @Override + public boolean isEmpty() { + return map.isEmpty(); + } + + @Override + public V computeIfAbsent(long key, Long2ObjectFunction mappingFunction) { + return map.computeIfAbsent(key, mappingFunction); + } + + @Override + public V computeIfPresent(long key, BiFunction mappingFunction) { + return map.computeIfPresent(key, mappingFunction); + } +} diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/AbstractMapTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/AbstractMapTest.java index 081448e..da55de8 100644 --- a/src/test/java/com/trivago/fastutilconcurrentwrapper/AbstractMapTest.java +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/AbstractMapTest.java @@ -17,6 +17,10 @@ protected static int nextInt() { return ThreadLocalRandom.current().nextInt(); } + protected static ObjectKey nextObject() { + return new ObjectKey(); + } + @Test protected abstract void containsKeyReturnsFalseIfMapIsEmpty(); @@ -67,4 +71,15 @@ protected static int nextInt() { @Test protected abstract void checkingValueIfNotPresentReturnsDefaultValue(); + + public static class ObjectKey { + + private final int number = nextInt(); + + @Override + public int hashCode() { + return Integer.hashCode(number); + } + + } } diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentIntFloatMapBuilderTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentIntFloatMapBuilderTest.java index 4bf6e9b..efe260b 100644 --- a/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentIntFloatMapBuilderTest.java +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentIntFloatMapBuilderTest.java @@ -1,7 +1,9 @@ package com.trivago.fastutilconcurrentwrapper; -import com.trivago.fastutilconcurrentwrapper.map.ConcurrentBusyWaitingIntFloatMap; -import com.trivago.fastutilconcurrentwrapper.map.ConcurrentIntFloatMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.ConcurrentIntFloatMapBuilder; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.IntFloatMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentBusyWaitingIntFloatMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentIntFloatMap; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentIntIntMapBuilderTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentIntIntMapBuilderTest.java index f66c63b..c1c579a 100644 --- a/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentIntIntMapBuilderTest.java +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentIntIntMapBuilderTest.java @@ -1,7 +1,9 @@ package com.trivago.fastutilconcurrentwrapper; -import com.trivago.fastutilconcurrentwrapper.map.ConcurrentBusyWaitingIntIntMap; -import com.trivago.fastutilconcurrentwrapper.map.ConcurrentIntIntMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.ConcurrentIntIntMapBuilder; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.IntIntMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentBusyWaitingIntIntMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentIntIntMap; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentLongFloatMapBuilderTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentLongFloatMapBuilderTest.java index 1956cf2..b272631 100644 --- a/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentLongFloatMapBuilderTest.java +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentLongFloatMapBuilderTest.java @@ -1,7 +1,9 @@ package com.trivago.fastutilconcurrentwrapper; -import com.trivago.fastutilconcurrentwrapper.map.ConcurrentBusyWaitingLongFloatMap; -import com.trivago.fastutilconcurrentwrapper.map.ConcurrentLongFloatMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.ConcurrentLongFloatMapBuilder; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongFloatMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentBusyWaitingLongFloatMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentLongFloatMap; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentLongIntMapBuilderTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentLongIntMapBuilderTest.java index 33ef050..e3054a3 100644 --- a/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentLongIntMapBuilderTest.java +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentLongIntMapBuilderTest.java @@ -1,7 +1,9 @@ package com.trivago.fastutilconcurrentwrapper; -import com.trivago.fastutilconcurrentwrapper.map.ConcurrentBusyWaitingLongIntMap; -import com.trivago.fastutilconcurrentwrapper.map.ConcurrentLongIntMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.ConcurrentLongIntMapBuilder; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongIntMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentBusyWaitingLongIntMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentLongIntMap; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentLongLongMapBuilderTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentLongLongMapBuilderTest.java index 11d506a..d9909e9 100644 --- a/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentLongLongMapBuilderTest.java +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentLongLongMapBuilderTest.java @@ -1,7 +1,9 @@ package com.trivago.fastutilconcurrentwrapper; -import com.trivago.fastutilconcurrentwrapper.map.ConcurrentBusyWaitingLongLongMap; -import com.trivago.fastutilconcurrentwrapper.map.ConcurrentLongLongMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.ConcurrentLongLongMapBuilder; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongLongMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentBusyWaitingLongLongMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentLongLongMap; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentObjectFloatMapBuilderTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentObjectFloatMapBuilderTest.java new file mode 100644 index 0000000..65f76bd --- /dev/null +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentObjectFloatMapBuilderTest.java @@ -0,0 +1,55 @@ +package com.trivago.fastutilconcurrentwrapper; + +import com.trivago.fastutilconcurrentwrapper.objectkeys.ConcurrentObjectFloatMapBuilder; +import com.trivago.fastutilconcurrentwrapper.objectkeys.ObjectFloatMap; +import com.trivago.fastutilconcurrentwrapper.objectkeys.map.ConcurrentBusyWaitingObjectFloatMap; +import com.trivago.fastutilconcurrentwrapper.objectkeys.map.ConcurrentObjectFloatMap; +import org.junit.jupiter.api.Test; + +import static com.trivago.fastutilconcurrentwrapper.AbstractMapTest.nextObject; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; + +public class ConcurrentObjectFloatMapBuilderTest { + private final float DEFAULT_VALUE = -1; + + @Test + public void simpleBuilderTest() { + ConcurrentObjectFloatMapBuilder b = ConcurrentObjectFloatMapBuilder.newBuilder() + .withBuckets(2) + .withDefaultValue(DEFAULT_VALUE) + .withInitialCapacity(100) + .withMode(ConcurrentMapBuilder.MapMode.BUSY_WAITING) + .withLoadFactor(0.9f); + + ObjectFloatMap map = b.build(); + + AbstractMapTest.ObjectKey key = nextObject(); + map.put(key, 10F); + float v = map.get(key); + + assertInstanceOf(ConcurrentBusyWaitingObjectFloatMap.class, map); + assertEquals(10F, v); + assertEquals(map.get(nextObject()), map.getDefaultValue()); + } + + @Test + public void buildsBlockingMap() { + ConcurrentObjectFloatMapBuilder b = ConcurrentObjectFloatMapBuilder.newBuilder() + .withBuckets(2) + .withDefaultValue(DEFAULT_VALUE) + .withInitialCapacity(100) + .withMode(ConcurrentMapBuilder.MapMode.BLOCKING) + .withLoadFactor(0.9f); + + ObjectFloatMap map = b.build(); + + AbstractMapTest.ObjectKey key = nextObject(); + map.put(key, 10F); + float v = map.get(key); + + assertInstanceOf(ConcurrentObjectFloatMap.class, map); + assertEquals(10F, v); + assertEquals(map.get(nextObject()), map.getDefaultValue()); + } +} diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentObjectIntMapBuilderTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentObjectIntMapBuilderTest.java new file mode 100644 index 0000000..5e5fc78 --- /dev/null +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentObjectIntMapBuilderTest.java @@ -0,0 +1,54 @@ +package com.trivago.fastutilconcurrentwrapper; + +import com.trivago.fastutilconcurrentwrapper.objectkeys.ConcurrentObjectIntMapBuilder; +import com.trivago.fastutilconcurrentwrapper.objectkeys.ObjectIntMap; +import com.trivago.fastutilconcurrentwrapper.objectkeys.map.ConcurrentBusyWaitingObjectIntMap; +import com.trivago.fastutilconcurrentwrapper.objectkeys.map.ConcurrentObjectIntMap; +import org.junit.jupiter.api.Test; + +import static com.trivago.fastutilconcurrentwrapper.AbstractMapTest.nextObject; +import static org.junit.jupiter.api.Assertions.*; + +public class ConcurrentObjectIntMapBuilderTest { + private final int DEFAULT_VALUE = -1; + + @Test + public void simpleBuilderTest() { + ConcurrentObjectIntMapBuilder b = ConcurrentObjectIntMapBuilder.newBuilder() + .withBuckets(2) + .withDefaultValue(DEFAULT_VALUE) + .withInitialCapacity(100) + .withMode(ConcurrentMapBuilder.MapMode.BUSY_WAITING) + .withLoadFactor(0.9f); + + ObjectIntMap map = b.build(); + + AbstractMapTest.ObjectKey key = nextObject(); + map.put(key, 10); + int v = map.get(key); + + assertInstanceOf(ConcurrentBusyWaitingObjectIntMap.class, map); + assertEquals(10, v); + assertEquals(map.get(nextObject()), map.getDefaultValue()); + } + + @Test + public void buildsBlockingMap() { + ConcurrentObjectIntMapBuilder b = ConcurrentObjectIntMapBuilder.newBuilder() + .withBuckets(2) + .withDefaultValue(DEFAULT_VALUE) + .withInitialCapacity(100) + .withMode(ConcurrentMapBuilder.MapMode.BLOCKING) + .withLoadFactor(0.9f); + + ObjectIntMap map = b.build(); + + AbstractMapTest.ObjectKey key = nextObject(); + map.put(key, 10); + int v = map.get(key); + + assertInstanceOf(ConcurrentObjectIntMap.class, map); + assertEquals(10, v); + assertEquals(map.get(nextObject()), map.getDefaultValue()); + } +} diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentObjectLongMapBuilderTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentObjectLongMapBuilderTest.java new file mode 100644 index 0000000..99e262b --- /dev/null +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/ConcurrentObjectLongMapBuilderTest.java @@ -0,0 +1,54 @@ +package com.trivago.fastutilconcurrentwrapper; + +import com.trivago.fastutilconcurrentwrapper.objectkeys.ConcurrentObjectLongMapBuilder; +import com.trivago.fastutilconcurrentwrapper.objectkeys.ObjectLongMap; +import com.trivago.fastutilconcurrentwrapper.objectkeys.map.ConcurrentBusyWaitingObjectLongMap; +import com.trivago.fastutilconcurrentwrapper.objectkeys.map.ConcurrentObjectLongMap; +import org.junit.jupiter.api.Test; + +import static com.trivago.fastutilconcurrentwrapper.AbstractMapTest.nextObject; +import static org.junit.jupiter.api.Assertions.*; + +public class ConcurrentObjectLongMapBuilderTest { + private final long DEFAULT_VALUE = -1L; + + @Test + public void simpleBuilderTest() { + ConcurrentObjectLongMapBuilder b = ConcurrentObjectLongMapBuilder.newBuilder() + .withBuckets(2) + .withDefaultValue(DEFAULT_VALUE) + .withInitialCapacity(100) + .withMode(ConcurrentMapBuilder.MapMode.BUSY_WAITING) + .withLoadFactor(0.9f); + + ObjectLongMap map = b.build(); + + AbstractMapTest.ObjectKey key = nextObject(); + map.put(key, 10L); + long v = map.get(key); + + assertInstanceOf(ConcurrentBusyWaitingObjectLongMap.class, map); + assertEquals(10L, v); + assertEquals(map.get(nextObject()), map.getDefaultValue()); + } + + @Test + public void buildsBlockingMap() { + ConcurrentObjectLongMapBuilder b = ConcurrentObjectLongMapBuilder.newBuilder() + .withBuckets(2) + .withDefaultValue(DEFAULT_VALUE) + .withInitialCapacity(100) + .withMode(ConcurrentMapBuilder.MapMode.BLOCKING) + .withLoadFactor(0.9f); + + ObjectLongMap map = b.build(); + + AbstractMapTest.ObjectKey key = nextObject(); + map.put(key, 10L); + long v = map.get(key); + + assertInstanceOf(ConcurrentObjectLongMap.class, map); + assertEquals(10L, v); + assertEquals(map.get(nextObject()), map.getDefaultValue()); + } +} diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/longint/AbstractLongIntMapTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/longint/AbstractLongIntMapTest.java index ce42f0c..769cb89 100644 --- a/src/test/java/com/trivago/fastutilconcurrentwrapper/longint/AbstractLongIntMapTest.java +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/longint/AbstractLongIntMapTest.java @@ -1,7 +1,7 @@ package com.trivago.fastutilconcurrentwrapper.longint; import com.trivago.fastutilconcurrentwrapper.AbstractMapTest; -import com.trivago.fastutilconcurrentwrapper.LongIntMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongIntMap; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/longint/ConcurrentBusyWaitingLongIntMapTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/longint/ConcurrentBusyWaitingLongIntMapTest.java index 471b17f..4891ff8 100644 --- a/src/test/java/com/trivago/fastutilconcurrentwrapper/longint/ConcurrentBusyWaitingLongIntMapTest.java +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/longint/ConcurrentBusyWaitingLongIntMapTest.java @@ -1,7 +1,7 @@ package com.trivago.fastutilconcurrentwrapper.longint; -import com.trivago.fastutilconcurrentwrapper.LongIntMap; -import com.trivago.fastutilconcurrentwrapper.map.ConcurrentBusyWaitingLongIntMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongIntMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentBusyWaitingLongIntMap; public class ConcurrentBusyWaitingLongIntMapTest extends AbstractLongIntMapTest { diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/longint/ConcurrentPrimitiveLongIntMapTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/longint/ConcurrentPrimitiveLongIntMapTest.java index 0046d77..2a675f3 100644 --- a/src/test/java/com/trivago/fastutilconcurrentwrapper/longint/ConcurrentPrimitiveLongIntMapTest.java +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/longint/ConcurrentPrimitiveLongIntMapTest.java @@ -1,7 +1,7 @@ package com.trivago.fastutilconcurrentwrapper.longint; -import com.trivago.fastutilconcurrentwrapper.LongIntMap; -import com.trivago.fastutilconcurrentwrapper.map.ConcurrentLongIntMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongIntMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentLongIntMap; public class ConcurrentPrimitiveLongIntMapTest extends AbstractLongIntMapTest { diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/longint/PrimitiveFastutilLongIntWrapperTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/longint/PrimitiveFastutilLongIntWrapperTest.java index 439b498..0aa3994 100644 --- a/src/test/java/com/trivago/fastutilconcurrentwrapper/longint/PrimitiveFastutilLongIntWrapperTest.java +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/longint/PrimitiveFastutilLongIntWrapperTest.java @@ -1,7 +1,7 @@ package com.trivago.fastutilconcurrentwrapper.longint; -import com.trivago.fastutilconcurrentwrapper.LongIntMap; -import com.trivago.fastutilconcurrentwrapper.wrapper.PrimitiveFastutilLongIntWrapper; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongIntMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.wrapper.PrimitiveFastutilLongIntWrapper; public class PrimitiveFastutilLongIntWrapperTest extends AbstractLongIntMapTest { diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/longlong/AbstractLongLongMapTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/longlong/AbstractLongLongMapTest.java index a394bc9..f83798e 100644 --- a/src/test/java/com/trivago/fastutilconcurrentwrapper/longlong/AbstractLongLongMapTest.java +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/longlong/AbstractLongLongMapTest.java @@ -1,7 +1,7 @@ package com.trivago.fastutilconcurrentwrapper.longlong; import com.trivago.fastutilconcurrentwrapper.AbstractMapTest; -import com.trivago.fastutilconcurrentwrapper.LongLongMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongLongMap; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/longlong/ConcurrentBusyWaitingLongLongMapTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/longlong/ConcurrentBusyWaitingLongLongMapTest.java index 87c55f3..2a905c7 100644 --- a/src/test/java/com/trivago/fastutilconcurrentwrapper/longlong/ConcurrentBusyWaitingLongLongMapTest.java +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/longlong/ConcurrentBusyWaitingLongLongMapTest.java @@ -1,7 +1,7 @@ package com.trivago.fastutilconcurrentwrapper.longlong; -import com.trivago.fastutilconcurrentwrapper.LongLongMap; -import com.trivago.fastutilconcurrentwrapper.map.ConcurrentBusyWaitingLongLongMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongLongMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentBusyWaitingLongLongMap; public class ConcurrentBusyWaitingLongLongMapTest extends AbstractLongLongMapTest { diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/longlong/ConcurrentLongLongMapTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/longlong/ConcurrentLongLongMapTest.java index 32830be..51ac591 100644 --- a/src/test/java/com/trivago/fastutilconcurrentwrapper/longlong/ConcurrentLongLongMapTest.java +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/longlong/ConcurrentLongLongMapTest.java @@ -1,7 +1,7 @@ package com.trivago.fastutilconcurrentwrapper.longlong; -import com.trivago.fastutilconcurrentwrapper.LongLongMap; -import com.trivago.fastutilconcurrentwrapper.map.ConcurrentLongLongMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongLongMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentLongLongMap; public class ConcurrentLongLongMapTest extends AbstractLongLongMapTest { diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/longlong/PrimitiveFastutilLongLongWrapperTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/longlong/PrimitiveFastutilLongLongWrapperTest.java index 7fa601a..3d1cfea 100644 --- a/src/test/java/com/trivago/fastutilconcurrentwrapper/longlong/PrimitiveFastutilLongLongWrapperTest.java +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/longlong/PrimitiveFastutilLongLongWrapperTest.java @@ -1,7 +1,7 @@ package com.trivago.fastutilconcurrentwrapper.longlong; -import com.trivago.fastutilconcurrentwrapper.LongLongMap; -import com.trivago.fastutilconcurrentwrapper.wrapper.PrimitiveFastutilLongLongWrapper; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongLongMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.wrapper.PrimitiveFastutilLongLongWrapper; public class PrimitiveFastutilLongLongWrapperTest extends AbstractLongLongMapTest { diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/longobject/AbstractLongObjectMapTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/longobject/AbstractLongObjectMapTest.java new file mode 100644 index 0000000..d61a3b0 --- /dev/null +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/longobject/AbstractLongObjectMapTest.java @@ -0,0 +1,209 @@ +package com.trivago.fastutilconcurrentwrapper.longobject; + +import com.trivago.fastutilconcurrentwrapper.AbstractMapTest; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongIntMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongObjectMap; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +abstract class AbstractLongObjectMapTest extends AbstractMapTest { + + protected ObjectKey defaultValue; + private LongObjectMap map; + // Keep the default value to easily verify that this value is returned. + + abstract LongObjectMap createMap(); + + @BeforeEach + void initializeMap() { + defaultValue = nextObject(); + 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(); + ObjectKey value = nextObject(); + map.put(key, value); + + final boolean contains = map.containsKey(key); + + assertTrue(contains); + } + + @Test + protected void containsKeyReturnsFalseIfKeyWasRemoved() { + int key = nextInt(); + ObjectKey value = nextObject(); + 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; + ObjectKey value = nextObject(); + + 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; + ObjectKey value = nextObject(); + + 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(); + ObjectKey value = nextObject(); + map.put(key, value); + final ObjectKey returnedValue = map.get(key); + + assertEquals(value, returnedValue); + } + + @Test + protected void gettingNonExistingValueReturnsCorrectValue() { + int key = nextInt(); + final ObjectKey returnedValue = map.get(key); + + assertEquals(defaultValue, returnedValue); + } + + @Test + protected void removingNonExistingKeyReturnsDefaultValue() { + int key = nextInt(); + final ObjectKey removedValue = map.remove(key); + + assertEquals(null, removedValue); + } + + @Test + protected void removingExistingKeyReturnsPreviousValue() { + int key = nextInt(); + ObjectKey value = nextObject(); + map.put(key, value); + final ObjectKey removedValue = map.remove(key); + + assertEquals(value, removedValue); + } + + @Test + protected void removingWithValueWhenKeyDoesNotExistReturnsFalse() { + int key = nextInt(); + ObjectKey value = nextObject(); + final boolean result = map.remove(key, value); + + assertFalse(result); + } + + @Test + protected void removingWithValueWhenValueIsDifferentReturnsFalse() { + int key = nextInt(); + ObjectKey value = nextObject(); + map.put(key, value); + final boolean result = map.remove(key, nextObject()); + + assertFalse(result); + } + + @Test + protected void removingWithValueWhenValueIsSameReturnsTrue() { + int key = nextInt(); + ObjectKey value = nextObject(); + map.put(key, value); + final boolean result = map.remove(key, value); + + assertTrue(result); + } + + @Test + protected void puttingValueIfAbsentReturnsSameValue() { + int key = nextInt(); + ObjectKey value = nextObject(); + map.computeIfAbsent(key, l -> value); + + ObjectKey result = map.get(key); + + assertEquals(result, value); + } + + @Test + protected void checkingValueIfNotAbsentReturnsSameValue() { + int key = nextInt(); + ObjectKey value = nextObject(); + map.put(key, value); + ObjectKey returned = map.computeIfAbsent(key, l -> value); + + ObjectKey result = map.get(key); + + assertEquals(result, value); + assertEquals(value, returned); + } + + @Test + protected void replacingValueIfPresentReturnsNewValue() { + int key = nextInt(); + ObjectKey value = nextObject(); + map.put(key, value); + + ObjectKey newValue = nextObject(); + + map.computeIfPresent(key, (aLongKey, anIntValue) -> newValue); // key + old value + + ObjectKey result = map.get(key); + + assertEquals(result, newValue); + } + + @Test + protected void checkingValueIfNotPresentReturnsDefaultValue() { + int key = nextInt(); + ObjectKey newValue = nextObject(); + map.computeIfPresent(key, (aLongKey, anIntValue) -> newValue); // key + old value + + ObjectKey result = map.get(key); + + assertEquals(result, map.getDefaultValue()); + } +} diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/longobject/ConcurrentBusyWaitingLongIntMapTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/longobject/ConcurrentBusyWaitingLongIntMapTest.java new file mode 100644 index 0000000..621ed84 --- /dev/null +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/longobject/ConcurrentBusyWaitingLongIntMapTest.java @@ -0,0 +1,12 @@ +package com.trivago.fastutilconcurrentwrapper.longobject; + +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongObjectMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentBusyWaitingLongObjectMap; + +public class ConcurrentBusyWaitingLongIntMapTest extends AbstractLongObjectMapTest { + + @Override + LongObjectMap createMap() { + return new ConcurrentBusyWaitingLongObjectMap<>(16, 16, 0.9F, defaultValue); + } +} diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/longobject/ConcurrentPrimitiveLongIntMapTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/longobject/ConcurrentPrimitiveLongIntMapTest.java new file mode 100644 index 0000000..1ad61f7 --- /dev/null +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/longobject/ConcurrentPrimitiveLongIntMapTest.java @@ -0,0 +1,12 @@ +package com.trivago.fastutilconcurrentwrapper.longobject; + +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongObjectMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.map.ConcurrentLongObjectMap; + +public class ConcurrentPrimitiveLongIntMapTest extends AbstractLongObjectMapTest { + @Override + LongObjectMap createMap() { + return new ConcurrentLongObjectMap<>(16, 16, 0.9F, defaultValue); + } + +} diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/longobject/PrimitiveFastutilLongIntWrapperTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/longobject/PrimitiveFastutilLongIntWrapperTest.java new file mode 100644 index 0000000..c14d53c --- /dev/null +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/longobject/PrimitiveFastutilLongIntWrapperTest.java @@ -0,0 +1,12 @@ +package com.trivago.fastutilconcurrentwrapper.longobject; + +import com.trivago.fastutilconcurrentwrapper.primitivekeys.LongObjectMap; +import com.trivago.fastutilconcurrentwrapper.primitivekeys.wrapper.PrimitiveFastutilLongObjectWrapper; + +public class PrimitiveFastutilLongIntWrapperTest extends AbstractLongObjectMapTest { + + @Override + LongObjectMap createMap() { + return new PrimitiveFastutilLongObjectWrapper<>(5, 0.9F, defaultValue); + } +} diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/objectint/AbstractObjectIntMapTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/objectint/AbstractObjectIntMapTest.java new file mode 100644 index 0000000..77f3dce --- /dev/null +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/objectint/AbstractObjectIntMapTest.java @@ -0,0 +1,213 @@ +package com.trivago.fastutilconcurrentwrapper.objectint; + +import com.trivago.fastutilconcurrentwrapper.AbstractMapTest; +import com.trivago.fastutilconcurrentwrapper.objectkeys.ObjectIntMap; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +abstract class AbstractObjectIntMapTest extends AbstractMapTest { + // Some methods return the default value of the underlying Fastutil implementation. + private static final int FASTUTIL_DEFAULT_VALUE = 0; + + protected int defaultValue; + private ObjectIntMap map; + // Keep the default value to easily verify that this value is returned. + + abstract ObjectIntMap createMap(); + + @BeforeEach + void initializeMap() { + defaultValue = nextInt(); + map = createMap(); + } + + @Test + protected void containsKeyReturnsFalseIfMapIsEmpty() { + final ObjectKey key = nextObject(); + + final boolean contains = map.containsKey(key); + + assertFalse(contains); + } + + @Test + protected void containsKeyReturnsTrueIfKeyExists() { + ObjectKey key = nextObject(); + int value = nextInt(); + map.put(key, value); + + final boolean contains = map.containsKey(key); + + assertTrue(contains); + } + + @Test + protected void containsKeyReturnsFalseIfKeyWasRemoved() { + ObjectKey key = nextObject(); + int value = nextInt(); + 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; + int value = nextInt(); + + List keys = new ArrayList<>(entryCount); + for (int key = 1; key <= entryCount; key++) { + ObjectKey objectKey = nextObject(); + keys.add(objectKey); + map.put(objectKey, value); + } + for (ObjectKey objectKey : keys) { + map.remove(objectKey); + } + + final boolean empty = map.isEmpty(); + + assertTrue(empty); + } + + @Test + protected void sizeIsCorrect() { + int entries = (Math.abs(nextInt()) % 50) + 1; + int value = nextInt(); + + for (int key = 1; key <= entries; key++) { + map.put(nextObject(), value); + } + + final int size = map.size(); + + assertEquals(entries, size); + } + + @Test + protected void gettingExistingValueReturnsCorrectValue() { + ObjectKey key = nextObject(); + int value = nextInt(); + map.put(key, value); + final int returnedValue = map.get(key); + + assertEquals(value, returnedValue); + } + + @Test + protected void gettingNonExistingValueReturnsCorrectValue() { + ObjectKey key = nextObject(); + final int returnedValue = map.get(key); + + assertEquals(defaultValue, returnedValue); + } + + @Test + protected void removingNonExistingKeyReturnsDefaultValue() { + ObjectKey key = nextObject(); + final int removedValue = map.remove(key); + + assertEquals(FASTUTIL_DEFAULT_VALUE, removedValue); + } + + @Test + protected void removingExistingKeyReturnsPreviousValue() { + ObjectKey key = nextObject(); + int value = nextInt(); + map.put(key, value); + final int removedValue = map.remove(key); + + assertEquals(value, removedValue); + } + + @Test + protected void removingWithValueWhenKeyDoesNotExistReturnsFalse() { + ObjectKey key = nextObject(); + int value = nextInt(); + final boolean result = map.remove(key, value); + + assertFalse(result); + } + + @Test + protected void removingWithValueWhenValueIsDifferentReturnsFalse() { + ObjectKey key = nextObject(); + int value = nextInt(); + map.put(key, value); + final boolean result = map.remove(key, value - 1); + + assertFalse(result); + } + + @Test + protected void removingWithValueWhenValueIsSameReturnsTrue() { + ObjectKey key = nextObject(); + int value = nextInt(); + map.put(key, value); + final boolean result = map.remove(key, value); + + assertTrue(result); + } + + @Test + protected void puttingValueIfAbsentReturnsSameValue() { + ObjectKey key = nextObject(); + int value = nextInt(); + map.computeIfAbsent(key, l -> value); + + int result = map.get(key); + + assertEquals(result, value); + } + + @Test + protected void checkingValueIfNotAbsentReturnsSameValue() { + ObjectKey key = nextObject(); + int value = nextInt(); + map.put(key, value); + int returned = map.computeIfAbsent(key, l -> value); + + int result = map.get(key); + + assertEquals(result, value); + assertEquals(value, returned); + } + + @Test + protected void replacingValueIfPresentReturnsNewValue() { + ObjectKey key = nextObject(); + int value = nextInt(); + map.put(key, value); + + map.computeIfPresent(key, (aLongKey, anIntValue) -> 2 * anIntValue); // key + old value + + int result = map.get(key); + + assertEquals(result, 2 * value); + } + + @Test + protected void checkingValueIfNotPresentReturnsDefaultValue() { + ObjectKey key = nextObject(); + map.computeIfPresent(key, (aLongKey, anIntValue) -> 2 * anIntValue); // key + old value + + int result = map.get(key); + + assertEquals(result, map.getDefaultValue()); + } +} diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/objectint/ConcurrentBusyWaitingObjectIntMapTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/objectint/ConcurrentBusyWaitingObjectIntMapTest.java new file mode 100644 index 0000000..24162bb --- /dev/null +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/objectint/ConcurrentBusyWaitingObjectIntMapTest.java @@ -0,0 +1,12 @@ +package com.trivago.fastutilconcurrentwrapper.objectint; + +import com.trivago.fastutilconcurrentwrapper.objectkeys.ObjectIntMap; +import com.trivago.fastutilconcurrentwrapper.objectkeys.map.ConcurrentBusyWaitingObjectIntMap; + +public class ConcurrentBusyWaitingObjectIntMapTest extends AbstractObjectIntMapTest { + + @Override + ObjectIntMap createMap() { + return new ConcurrentBusyWaitingObjectIntMap<>(16, 16, 0.9F, defaultValue); + } +} diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/objectint/ConcurrentPrimitiveObjectIntMapTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/objectint/ConcurrentPrimitiveObjectIntMapTest.java new file mode 100644 index 0000000..e6abcee --- /dev/null +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/objectint/ConcurrentPrimitiveObjectIntMapTest.java @@ -0,0 +1,12 @@ +package com.trivago.fastutilconcurrentwrapper.objectint; + +import com.trivago.fastutilconcurrentwrapper.objectkeys.ObjectIntMap; +import com.trivago.fastutilconcurrentwrapper.objectkeys.map.ConcurrentObjectIntMap; + +public class ConcurrentPrimitiveObjectIntMapTest extends AbstractObjectIntMapTest { + @Override + ObjectIntMap createMap() { + return new ConcurrentObjectIntMap<>(16, 16, 0.9F, defaultValue); + } + +} diff --git a/src/test/java/com/trivago/fastutilconcurrentwrapper/objectint/PrimitiveFastutilObjectIntWrapperTest.java b/src/test/java/com/trivago/fastutilconcurrentwrapper/objectint/PrimitiveFastutilObjectIntWrapperTest.java new file mode 100644 index 0000000..87b84d9 --- /dev/null +++ b/src/test/java/com/trivago/fastutilconcurrentwrapper/objectint/PrimitiveFastutilObjectIntWrapperTest.java @@ -0,0 +1,12 @@ +package com.trivago.fastutilconcurrentwrapper.objectint; + +import com.trivago.fastutilconcurrentwrapper.objectkeys.ObjectIntMap; +import com.trivago.fastutilconcurrentwrapper.objectkeys.wrapper.PrimitiveFastutilObjectIntWrapper; + +public class PrimitiveFastutilObjectIntWrapperTest extends AbstractObjectIntMapTest { + + @Override + ObjectIntMap createMap() { + return new PrimitiveFastutilObjectIntWrapper<>(5, 0.9F, defaultValue); + } +}