diff --git a/src/jmh/java/com/trivago/kangaroo/AbstractBenchHelper.java b/src/jmh/java/com/trivago/kangaroo/AbstractBenchHelper.java index cff591e..2de6414 100644 --- a/src/jmh/java/com/trivago/kangaroo/AbstractBenchHelper.java +++ b/src/jmh/java/com/trivago/kangaroo/AbstractBenchHelper.java @@ -9,6 +9,17 @@ public abstract class AbstractBenchHelper extends AbstractCommonBenchHelper { protected static final int NUM_VALUES = 1_000_000; protected ConcurrentLongLongMap map; + /** + * Initializes the concurrent map with a pre-populated set of random key-value pairs. + * + *
The map is configured with 16 buckets, an initial capacity defined by {@code NUM_VALUES}, + * and a load factor of 0.8. When the {@code mode} parameter is {@code BUSY_WAITING}, the map is built + * with busy-waiting behavior; otherwise, a default configuration is used. After initialization, + * the map is populated with {@code NUM_VALUES} entries, each assigned random long keys and values + * generated via {@link ThreadLocalRandom}.
+ * + * @param mode the map mode that determines whether busy-waiting is enabled + */ public void initAndLoadData(PrimitiveMapBuilder.MapMode mode) { if (mode == PrimitiveMapBuilder.MapMode.BUSY_WAITING){ map = ConcurrentLongLongMap.newBuilder() diff --git a/src/jmh/java/com/trivago/kangaroo/AbstractCommonBenchHelper.java b/src/jmh/java/com/trivago/kangaroo/AbstractCommonBenchHelper.java index af4fa41..8af05e7 100644 --- a/src/jmh/java/com/trivago/kangaroo/AbstractCommonBenchHelper.java +++ b/src/jmh/java/com/trivago/kangaroo/AbstractCommonBenchHelper.java @@ -9,6 +9,12 @@ import java.util.concurrent.TimeUnit; public abstract class AbstractCommonBenchHelper { + /** + * Benchmarks the throughput of the "get" operation. + * + *This method executes the testGet() operation using the throughput mode and measures its performance + * with 4 concurrent threads. + */ @Threads(4) @Benchmark @BenchmarkMode(Mode.Throughput) @@ -46,6 +52,13 @@ public void testRandomPutAvgTime() { testPut(); } + /** + * Measures the average execution time of all operations. + *
+ * Executes the {@code testAllOps()} method across four concurrent threads + * and reports the average execution time in nanoseconds. + *
+ */ @Threads(4) @Benchmark @BenchmarkMode(Mode.AverageTime) @@ -54,9 +67,28 @@ public void testRandomAllOpsAvgTime() { testAllOps(); } - public abstract void testGet(); + /** + * Executes the GET operation benchmark. + * + *This abstract method should be implemented by subclasses to perform the GET operation, + * which is used in benchmarking tests to measure performance metrics such as throughput and average execution time.
+ */ +public abstract void testGet(); - public abstract void testPut(); + /** + * Executes a put operation for benchmarking purposes. + * + *Implementations should override this method to define the logic for a put operation, + * which will be measured by throughput and average execution time benchmarks.
+ */ +public abstract void testPut(); - public abstract void testAllOps(); + /** + * Executes a comprehensive set of benchmark operations. + * + *This abstract method should be implemented to perform a mixed workload—typically combining + * get and put operations—to simulate a realistic full-spectrum scenario. It is invoked during + * benchmarking runs to measure both throughput and average execution time in multi-threaded environments. + */ +public abstract void testAllOps(); } \ No newline at end of file diff --git a/src/jmh/java/com/trivago/kangaroo/FastutilWrapperBusyWaitingBenchmark.java b/src/jmh/java/com/trivago/kangaroo/FastutilWrapperBusyWaitingBenchmark.java index 963163f..e9c3507 100644 --- a/src/jmh/java/com/trivago/kangaroo/FastutilWrapperBusyWaitingBenchmark.java +++ b/src/jmh/java/com/trivago/kangaroo/FastutilWrapperBusyWaitingBenchmark.java @@ -12,6 +12,12 @@ @Warmup(iterations = 3, time = 1) @Measurement(iterations = 3, time = 2) public class FastutilWrapperBusyWaitingBenchmark extends AbstractBenchHelper { + /** + * Initializes and loads benchmark data using busy waiting mode. + * + *
This setup method is executed once per trial (as dictated by the @Setup(Level.Trial) + * annotation) to prepare the data required for the benchmark. + */ @Setup(Level.Trial) public void loadData() { initAndLoadData(PrimitiveMapBuilder.MapMode.BUSY_WAITING); diff --git a/src/jmh/java/com/trivago/kangaroo/FastutilWrapperDefaultBenchmark.java b/src/jmh/java/com/trivago/kangaroo/FastutilWrapperDefaultBenchmark.java index d51d86f..912ee4a 100644 --- a/src/jmh/java/com/trivago/kangaroo/FastutilWrapperDefaultBenchmark.java +++ b/src/jmh/java/com/trivago/kangaroo/FastutilWrapperDefaultBenchmark.java @@ -12,6 +12,14 @@ @Warmup(iterations = 3, time = 1) @Measurement(iterations = 3, time = 2) public class FastutilWrapperDefaultBenchmark extends AbstractBenchHelper { + /** + * Initializes and loads the data required for the benchmark trial in blocking mode. + * + *
+ * This method is executed once before the benchmark trial starts and sets up the necessary data by + * invoking the initialization routine with the blocking mode specified by {@code PrimitiveMapBuilder.MapMode.BLOCKING}. + *
+ */ @Setup(Level.Trial) public void loadData() { initAndLoadData(PrimitiveMapBuilder.MapMode.BLOCKING); diff --git a/src/jmh/java/com/trivago/kangaroo/JavaUtilWrapperBenchmark.java b/src/jmh/java/com/trivago/kangaroo/JavaUtilWrapperBenchmark.java index 458788e..cfe6c84 100644 --- a/src/jmh/java/com/trivago/kangaroo/JavaUtilWrapperBenchmark.java +++ b/src/jmh/java/com/trivago/kangaroo/JavaUtilWrapperBenchmark.java @@ -21,6 +21,15 @@ public class JavaUtilWrapperBenchmark extends AbstractCommonBenchHelper { MapThis setup method creates a {@code Long2LongOpenHashMap} with a predefined capacity and a load factor of 0.8, + * populates it with random long keys and values generated via {@code ThreadLocalRandom}, and then wraps the map with + * {@code Collections.synchronizedMap} to ensure thread-safe access during benchmark trials. + * + *
The method is executed once per trial, as indicated by the {@code @Setup(Level.Trial)} annotation. + */ @Setup(Level.Trial) public void loadData() { Long2LongOpenHashMap m = new Long2LongOpenHashMap(AbstractBenchHelper.NUM_VALUES, 0.8f); @@ -32,12 +41,26 @@ public void loadData() { map = Collections.synchronizedMap(m); } + /** + * Benchmarks a map retrieval operation using a randomly generated key. + * + *
This method generates a random key via {@link java.util.concurrent.ThreadLocalRandom} + * and retrieves the corresponding value from the synchronized map. It is designed to measure + * the performance of get operations during benchmarking tests.
+ */ @Override public void testGet() { long key = ThreadLocalRandom.current().nextLong(); map.get(key); } + /** + * Inserts a new entry into the map using randomly generated key and value. + * + *This method generates random long values for both the key and value with + * {@link ThreadLocalRandom} and inserts the entry into the synchronized map, + * serving as a benchmark for put operations.
+ */ @Override public void testPut() { long key = ThreadLocalRandom.current().nextLong(); @@ -45,6 +68,17 @@ public void testPut() { map.put(key, value); } + /** + * Executes a randomly selected map operation for benchmarking purposes. + * + *This method randomly performs one of three actions on the map: + *
The map is built with 16 buckets, an initial capacity of {@code NUM_VALUES} (1,000,000), and a load factor of 0.8. + * The provided map mode is used during construction. After initialization, the map is filled with + * {@code NUM_VALUES} randomly generated long key-value pairs. + * + * @param mode the map mode to be applied during the map's initialization + */ public void initAndLoadData (PrimitiveMapBuilder.MapMode mode) { map = ConcurrentLongLongMap.newBuilder() .withBuckets(16) @@ -25,12 +34,24 @@ public void initAndLoadData (PrimitiveMapBuilder.MapMode mode) { } } + /** + * Retrieves a value from the concurrent map using a randomly generated key. + * + *
This benchmark method generates a random long key via ThreadLocalRandom and uses it to perform a + * get operation on the map, facilitating the measurement of concurrent retrieval performance.
+ */ @Override public void testGet() { long key = ThreadLocalRandom.current().nextLong(); map.get(key); } + /** + * Benchmarks the put operation on the concurrent map by inserting a randomly generated key-value pair. + * + *This method uses thread-local random values for both the key and value to simulate a put operation + * in a concurrent benchmarking scenario.
+ */ @Override public void testPut() { long key = ThreadLocalRandom.current().nextLong(); @@ -38,6 +59,16 @@ public void testPut() { map.put(key, value); } + /** + * Executes a random operation on the concurrent map. + * + *This method randomly selects one of three operations: + *
This method is executed once before the benchmark trial begins and sets up the data by + * invoking the superclass's data initialization routine with a busy-waiting strategy. + */ @Setup(Level.Trial) public void loadData() { initAndLoadData(PrimitiveMapBuilder.MapMode.BUSY_WAITING); diff --git a/src/jmh/java/com/trivago/kangaroo/long2long/FastutilWrapperDefaultLongLongBenchmark.java b/src/jmh/java/com/trivago/kangaroo/long2long/FastutilWrapperDefaultLongLongBenchmark.java index f20f5ca..a86ec0e 100644 --- a/src/jmh/java/com/trivago/kangaroo/long2long/FastutilWrapperDefaultLongLongBenchmark.java +++ b/src/jmh/java/com/trivago/kangaroo/long2long/FastutilWrapperDefaultLongLongBenchmark.java @@ -12,6 +12,13 @@ @Warmup(iterations = 3, time = 1) @Measurement(iterations = 3, time = 2) public class FastutilWrapperDefaultLongLongBenchmark extends AbstractLongLongBenchHelper { + /** + * Initializes and loads data for the benchmark trial. + * + *
This setup method is executed once before the benchmark trial begins. It initializes + * the necessary data structures in blocking mode by invoking {@code initAndLoadData} with + * {@code PrimitiveMapBuilder.MapMode.BLOCKING}.
+ */ @Setup(Level.Trial) public void loadData() { initAndLoadData(PrimitiveMapBuilder.MapMode.BLOCKING); diff --git a/src/jmh/java/com/trivago/kangaroo/long2long/JavaConcurrentLongLongBenchmark.java b/src/jmh/java/com/trivago/kangaroo/long2long/JavaConcurrentLongLongBenchmark.java index 16ca2e7..f88c23b 100644 --- a/src/jmh/java/com/trivago/kangaroo/long2long/JavaConcurrentLongLongBenchmark.java +++ b/src/jmh/java/com/trivago/kangaroo/long2long/JavaConcurrentLongLongBenchmark.java @@ -19,6 +19,13 @@ public class JavaConcurrentLongLongBenchmark extends AbstractCommonBenchHelper { MapThis setup method, annotated with {@code @Setup(Level.Trial)}, creates a {@link java.util.concurrent.ConcurrentHashMap} + * using a predefined capacity and load factor, then populates it with entries where both keys and values are random long + * values generated by {@link java.util.concurrent.ThreadLocalRandom}. + */ @Setup(Level.Trial) public void loadData() { map = new ConcurrentHashMap<>(AbstractLongLongBenchHelper.NUM_VALUES, 0.8f); @@ -29,12 +36,25 @@ public void loadData() { } } + /** + * Benchmarks a get operation on the concurrent map by retrieving a value using a randomly generated key. + * + *
This method generates a random long key with ThreadLocalRandom and performs a lookup in the map, + * serving as part of the benchmarking process for concurrent retrieval performance. + */ @Override public void testGet() { long key = ThreadLocalRandom.current().nextLong(); map.get(key); } + /** + * Inserts a random key-value pair into the map. + * + *
This method generates random long values for both the key and the value using ThreadLocalRandom, + * and inserts the generated pair into the map. It overrides the superclass method to simulate a put + * operation within a concurrent benchmarking environment. + */ @Override public void testPut() { long key = ThreadLocalRandom.current().nextLong(); @@ -42,6 +62,18 @@ public void testPut() { map.put(key, value); } + /** + * Executes a randomly selected operation on the concurrent map. + * + *
This method simulates mixed access patterns by performing one of three operations: + *
These operations are used for concurrent benchmarking of map performance.
+ */
@Override
public void testAllOps() {
int op = ThreadLocalRandom.current().nextInt(3);
diff --git a/src/jmh/java/com/trivago/kangaroo/long2long/JavaUtilWrapperLongLongBenchmark.java b/src/jmh/java/com/trivago/kangaroo/long2long/JavaUtilWrapperLongLongBenchmark.java
index 885466c..e474368 100644
--- a/src/jmh/java/com/trivago/kangaroo/long2long/JavaUtilWrapperLongLongBenchmark.java
+++ b/src/jmh/java/com/trivago/kangaroo/long2long/JavaUtilWrapperLongLongBenchmark.java
@@ -20,6 +20,15 @@ public class JavaUtilWrapperLongLongBenchmark extends AbstractCommonBenchHelper
Map This method creates a Long2LongOpenHashMap with an initial capacity defined by
+ * AbstractLongLongBenchHelper.NUM_VALUES and a load factor of 0.8, populating it with
+ * randomly generated key-value pairs using ThreadLocalRandom. The generated map is then wrapped
+ * in a synchronized map to ensure thread safety during benchmark operations. This setup is
+ * executed once per trial as indicated by the @Setup(Level.Trial) annotation. This method generates a random key and retrieves the associated value from the map, helping to simulate
+ * random access patterns during performance measurements.
+ */
@Override
public void testGet() {
long key = ThreadLocalRandom.current().nextLong();
map.get(key);
}
+ /**
+ * Inserts a random key-value pair into the map to benchmark the put operation.
+ *
+ * This method generates random long values for both the key and the value using ThreadLocalRandom,
+ * then adds the pair to the map.
+ */
@Override
public void testPut() {
long key = ThreadLocalRandom.current().nextLong();
@@ -44,6 +65,18 @@ public void testPut() {
map.put(key, value);
}
+ /**
+ * Performs a random operation on the map.
+ *
+ * This method randomly selects one of the following operations using a randomly generated key:
+ * The method does not return any value.
+ */
@Override
public void testAllOps() {
int op = ThreadLocalRandom.current().nextInt(3);
diff --git a/src/jmh/java/com/trivago/kangaroo/object2long/AbstractObjectLongBenchHelper.java b/src/jmh/java/com/trivago/kangaroo/object2long/AbstractObjectLongBenchHelper.java
index ea02095..af1e50c 100644
--- a/src/jmh/java/com/trivago/kangaroo/object2long/AbstractObjectLongBenchHelper.java
+++ b/src/jmh/java/com/trivago/kangaroo/object2long/AbstractObjectLongBenchHelper.java
@@ -10,6 +10,15 @@ public abstract class AbstractObjectLongBenchHelper extends AbstractCommonBenchH
protected static final int NUM_VALUES = 1_000_000;
protected ConcurrentObjectLongMap This method configures the map using a builder pattern with 16 buckets, an initial capacity of
+ * NUM_VALUES, the specified map mode, and a load factor of 0.8. It then populates the map with NUM_VALUES
+ * entries, where each entry consists of a new TestObjectKey instance and a randomly generated long value.
+ *
+ * @param mode the mode used to configure the map builder
+ */
public void initAndLoadData (PrimitiveMapBuilder.MapMode mode) {
map = ConcurrentObjectLongMap. This method creates a new TestObjectKey and retrieves its associated value from the map,
+ * allowing measurement of the map's get performance.
+ */
@Override
public void testGet() {
TestObjectKey key = new TestObjectKey();
map.get(key);
}
+ /**
+ * Inserts a new key-value pair into the concurrent map.
+ *
+ * This method creates a fresh key and associates it with a randomly generated long value,
+ * simulating a put operation for benchmarking purposes.
+ */
@Override
public void testPut() {
TestObjectKey key = new TestObjectKey();
@@ -38,6 +59,12 @@ public void testPut() {
map.put(key, value);
}
+ /**
+ * Executes a random operation on the concurrent map.
+ *
+ * This method randomly selects one of three operations—insert (put), removal (remove), or retrieval (get)—
+ * using a newly instantiated key for each call. When inserting, it generates a random long value to associate with the key.
+ */
@Override
public void testAllOps() {
int op = ThreadLocalRandom.current().nextInt(3);
diff --git a/src/jmh/java/com/trivago/kangaroo/object2long/FastutilWrapperBusyWaitingObjectLongBenchmark.java b/src/jmh/java/com/trivago/kangaroo/object2long/FastutilWrapperBusyWaitingObjectLongBenchmark.java
index 47424c2..332c4d0 100644
--- a/src/jmh/java/com/trivago/kangaroo/object2long/FastutilWrapperBusyWaitingObjectLongBenchmark.java
+++ b/src/jmh/java/com/trivago/kangaroo/object2long/FastutilWrapperBusyWaitingObjectLongBenchmark.java
@@ -12,6 +12,12 @@
@Warmup(iterations = 3, time = 1)
@Measurement(iterations = 3, time = 2)
public class FastutilWrapperBusyWaitingObjectLongBenchmark extends AbstractObjectLongBenchHelper {
+ /**
+ * Initializes and loads data for the benchmark using a busy waiting strategy.
+ *
+ * This setup method is executed once per trial and prepares the benchmark state by invoking
+ * the data initialization routine with a busy-waiting configuration. This method is executed once per trial (annotated with {@code @Setup(Level.Trial)}) and prepares
+ * the benchmark environment by invoking {@code initAndLoadData} with {@code PrimitiveMapBuilder.MapMode.BLOCKING}.
+ */
@Setup(Level.Trial)
public void loadData() {
initAndLoadData(PrimitiveMapBuilder.MapMode.BLOCKING);
diff --git a/src/jmh/java/com/trivago/kangaroo/object2long/JavaConcurrentObjectLongBenchmark.java b/src/jmh/java/com/trivago/kangaroo/object2long/JavaConcurrentObjectLongBenchmark.java
index e790615..6ac950e 100644
--- a/src/jmh/java/com/trivago/kangaroo/object2long/JavaConcurrentObjectLongBenchmark.java
+++ b/src/jmh/java/com/trivago/kangaroo/object2long/JavaConcurrentObjectLongBenchmark.java
@@ -19,6 +19,15 @@ public class JavaConcurrentObjectLongBenchmark extends AbstractCommonBenchHelper
Map This method is executed once per trial setup. It initializes the map as a new
+ * {@link java.util.concurrent.ConcurrentHashMap} with an initial capacity of
+ * {@link AbstractObjectLongBenchHelper#NUM_VALUES} and a load factor of 0.8. The method then
+ * iterates {@code NUM_VALUES} times, generating a new {@link TestObjectKey} and a random
+ * long value for each entry, which is added to the map.
+ */
@Setup(Level.Trial)
public void loadData() {
map = new ConcurrentHashMap<>(AbstractObjectLongBenchHelper.NUM_VALUES, 0.8f);
@@ -29,11 +38,25 @@ public void loadData() {
}
}
+ /**
+ * Executes a get operation on the concurrent map for benchmarking purposes.
+ *
+ *
+ * This method retrieves a value from the map using a new instance of {@code TestObjectKey},
+ * measuring the performance of read operations in a concurrent environment.
+ * This method creates a new instance of TestObjectKey and associates it with a random long value,
+ * simulating a put operation for benchmark testing.
+ */
@Override
public void testPut() {
TestObjectKey key = new TestObjectKey();
@@ -41,6 +64,17 @@ public void testPut() {
map.put(key, value);
}
+ /**
+ * Executes a random operation on the concurrent map used for benchmarking.
+ *
+ * This method simulates a mixed workload by randomly choosing one of three actions:
+ * This method creates an {@code Object2LongOpenHashMap} with a predefined capacity and load factor,
+ * populates it with random long values using new {@code TestObjectKey} instances, and wraps the map
+ * in a synchronized wrapper. It is executed once per trial as part of the benchmark setup. This method retrieves a value using a newly instantiated TestObjectKey to measure the performance of
+ * map lookup operations as part of the benchmark.
+ */
@Override
public void testGet() {
map.get(new TestObjectKey());
}
+ /**
+ * Inserts a new key-value pair into the map used for benchmarking.
+ *
+ * This method creates a new instance of TestObjectKey and generates a random long value,
+ * then adds the pair to the map.
+ */
@Override
public void testPut() {
TestObjectKey key = new TestObjectKey();
@@ -43,6 +62,18 @@ public void testPut() {
map.put(key, value);
}
+ /**
+ * Executes one of the map operations (put, remove, or get) at random.
+ *
+ * This method randomly selects one of three operations to perform on the map:
+ *
+ * The hash code is computed by applying {@link Integer#hashCode(int)} to the {@code id} field.
+ * The map is initialized with a fixed number of buckets, each protected by a separate {@link ReentrantReadWriteLock}
+ * for thread safety. The {@code numBuckets} parameter must be within the range [1, 100,000,000]; otherwise, an
+ * {@link IllegalArgumentException} is thrown.
+ *
+ * @param numBuckets the number of buckets for the map; must be between 1 and 100,000,000
+ * @throws IllegalArgumentException if {@code numBuckets} is less than 1 or greater than 100,000,000
+ */
protected PrimitiveConcurrentMap (int numBuckets) {
if (numBuckets < 1 || numBuckets > 100_000_000)
throw new IllegalArgumentException("numBuckets must be between 1 and 100_000_000, but: "+ numBuckets);
@@ -25,7 +35,14 @@ protected PrimitiveConcurrentMap (int numBuckets) {
locks[i] = new ReentrantReadWriteLock();
}//new
- /** Lock must be held! */
+ /**
+ * Retrieves the mapping function for the bucket at the specified index.
+ *
+ * Precondition: The appropriate lock must be held when calling this method.
+ *
+ * @param index the index of the bucket whose mapping function is to be retrieved
+ * @return the mapping function associated with the specified bucket index
+ */
protected abstract Function
+ * The key is used as its own hash code and passed to the static {@link #bucket(int, int)} method,
+ * which applies a mixing function to distribute entries uniformly across the available buckets.
+ * If the key is {@code null}, returns a default index of 0; otherwise, uses the key's hash
+ * code and the total number of buckets to compute the appropriate bucket index. This method applies a mixing function to the input hash and returns the absolute value of the remainder
+ * when divided by the total number of buckets. The resulting index is within the range [0, bucketSize).
+ *
+ * @param hash the hash value to be mixed
+ * @param bucketSize the total number of available buckets; must be positive
+ * @return the computed bucket index
+ */
public static int bucket (int hash, int bucketSize) {
return Math.abs(HashCommon.mix(hash) % bucketSize);
}
diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/intkey/ConcurrentBusyWaitingIntFloatMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/intkey/ConcurrentBusyWaitingIntFloatMap.java
index e94aec3..d5eaf8f 100644
--- a/src/main/java/com/trivago/fastutilconcurrentwrapper/intkey/ConcurrentBusyWaitingIntFloatMap.java
+++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/intkey/ConcurrentBusyWaitingIntFloatMap.java
@@ -6,10 +6,32 @@
import java.util.function.BiFunction;
public class ConcurrentBusyWaitingIntFloatMap extends ConcurrentIntFloatMap {
+ /**
+ * Constructs a new ConcurrentBusyWaitingIntFloatMap with the specified configuration.
+ *
+ * This map employs busy waiting for lock acquisition and delegates initialization to its superclass.
+ * It partitions data into a specified number of buckets, defines an initial capacity and load factor,
+ * and uses a default value for missing keys.
+ *
+ * @param numBuckets the number of buckets used for partitioning the map for concurrent access
+ * @param initialCapacity the initial capacity of the map
+ * @param loadFactor the load factor that triggers resizing when exceeded
+ * @param defaultValue the default value returned when a key is not present in the map
+ */
public ConcurrentBusyWaitingIntFloatMap (int numBuckets, int initialCapacity, float loadFactor, float defaultValue) {
super(numBuckets, initialCapacity, loadFactor, defaultValue);
}
+ /**
+ * Checks if the map contains the specified key.
+ *
+ * This method continuously attempts to acquire a read lock on the bucket associated
+ * with the key using busy waiting. Once the lock is obtained, it checks whether the key
+ * exists in the corresponding bucket. This method continuously attempts to acquire the read lock for the bucket corresponding to the key via busy waiting.
+ * It returns the value mapped to the key if present, or the default value otherwise.
+ *
+ * @param key the key whose associated value is to be returned
+ * @return the value associated with the key, or the default value if the key does not exist
+ */
@Override
public float get (int key) {
int bucket = getBucket(key);
@@ -46,6 +77,16 @@ public float get (int key) {
}
}
+ /**
+ * Inserts or updates the value for the specified key in the map.
+ *
+ * This method acquires a write lock for the appropriate bucket using busy waiting. Once the lock is acquired, it updates
+ * the mapping for the key and returns the previous value associated with the key, or the default value if no mapping existed.
+ *
+ * @param key the key for which the value is to be inserted or updated
+ * @param value the value to associate with the specified key
+ * @return the previous value associated with the key, or the default value if there was no mapping
+ */
@Override
public float put(int key, float value) {
int bucket = getBucket(key);
@@ -64,6 +105,16 @@ public float put(int key, float value) {
}
}
+ /**
+ * Removes the mapping for the specified key and returns its associated value.
+ *
+ * This method busy-waits to acquire the write lock for the bucket determined by the key, then
+ * removes the key from that bucket. If the key is present, its associated value is returned;
+ * otherwise, the map's default value is returned.
+ *
+ * @param key the key whose mapping is to be removed
+ * @return the value previously associated with the key, or the default value if no mapping existed
+ */
@Override
public float remove(int key) {
int bucket = getBucket(key);
@@ -82,6 +133,17 @@ public float remove(int key) {
}
}
+ /**
+ * Removes the mapping for the specified key if it is currently associated with the given value.
+ *
+ * This method repeatedly attempts to acquire the write lock for the key's bucket using busy waiting.
+ * If the current value associated with the key equals the specified value, the mapping is removed.
+ *
+ * This method busy-waits to acquire a write lock for the bucket corresponding to the key. Once the lock is obtained,
+ * it either returns the existing value or computes and stores a new value using the provided mapping function.
+ * This method repeatedly attempts to acquire the write lock for the bucket corresponding to the key
+ * using busy waiting. Once the lock is obtained, it applies the provided mapping function to the key and its
+ * current value to compute an updated value.
+ *
+ * @param key the key whose associated value is to be updated if present
+ * @param mappingFunction a function that computes a new value from the key and its current value
+ * @return the updated value associated with the key, or the current value if the mapping function does not alter it
+ */
@Override
public float computeIfPresent(int key, BiFunction This implementation partitions its data into a fixed number of buckets and uses busy waiting to acquire
+ * locks for thread-safe access. Initialization is delegated to the superclass, ConcurrentIntIntMap.
+ *
+ * @param numBuckets the number of buckets used for partitioning the map
+ * @param initialCapacity the initial capacity of the map
+ * @param loadFactor the load factor that influences the map's resizing threshold
+ * @param defaultValue the default value to return when a key is not found
+ */
public ConcurrentBusyWaitingIntIntMap (int numBuckets, int initialCapacity, float loadFactor, int defaultValue) {
super(numBuckets, initialCapacity, loadFactor, defaultValue);
}
+ /**
+ * Determines if the map contains the specified key.
+ *
+ * This method calculates the bucket corresponding to the key and repeatedly attempts to acquire a
+ * read lock using busy waiting. Once the lock is obtained, it verifies the presence of the key in the
+ * associated bucket.
+ * This method acquires the write lock on the appropriate bucket using a busy-wait
+ * mechanism. Once the lock is obtained, it updates the mapping for the given key by
+ * delegating to the underlying map implementation.
+ *
+ * @param key the key whose value is to be inserted or updated
+ * @param value the value to associate with the key
+ * @return the previous value associated with the key, or a default value if no mapping existed
+ */
@Override
public int put(int key, int value) {
int bucket = getBucket(key);
@@ -64,6 +96,16 @@ public int put(int key, int value) {
}
}
+ /**
+ * Removes the mapping for the specified key from the map.
+ *
+ * This method repeatedly attempts to acquire the write lock for the bucket
+ * corresponding to the given key using a busy waiting strategy. Once the lock is
+ * obtained, it removes the mapping and returns the previously associated value.
+ *
+ * @param key the key whose mapping should be removed
+ * @return the value that was associated with the key, or the default value if no mapping existed
+ */
@Override
public int remove(int key) {
int bucket = getBucket(key);
diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/intkey/ConcurrentIntFloatMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/intkey/ConcurrentIntFloatMap.java
index 8cf7244..9463ec3 100644
--- a/src/main/java/com/trivago/fastutilconcurrentwrapper/intkey/ConcurrentIntFloatMap.java
+++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/intkey/ConcurrentIntFloatMap.java
@@ -13,6 +13,19 @@ public class ConcurrentIntFloatMap extends PrimitiveConcurrentMap
+ * The map is divided into multiple buckets to support concurrent access. Each bucket is initialized
+ * as an instance of {@code Int2FloatOpenHashMap} with the specified initial capacity and load factor.
+ * The specified default value is returned for any key that is not present in the map.
+ * This method returns the internal mapping function (bucket) corresponding to the given index,
+ * allowing for thread-safe operations on that segment of the map.
+ *
+ * @param index the index of the bucket to access
+ * @return the mapping function for the specified bucket index
+ */
@Override
protected Function This method determines the appropriate bucket for the key, acquires a read lock on that bucket,
+ * and then verifies if the key is present in the corresponding map.
+ * If the key is not present in the map, the default value is returned.
+ * If the key already has an associated value, that value is replaced and returned.
+ * If the key is not present, the key is mapped to the given value and the default map value
+ * is returned. This operation is thread-safe.
+ * Returns the value previously associated with the key, or the default value if the key was not present.
+ * If the key exists, the supplied mapping function is applied to the key and its current value,
+ * and the mapping is updated with the computed result in a thread-safe manner. If the key is not
+ * present, the mapping function is not invoked and the map remains unchanged. The returned builder lets you define map properties such as the number of buckets, initial capacity,
+ * load factor, and default value for absent keys. When the builder's {@code build()} method is called, it
+ * selects the appropriate implementation—either a busy-waiting or blocking version—based on the current map mode.
+ * If no default value is specified, 0 is used. This constructor creates an array of Int2IntOpenHashMap instances, one per bucket, where each map is initialized with
+ * the given initial capacity and load factor. The provided default value is stored and used for any key that is not present.
+ *
+ * @param numBuckets the number of buckets to divide the map into
+ * @param initialCapacity the initial capacity of each bucket's map
+ * @param loadFactor the load factor for each bucket's map
+ * @param defaultValue the default value returned for missing keys
+ */
public ConcurrentIntIntMap(
int numBuckets,
int initialCapacity,
@@ -26,11 +37,25 @@ public ConcurrentIntIntMap(
maps[i] = new Int2IntOpenHashMap(initialCapacity, loadFactor);
}
+ /**
+ * Retrieves the mapping function for the bucket at the specified index.
+ *
+ * @param index the index of the bucket to retrieve
+ * @return the mapping function corresponding to the bucket at the given index
+ */
@Override
protected Function This thread-safe method uses a read lock on the appropriate bucket to verify the presence of the key in the map.
+ * This method acquires a read lock on the bucket corresponding to the provided key
+ * and returns its value. If the key is not found, the default value is returned.
+ * This method determines the bucket corresponding to the key, acquires the bucket's write lock,
+ * and updates the underlying map with the new value. It returns the previous value associated with the key,
+ * or the default value if no mapping was present.
+ *
+ * @param key the key to update
+ * @param value the value to associate with the key
+ * @return the previous value associated with the key, or the default value if the key was not present
+ */
public int put(int key, int value) {
int bucket = getBucket(key);
@@ -67,8 +113,23 @@ public int put(int key, int value) {
}
}
- public int getDefaultValue (){ return defaultValue; }
-
+ /**
+ * Returns the default value used for keys that are not present in the map.
+ *
+ * @return the default value.
+ */
+public int getDefaultValue (){ return defaultValue; }
+
+ /**
+ * Removes the mapping for the specified key and returns the associated value.
+ *
+ * This method identifies the corresponding bucket for the key, acquires a write lock on that bucket,
+ * and removes the key-value mapping. It returns the value that was previously associated with the key,
+ * or the map's default value if no mapping was present.
+ * This method ensures thread-safe removal by acquiring a write lock on the bucket corresponding to the key.
+ *
+ * @param key the key whose mapping is to be conditionally removed
+ * @param value the value expected to be associated with the key
+ * @return {@code true} if the entry was removed, {@code false} otherwise
+ */
public boolean remove(int key, int value) {
int bucket = getBucket(key);
@@ -93,6 +163,15 @@ public boolean remove(int key, int value) {
}
}
+ /**
+ * Atomically computes and associates a value for the specified key if absent.
+ * If no value is present for the key, the provided mapping function is applied to compute a new value,
+ * which is then stored and returned. If a value already exists, it is simply returned.
+ *
+ * @param key the key for which the value is to be computed
+ * @param mappingFunction the function to compute a value for the key if it is not already present
+ * @return the existing or computed value associated with the specified key
+ */
public int computeIfAbsent(int key, Int2IntFunction mappingFunction) {
int bucket = getBucket(key);
@@ -105,6 +184,17 @@ public int computeIfAbsent(int key, Int2IntFunction mappingFunction) {
}
}
+ /**
+ * Atomically updates the value for the specified key if a mapping is present.
+ *
+ * If the key is currently mapped to a value, this method applies the provided mapping function
+ * to compute a new value and updates the mapping accordingly. If the key is not present,
+ * the default value is returned.
+ *
+ * @param key the key whose associated value is to be updated
+ * @param mappingFunction the function that computes a new value from the key and its current value
+ * @return the updated value for the key if present; otherwise, the default value
+ */
public int computeIfPresent(int key, BiFunction The returned builder allows configuration of map parameters such as the number of buckets, initial capacity,
+ * load factor, and default value for missing keys. When the build method is invoked, the builder creates a map
+ * instance based on the configured map mode: a ConcurrentBusyWaitingIntIntMap is returned for BUSY_WAITING mode,
+ * and a ConcurrentIntIntMap for BLOCKING mode. If no default value is set, zero is used. This constructor initializes a concurrent map for long keys and float values that employs busy waiting
+ * for lock acquisition. The map is partitioned into the specified number of buckets, uses the given initial capacity
+ * and load factor, and returns the provided default value when a key is not present. This method determines the appropriate bucket for the key and uses a busy-wait loop to acquire a read lock. Once the lock is acquired,
+ * it queries the underlying map to check for the key's presence.
+ *
+ * @param key the key to check for presence in the map
+ * @return {@code true} if the key exists in the map, otherwise {@code false}
+ */
@Override
public boolean containsKey(long key) {
int bucket = getBucket(key);
@@ -46,6 +67,16 @@ public float get(long key) {
}
}
+ /**
+ * Inserts or updates the mapping for the specified key using busy waiting until a write lock is acquired.
+ *
+ * The method identifies the appropriate bucket based on the key, then repeatedly attempts to acquire the corresponding
+ * write lock. Once the lock is obtained, it updates the value associated with the key and returns the previous value.
+ *
+ * @param key the key whose mapping is to be updated
+ * @param value the new value to associate with the key
+ * @return the previous value associated with the key, or the default value if no mapping existed
+ */
@Override
public float put(long key, float value) {
int bucket = getBucket(key);
@@ -64,6 +95,17 @@ public float put(long key, float value) {
}
}
+ /**
+ * Removes the entry for the specified key from the map.
+ *
+ * This method determines the appropriate bucket for the key and repeatedly attempts
+ * to acquire the corresponding write lock using busy waiting. Once the lock is acquired,
+ * it removes the key and returns the value that was previously associated with it. If the
+ * key is not present, the default value is returned.
+ *
+ * @param key the key whose entry is to be removed
+ * @return the value associated with the removed key, or the default value if the key was not present
+ */
@Override
public float remove(long key) {
int bucket = getBucket(key);
diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/longkey/ConcurrentBusyWaitingLongIntMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/longkey/ConcurrentBusyWaitingLongIntMap.java
index a08057d..7ba5ec6 100644
--- a/src/main/java/com/trivago/fastutilconcurrentwrapper/longkey/ConcurrentBusyWaitingLongIntMap.java
+++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/longkey/ConcurrentBusyWaitingLongIntMap.java
@@ -6,10 +6,33 @@
import java.util.function.BiFunction;
public class ConcurrentBusyWaitingLongIntMap extends ConcurrentLongIntMap {
+ /**
+ * Constructs a new ConcurrentBusyWaitingLongIntMap with the specified configuration.
+ *
+ * This map partitions its storage into the given number of buckets to facilitate concurrent access,
+ * using busy waiting for lock acquisition. Each bucket is initialized with the specified capacity and load factor,
+ * and the supplied default value is returned for absent keys.
+ *
+ * @param numBuckets the number of partitions for concurrent access
+ * @param initialCapacity the starting capacity for each bucket
+ * @param loadFactor the load factor threshold for resizing each bucket
+ * @param defaultValue the value to return when a key is not present in the map
+ */
public ConcurrentBusyWaitingLongIntMap (int numBuckets, int initialCapacity, float loadFactor, int defaultValue) {
super(numBuckets, initialCapacity, loadFactor, defaultValue);
}
+ /**
+ * Checks whether the map contains the specified key.
+ *
+ *
+ * This method calculates the appropriate bucket for the given key and repeatedly attempts to acquire a read lock
+ * using busy waiting. Once the lock is acquired, it checks if the key exists in the bucket.
+ * This method repeatedly attempts to acquire a write lock on the bucket for the given key using busy waiting.
+ * Once the lock is obtained, it updates the stored value for the key and returns the previous value associated with it,
+ * or a default value if the key was not previously mapped.
+ *
+ * @param key the key whose value is to be inserted or updated
+ * @param value the new value to associate with the key
+ * @return the previous value associated with the key, or the default if none existed
+ */
@Override
public int put(long key, int value) {
int bucket = getBucket(key);
@@ -64,6 +98,16 @@ public int put(long key, int value) {
}
}
+ /**
+ * Removes the mapping for the specified key from the map.
+ *
+ * This method uses busy waiting to acquire the write lock associated with the bucket
+ * containing the key. Once the appropriate lock is obtained, it removes the key-value
+ * pair and returns the value that was previously associated with the key.
+ *
+ * @param key the long key whose mapping is to be removed
+ * @return the value previously associated with the key, or the map's default value if not present
+ */
@Override
public int remove(long key) {
int bucket = getBucket(key);
diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/longkey/ConcurrentBusyWaitingLongLongMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/longkey/ConcurrentBusyWaitingLongLongMap.java
index 80917cd..1a77783 100644
--- a/src/main/java/com/trivago/fastutilconcurrentwrapper/longkey/ConcurrentBusyWaitingLongLongMap.java
+++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/longkey/ConcurrentBusyWaitingLongLongMap.java
@@ -6,10 +6,31 @@
import java.util.function.BiFunction;
public class ConcurrentBusyWaitingLongLongMap extends ConcurrentLongLongMap {
+ /**
+ * Constructs a ConcurrentBusyWaitingLongLongMap with the specified configuration.
+ *
+ * This constructor initializes the map by partitioning it into a fixed number of buckets to support concurrent
+ * operations via busy-waiting locks. The initial capacity and load factor influence the map's performance and resizing behavior,
+ * while the default value is returned for keys that are not present. This method busy-waits until a read lock on the corresponding bucket is acquired, then it verifies
+ * the presence of the key in the underlying map.
+ *
+ * @param key the key to check for presence
+ * @return {@code true} if the key exists in the map; {@code false} otherwise
+ */
@Override
public boolean containsKey(long key) {
int bucket = getBucket(key);
@@ -46,6 +67,17 @@ public long get(long key) {
}
}
+ /**
+ * Inserts or updates the mapping for the specified key with the given value.
+ *
+ * This method employs a busy-waiting strategy to acquire the write lock on the bucket corresponding to the key.
+ * Once the lock is obtained, it updates the underlying map and returns the previous value associated with the key,
+ * or the default value if the key was not present.
+ *
+ * @param key the key whose mapping is to be updated
+ * @param value the value to associate with the key
+ * @return the previous value associated with the key, or the default value if the key did not have a mapping
+ */
@Override
public long put(long key, long value) {
int bucket = getBucket(key);
@@ -64,6 +96,14 @@ public long put(long key, long value) {
}
}
+ /**
+ * Removes the mapping for the specified key.
+ *
+ * This method repeatedly attempts to acquire the write lock for the bucket associated with the given key using a busy-waiting strategy. Once the lock is acquired, it removes and returns the value associated with the key from the underlying map.
+ *
+ * @param key the key whose mapping is to be removed
+ * @return the value previously associated with the key, or the default value if the key was not present
+ */
@Override
public long remove(long key) {
int bucket = getBucket(key);
diff --git a/src/main/java/com/trivago/fastutilconcurrentwrapper/longkey/ConcurrentBusyWaitingLongObjectMap.java b/src/main/java/com/trivago/fastutilconcurrentwrapper/longkey/ConcurrentBusyWaitingLongObjectMap.java
index 76e2352..373018c 100644
--- a/src/main/java/com/trivago/fastutilconcurrentwrapper/longkey/ConcurrentBusyWaitingLongObjectMap.java
+++ b/src/main/java/com/trivago/fastutilconcurrentwrapper/longkey/ConcurrentBusyWaitingLongObjectMap.java
@@ -6,10 +6,28 @@
import java.util.function.BiFunction;
public class ConcurrentBusyWaitingLongObjectMap This method repeatedly attempts to acquire a read lock for the bucket corresponding
+ * to the specified key using busy waiting. Once the lock is acquired, it returns whether
+ * the underlying bucket map contains the key. This method returns the value mapped to the key if present; otherwise, it returns
+ * the default value. It acquires the corresponding bucket's read lock using a busy waiting approach,
+ * continuously yielding with {@code Thread.onSpinWait()} until the lock is obtained.
+ *
+ * @param key the key whose associated value is to be retrieved
+ * @return the value associated with the key, or the default value if the key is not present
+ */
@Override
public V get (long key) {
int bucket = getBucket(key);
@@ -46,6 +74,17 @@ public V get (long key) {
}
}
+ /**
+ * Inserts or updates the mapping for the specified key using busy waiting for write lock acquisition.
+ *
+ * This method determines the corresponding bucket for the key and repeatedly attempts to acquire the
+ * write lock. Once the lock is held, it delegates the put operation to the underlying bucket map and returns
+ * the previous value associated with the key, if any.
+ *
+ * @param key the key for which the value is being stored
+ * @param value the new value to associate with the key
+ * @return the previous value associated with the key, or null if no mapping existed
+ */
@Override
public V put (long key, V value) {
int bucket = getBucket(key);
@@ -64,6 +103,16 @@ public V put (long key, V value) {
}
}
+ /**
+ * Removes the entry associated with the specified key from the map.
+ *
+ * The method identifies the correct bucket for the key and continually attempts to acquire the bucket's
+ * write lock using busy waiting. When the lock is acquired, it removes the key from the corresponding bucket's
+ * underlying map.
+ *
+ * @param key the key whose mapping is to be removed
+ * @return the previous value associated with the key, or {@code null} if no mapping existed
+ */
@Override
public V remove (long key) {
int bucket = getBucket(key);
@@ -82,6 +131,14 @@ public V remove (long key) {
}
}
+ /**
+ * Conditionally removes the mapping for the specified key if it is currently associated with the given value.
+ * This method busy-waits to acquire a write lock on the bucket corresponding to the key before attempting removal.
+ *
+ * @param key the key whose mapping is to be removed
+ * @param value the expected value associated with the key
+ * @return true if the mapping was removed, false otherwise
+ */
@Override
public boolean remove (long key, V value) {
int bucket = getBucket(key);
@@ -100,6 +157,17 @@ public boolean remove (long key, V value) {
}
}
+ /**
+ * Computes and stores a value for the specified key if it is not already present.
+ *
+ * This method identifies the bucket corresponding to the key and employs a busy waiting loop to acquire its
+ * write lock. Once the lock is acquired, if the key is absent, the provided mapping function is used to compute
+ * and store the value, which is then returned. This method continually attempts to acquire a write lock on the bucket corresponding to the key using a busy-wait loop.
+ * Once the lock is acquired, if the key exists, it applies the provided mapping function to compute and update the value associated with the key.
+ *
+ * @param key the key whose associated value is to be computed
+ * @param mappingFunction a function that takes the key and its current value and returns the new value
+ * @return the new value associated with the specified key, or {@code null} if the key was not present
+ */
@Override
public V computeIfPresent (long key, BiFunction This constructor partitions the map into multiple buckets to improve concurrency. Each bucket is
+ * initialized as a Long2FloatOpenHashMap with the specified initial capacity and load factor. The provided
+ * default value is used as the fallback when a key is not present in the map. This method calculates the appropriate bucket for the key, acquires a read lock on that bucket,
+ * and then verifies if the key exists in the corresponding sub-map in a thread-safe manner.
+ *
+ * @param key the key to check for presence in the map
+ * @return {@code true} if the key exists in the map; {@code false} otherwise
+ */
public boolean containsKey(long key) {
int bucket = getBucket(key);
@@ -45,6 +77,15 @@ public boolean containsKey(long key) {
}
}
+ /**
+ * Retrieves the float value associated with the specified key.
+ *
+ * This method identifies the corresponding bucket for the key, locks it for thread-safe access, and
+ * returns the associated value if present. If the key is not found, it returns the default value.
+ *
+ * @param key the key whose associated value is to be returned
+ * @return the value associated with the key, or the default value if the key is absent
+ */
public float get(long key) {
int bucket = getBucket(key);
@@ -57,6 +98,16 @@ public float get(long key) {
}
}
+ /**
+ * Inserts or updates the float value associated with the specified key in a thread-safe manner.
+ *
+ * This method acquires a write lock on the bucket determined by the key, updates the mapping,
+ * and returns the previous value associated with the key, or the default value if the key was absent. This method locates the bucket corresponding to the key, acquires the write lock to ensure thread safety,
+ * and removes the associated value. If the key is not present, the default value is returned.
+ *
+ * @param key the key whose mapping is to be removed
+ * @return the previous value associated with the key, or the default value if no mapping existed
+ */
public float remove(long key) {
int bucket = getBucket(key);
@@ -81,6 +141,17 @@ public float remove(long key) {
}
}
+ /**
+ * Conditionally removes the mapping for the specified key if it is currently associated with the given value.
+ *
+ * The method acquires a write lock on the bucket corresponding to the key to ensure a thread-safe removal.
+ * If the key is mapped to the provided value, the mapping is removed and the method returns true;
+ * otherwise, the map remains unchanged and the method returns false. If the key is not already present in the map, the provided mapping function is applied
+ * to compute a new value, which is then stored and returned. If the key is already mapped,
+ * its existing value is returned. This method acquires a write lock on the bucket corresponding to the key, ensuring thread-safe updates.
+ * If the key exists, the provided {@code mappingFunction} is applied to the current key-value pair. If the
+ * function returns a non-null value, the map is updated with this new value; if it returns {@code null}, the key
+ * is removed from the map. The returned builder supports configuration of map parameters such as the number of buckets,
+ * initial capacity, load factor, and default value. Depending on the configured map mode, the builder
+ * constructs either a busy-waiting variant (ConcurrentBusyWaitingLongFloatMap) or a blocking variant
+ * (ConcurrentLongFloatMap). If no default value is provided, it defaults to 0. This constructor partitions the map into a fixed number of buckets, where each bucket is a Long2IntOpenHashMap
+ * initialized with the given capacity and load factor. The provided default value is used to represent absent keys. This method provides access to the underlying map for a given bucket, allowing retrieval
+ * of integer values associated with long keys. This method determines the appropriate bucket for the given key, acquires a read lock to ensure thread safety,
+ * and verifies if the key exists in that bucket.
+ * This method determines the appropriate bucket for the key, acquires a read lock on that bucket,
+ * and then returns the corresponding integer value. If the key is not present in the map, the default value is returned.
+ * This method acquires the write lock for the bucket corresponding to the key to ensure thread safety.
+ * If the key was already present, the method returns the previous value; otherwise, it returns the default value.
+ *
+ * @param key the key for the value to be inserted or updated
+ * @param value the value to be associated with the key
+ * @return the previous value associated with the key, or the default value if the key was not present
+ */
public int put(long key, int value) {
int bucket = getBucket(key);
@@ -67,8 +116,22 @@ public int put(long key, int value) {
}
}
- public int getDefaultValue (){ return defaultValue; }
-
+ /**
+ * Retrieves the default integer value used when a key is not found in the map.
+ *
+ * @return the default value configured for missing keys.
+ */
+public int getDefaultValue (){ return defaultValue; }
+
+ /**
+ * Removes the mapping for the specified key from the map.
+ *
+ * This method determines the bucket corresponding to the given key, acquires an exclusive write lock on that bucket,
+ * and removes the mapping if it exists. It returns the value that was associated with the key, or the default value if no mapping was found. This method acquires a write lock on the bucket corresponding to the key to ensure thread safety.
+ * It only removes the entry if the current mapping matches the given value.
+ * If the key is not already mapped, this method applies the provided mapping function to
+ * compute a new value, inserts it into the map, and returns the computed value. If the key
+ * is already mapped, the existing value is returned.
+ *
+ * @param key the key for which the value is to be computed
+ * @param mappingFunction the function used to compute a value from the key if absent
+ * @return the current (existing or computed) value associated with the key
+ */
public int computeIfAbsent(long key, Long2IntFunction mappingFunction) {
int bucket = getBucket(key);
@@ -105,6 +189,19 @@ public int computeIfAbsent(long key, Long2IntFunction mappingFunction) {
}
}
+ /**
+ * Computes a new value for the specified key if it is currently mapped to a value.
+ *
+ * This method determines the appropriate bucket for the given key and acquires its write lock
+ * to ensure thread safety. It then applies the provided mapping function to the key and its existing
+ * value. If the mapping function returns a non-null result, the key is updated with the new value;
+ * if it returns {@code null}, the key is removed from the map. This builder facilitates configuration of parameters such as bucket count, initial capacity, load factor, and
+ * default value. The {@code build()} method creates a new map instance based on the builder’s map mode: it returns a
+ * {@code ConcurrentBusyWaitingLongIntMap} for busy waiting mode or a {@code ConcurrentLongIntMap} for blocking mode.
+ * If no default value is provided, it defaults to 0. Each bucket is backed by a Long2LongOpenHashMap created with the provided initial capacity and load factor.
+ * The default value is returned when a key is not present in the map.
+ *
+ * @param numBuckets the number of buckets used to partition the map
+ * @param initialCapacity the initial capacity for each bucket's hash map
+ * @param loadFactor the load factor for each bucket's hash map
+ * @param defaultValue the value returned if a key is not found in the map
+ */
public ConcurrentLongLongMap(
int numBuckets,
int initialCapacity,
@@ -26,11 +37,25 @@ public ConcurrentLongLongMap(
maps[i] = new Long2LongOpenHashMap(initialCapacity, loadFactor);
}
+ /**
+ * Retrieves the map corresponding to the specified bucket index.
+ *
+ * @param index the index of the bucket to access
+ * @return the map function representing the bucket at the given index
+ */
@Override
protected final Function This method performs a thread-safe lookup by acquiring a read lock on the bucket corresponding to the given key.
+ *
+ * @param key the key to check
+ * @return {@code true} if the key is present, {@code false} otherwise
+ */
public boolean containsKey(long key) {
int bucket = getBucket(key);
@@ -43,6 +68,15 @@ public boolean containsKey(long key) {
}
}
+ /**
+ * Retrieves the value associated with the specified key.
+ *
+ * This method determines the appropriate bucket for the given key, acquires a read lock for thread safety,
+ * and returns the corresponding value. If the key is not present in the map, the default value is returned.
+ *
+ * @param key the key whose associated value is to be returned
+ * @return the value associated with the specified key, or the default value if the key is absent
+ */
public long get (long key) {
int bucket = getBucket(key);
@@ -55,6 +89,16 @@ public long get (long key) {
}
}
+ /**
+ * Inserts or updates the mapping for the specified key with the given value in a thread-safe manner.
+ *
+ * This method identifies the target bucket based on the key, acquires its write lock, and then performs the update.
+ * It returns the previous value associated with the key, or the map's default value if no mapping existed. This method acquires a write lock on the bucket corresponding to the key to ensure thread-safe removal. This method checks the mapping of the provided key and removes it if the associated value matches the specified value, ensuring thread-safe removal. This method retrieves the appropriate bucket for the given key and locks it for exclusive write access.
+ * If the key is absent, it computes the value using the provided mapping function, stores the computed value,
+ * and returns it. If the key is already mapped, the current value is returned.
+ *
+ * @param key the key for which the value is to be computed if absent
+ * @param mappingFunction the function to compute a value for the key if absent
+ * @return the existing or computed value associated with the key
+ */
public long computeIfAbsent(long key, Long2LongFunction mappingFunction) {
int bucket = getBucket(key);
@@ -105,6 +182,17 @@ public long computeIfAbsent(long key, Long2LongFunction mappingFunction) {
}
}
+ /**
+ * Atomically updates the value for the specified key if it is present.
+ *
+ * If the key exists, the provided remapping function is applied to its current value to compute a new
+ * value, which is then stored and returned. If the key is not present, the mapping function is not invoked
+ * and the map’s default value is returned.
+ *
+ * @param key the key for which the value should be updated if present
+ * @param mappingFunction the function that computes a new value given the key and its current value
+ * @return the new value associated with the key if present, or the default value otherwise
+ */
public long computeIfPresent(long key, BiFunction The returned builder allows configuration of parameters such as bucket count,
+ * initial capacity, load factor, and default value. Depending on the map mode set in the builder,
+ * the {@code build()} method will instantiate either a {@link ConcurrentBusyWaitingLongLongMap}
+ * (for busy waiting) or a {@link ConcurrentLongLongMap} (for blocking) with the specified configuration.
+ *
+ * @return a {@link PrimitiveMapBuilder} configured for building {@link ConcurrentLongLongMap} instances
+ */
public static PrimitiveMapBuilder This constructor initializes the map by creating the specified number of internal buckets,
+ * each as a Long2ObjectOpenHashMap configured with the given initial capacity and load factor.
+ * The provided default value is returned when a key is not mapped to any value. This method provides access to the internal map responsible for managing key-value pairs
+ * for a given bucket within the concurrent map. The returned function serves as the bucket's
+ * lookup mechanism for long keys.
+ *
+ * @param index the index of the bucket
+ * @return the mapping function associated with the specified bucket index
+ */
@Override
protected final Function This method performs a thread-safe lookup by acquiring a read lock on the bucket corresponding
+ * to the provided key.
+ *
+ * @param key the key to check for presence in the map
+ * @return {@code true} if the key exists in the map; {@code false} otherwise
+ */
public boolean containsKey(long key) {
int bucket = getBucket(key);
@@ -44,6 +75,14 @@ public boolean containsKey(long key) {
}
}
+ /**
+ * Retrieves the value associated with the specified key, or returns the default value if the key is not present.
+ *
+ * This method provides thread-safe access by employing a read lock on the bucket corresponding to the key.
+ *
+ * @param key the key whose associated value is to be returned
+ * @return the value mapped to the key, or the map's default value if the key is absent
+ */
public V get (long key) {
int bucket = getBucket(key);
@@ -56,6 +95,16 @@ public V get (long key) {
}
}
+ /**
+ * Inserts or updates the mapping for the specified key with the given value.
+ *
+ * This operation is thread-safe, as it acquires the write lock on the relevant bucket
+ * before updating the map.
+ * This operation is thread-safe, acquiring a write lock on the corresponding bucket.
+ * This method acquires a write lock on the corresponding bucket to ensure thread safety, and it removes the entry
+ * only when the current mapped value exactly matches the provided value.
+ * If the key is absent, the provided mapping function is applied to compute a value,
+ * which is then stored and returned. If the key already exists, its current value is returned.
+ * This operation is performed under a write lock to ensure thread safety.
+ *
+ * @param key the key for which a value is to be computed if absent
+ * @param mappingFunction the function to compute a value for the key
+ * @return the current (existing or computed) value associated with the key
+ */
public V computeIfAbsent (long key, Long2ObjectFunction The operation is performed under a write lock for thread safety. If the mapping
+ * function returns {@code null}, the mapping is removed.
+ *
+ * @param key the key for which the mapping is to be computed
+ * @param mappingFunction a function that accepts the current key and value, and returns
+ * a new value (or {@code null} to remove the mapping)
+ * @return the new value associated with the key, or {@code null} if the entry was removed
+ */
public V computeIfPresent (long key, BiFunction This builder enables configuration of the map's parameters. When the {@code build()} method
+ * is invoked, the builder creates an instance of either a busy waiting or a blocking
+ * concurrent map implementation based on the configured map mode. This constructor initializes the map with a fixed number of buckets for concurrent access,
+ * an initial capacity, a load factor to determine resizing thresholds, and a default value to return
+ * when a key is not present.
+ *
+ * @param numBuckets the number of buckets used for partitioning the map
+ * @param initialCapacity the initial capacity of the map
+ * @param loadFactor the load factor threshold for resizing the map
+ * @param defaultValue the default value to return for absent keys
+ */
public ConcurrentBusyWaitingObjectLongMap (int numBuckets, int initialCapacity, float loadFactor, long defaultValue) {
super(numBuckets, initialCapacity, loadFactor, defaultValue);
}
+ /**
+ * Checks if the map contains the specified key.
+ *
+ * This method identifies the bucket corresponding to the given key and continuously
+ * attempts to acquire its read lock using busy waiting. Once the lock is acquired, it
+ * checks whether the underlying map for that bucket contains the key.
+ *
+ * @param key the key to check for presence in the map
+ * @return {@code true} if the key is present, {@code false} otherwise
+ */
@Override
public boolean containsKey (K key) {
int bucket = getBucket(key);
@@ -28,6 +50,17 @@ public boolean containsKey (K key) {
}
}
+ /**
+ * Retrieves the value associated with the specified key.
+ *
+ *
+ * This method attempts to acquire a read lock on the bucket corresponding to the key using busy waiting.
+ * If the key is not found, the default value is returned.
+ * This method uses busy waiting to acquire a write lock on the bucket corresponding to the key,
+ * ensuring thread-safe update operations. Once the lock is obtained, the value for the key is updated,
+ * and the previous value (or the default value if no mapping existed) is returned.
+ *
+ * @param key the key to insert or update
+ * @param value the value to associate with the key
+ * @return the previous value associated with the key, or the default value if none was present
+ */
@Override
public long put (K key, long value) {
int bucket = getBucket(key);
@@ -64,6 +108,16 @@ public long put (K key, long value) {
}
}
+ /**
+ * Removes the entry for the specified key from the map and returns the associated value.
+ *
+ * This method repeatedly attempts to acquire the write lock for the bucket corresponding
+ * to the given key using busy waiting. Once the lock is acquired, it removes the key's entry
+ * from the underlying map.
+ *
+ * @param key the key for which the mapping is to be removed
+ * @return the value previously associated with the specified key, or the default value if no mapping existed
+ */
@Override
public long remove (K key) {
int bucket = getBucket(key);
@@ -82,6 +136,17 @@ public long remove (K key) {
}
}
+ /**
+ * Removes the mapping for the specified key only if it is currently associated with the given value.
+ *
+ * This method busy-waits to acquire a write lock on the bucket corresponding to the key.
+ * Once the lock is obtained, it conditionally removes the entry from the underlying map.
+ *
+ * This method busy-waits until a write lock for the key’s bucket is acquired. If the key is not present, the mapping function is
+ * applied to compute its value, which is then stored and returned.
+ *
+ * @param key the key for which the value is to be computed if absent
+ * @param mappingFunction the function to compute the value if the key is not already associated with one
+ * @return the existing or newly computed value associated with the key
+ */
@Override
public long computeIfAbsent (K key, Object2LongFunction
+ * This method busy-waits to acquire a write lock on the bucket associated with the key to ensure thread-safe updates.
+ * If the key is present, the provided mapping function is applied to compute a new value, which then replaces the existing value.
+ * If the key is not present, the map returns its default value.
+ * This constructor creates a concurrent map that divides its data into a set number of buckets,
+ * each backed by an Object2LongOpenHashMap. The specified initial capacity and load factor configure
+ * each bucket's underlying map, while the default value is returned for keys that are not present. This method acquires the read lock on the corresponding bucket to ensure thread-safe access when determining
+ * whether the key is present in the map. If the key is not present, the default value is returned. This method ensures thread-safe access by acquiring
+ * the read lock on the bucket corresponding to the key.
+ *
+ * @param key the key whose associated value is to be returned
+ * @return the value associated with the key, or the default value if no mapping exists
+ */
public long get (K key) {
int bucket = getBucket(key);
@@ -56,6 +92,18 @@ public long get (K key) {
}
}
+ /**
+ * Associates the specified long value with the specified key in the map.
+ *
+ *
+ * Acquires a write lock on the bucket corresponding to the key to ensure thread safety and returns
+ * the previous value associated with the key, or the default value if no prior mapping existed.
+ * This method acquires a write lock on the bucket corresponding to the key to ensure thread-safe removal.
+ *
+ * @param key the key whose mapping is to be removed
+ * @return the value previously associated with the key, or the default value if the key was not present
+ */
public long remove (K key) {
int bucket = getBucket(key);
@@ -82,6 +145,17 @@ public long remove (K key) {
}
}
+ /**
+ * Removes the mapping for the specified key only if it is currently associated with the provided value.
+ *
+ * This method acquires a write lock on the bucket containing the key to ensure thread safety.
+ * If the current value mapped to the key matches the given value, the entry is removed and {@code true}
+ * is returned; otherwise, the map remains unchanged and {@code false} is returned.
+ *
+ * @param key the key whose mapping is to be conditionally removed
+ * @param value the expected value associated with the key
+ * @return {@code true} if the key-value pair was successfully removed, otherwise {@code false}
+ */
public boolean remove (K key, long value) {
int bucket = getBucket(key);
@@ -94,6 +168,17 @@ public boolean remove (K key, long value) {
}
}
+ /**
+ * Computes a value for the specified key if it is not already associated with one.
+ *
+ * This method acquires a write lock on the corresponding bucket to ensure thread safety.
+ * If no value exists for the key, the provided mapping function is used to compute and store a new value.
+ * The current (existing or computed) value is then returned. If the key exists, the provided mapping function is applied to the key and its current value to compute a new value,
+ * which then replaces the old value. This method acquires a write lock on the corresponding bucket to ensure thread safety.
+ * If the key is not present, the mapping function is not invoked and the map remains unchanged. The returned builder supports different concurrency modes. When the map mode is set to
+ * {@code BUSY_WAITING}, the builder produces an instance of {@link ConcurrentBusyWaitingObjectLongMap};
+ * when set to {@code BLOCKING}, it produces a standard {@link ConcurrentObjectLongMap}.
+ *
+ *
+ *
+ *
+ * The operation is selected using a thread-local random generator.
+ */
@Override
public void testAllOps() {
int op = ThreadLocalRandom.current().nextInt(3);
diff --git a/src/jmh/java/com/trivago/kangaroo/object2long/JavaUtilWrapperObjectLongBenchmark.java b/src/jmh/java/com/trivago/kangaroo/object2long/JavaUtilWrapperObjectLongBenchmark.java
index d794de2..c6e7db7 100644
--- a/src/jmh/java/com/trivago/kangaroo/object2long/JavaUtilWrapperObjectLongBenchmark.java
+++ b/src/jmh/java/com/trivago/kangaroo/object2long/JavaUtilWrapperObjectLongBenchmark.java
@@ -20,6 +20,13 @@ public class JavaUtilWrapperObjectLongBenchmark extends AbstractCommonBenchHelpe
Map
+ *
+ * Each operation uses a freshly created instance of {@code TestObjectKey}. Note that no operation result is returned.
+ *