-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add support for LongIntMap * Update list of developers & bump up java version to 17 * Add unit-tests for IntMap implementations * Add unit-tests for IntMap builder * Add unit-tests for IntMap builder * Fix code-convention violations * Bump up to 0.2.2
- Loading branch information
1 parent
a665d67
commit 987fce3
Showing
18 changed files
with
967 additions
and
130 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
src/main/java/com/trivago/fastutilconcurrentwrapper/ConcurrentLongIntMapBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
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); | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
src/main/java/com/trivago/fastutilconcurrentwrapper/LongIntMap.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.trivago.fastutilconcurrentwrapper; | ||
|
||
import it.unimi.dsi.fastutil.longs.Long2IntFunction; | ||
|
||
import java.util.function.BiFunction; | ||
|
||
public interface LongIntMap extends PrimitiveLongKeyMap { | ||
|
||
int DEFAULT_VALUE = 0; | ||
|
||
/** | ||
* @param key key to get | ||
* @return configured LongIntMap.getDefaultValue(), if the key is not present | ||
*/ | ||
int get(long key); | ||
|
||
int put(long key, int value); | ||
|
||
int getDefaultValue(); | ||
|
||
int remove(long key); | ||
|
||
boolean remove(long key, int value); | ||
|
||
int computeIfAbsent(long key, Long2IntFunction mappingFunction); | ||
|
||
int computeIfPresent(long key, BiFunction<Long, Integer, Integer> mappingFunction); | ||
} |
165 changes: 165 additions & 0 deletions
165
src/main/java/com/trivago/fastutilconcurrentwrapper/map/ConcurrentBusyWaitingLongIntMap.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
package com.trivago.fastutilconcurrentwrapper.map; | ||
|
||
import com.trivago.fastutilconcurrentwrapper.LongIntMap; | ||
import com.trivago.fastutilconcurrentwrapper.LongLongMap; | ||
import com.trivago.fastutilconcurrentwrapper.wrapper.PrimitiveFastutilLongIntWrapper; | ||
import com.trivago.fastutilconcurrentwrapper.wrapper.PrimitiveFastutilLongLongWrapper; | ||
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; | ||
|
||
public class ConcurrentBusyWaitingLongIntMap extends PrimitiveConcurrentMap implements LongIntMap { | ||
|
||
private final LongIntMap[] maps; | ||
private final int defaultValue; | ||
|
||
public ConcurrentBusyWaitingLongIntMap(int numBuckets, | ||
int initialCapacity, | ||
float loadFactor, | ||
int defaultValue) { | ||
super(numBuckets); | ||
|
||
this.maps = new LongIntMap[numBuckets]; | ||
this.defaultValue = defaultValue; | ||
|
||
for (int i = 0; i < numBuckets; i++) { | ||
maps[i] = new PrimitiveFastutilLongIntWrapper(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 int 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 int put(long 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(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, 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(long key, Long2IntFunction 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(long key, BiFunction<Long, Integer, Integer> 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(); | ||
} | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.