Skip to content

Commit 987fce3

Browse files
Add support for longintmap (#14)
* 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
1 parent a665d67 commit 987fce3

18 files changed

+967
-130
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ _Note_: currently the lib contains wrappers not for every primitive map. Feel fr
3232
<dependency>
3333
<groupId>com.trivago</groupId>
3434
<artifactId>fastutil-concurrent-wrapper</artifactId>
35-
<version>0.2.1</version>
35+
<version>0.2.2</version>
3636
</dependency>
3737
```
3838

build.gradle

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ allprojects {
1616
}
1717

1818
group 'com.trivago'
19-
version '0.2.2-SNAPSHOT'
19+
version '0.2.2'
2020

2121
mavenPublishing {
2222
pom {
@@ -41,6 +41,11 @@ mavenPublishing {
4141
name = "Fehim Erdogan"
4242
url = "https://github.com/erdoganf"
4343
}
44+
developer {
45+
id = "sarveswaran-m"
46+
name = "Sarveswaran Meenakshisundaram"
47+
url = "https://github.com/sarveswaran-m"
48+
}
4449
}
4550
scm {
4651
url = "https://github.com/trivago/fastutil-concurrent-wrapper"
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package com.trivago.fastutilconcurrentwrapper;
2+
3+
import com.trivago.fastutilconcurrentwrapper.map.ConcurrentBusyWaitingLongIntMap;
4+
import com.trivago.fastutilconcurrentwrapper.map.ConcurrentLongIntMap;
5+
6+
public final class ConcurrentLongIntMapBuilder {
7+
private MapMode mapMode = MapMode.BLOCKING;
8+
private int buckets = 8;
9+
private int initialCapacity = 100_000;
10+
private float loadFactor = 0.8f;
11+
private int defaultValue = LongIntMap.DEFAULT_VALUE;
12+
13+
private ConcurrentLongIntMapBuilder() {
14+
15+
}
16+
17+
public static ConcurrentLongIntMapBuilder newBuilder() {
18+
return new ConcurrentLongIntMapBuilder();
19+
}
20+
21+
public ConcurrentLongIntMapBuilder withBuckets(int buckets) {
22+
this.buckets = buckets;
23+
return this;
24+
}
25+
26+
public ConcurrentLongIntMapBuilder withInitialCapacity(int initialCapacity) {
27+
this.initialCapacity = initialCapacity;
28+
return this;
29+
}
30+
31+
public ConcurrentLongIntMapBuilder withLoadFactor(float loadFactor) {
32+
this.loadFactor = loadFactor;
33+
return this;
34+
}
35+
36+
public ConcurrentLongIntMapBuilder withMode(MapMode mapMode) {
37+
this.mapMode = mapMode;
38+
return this;
39+
}
40+
41+
public ConcurrentLongIntMapBuilder withDefaultValue(int defaultValue) {
42+
this.defaultValue = defaultValue;
43+
return this;
44+
}
45+
46+
public LongIntMap build() {
47+
return mapMode.createMap(this);
48+
}
49+
50+
public enum MapMode {
51+
BUSY_WAITING {
52+
@Override
53+
LongIntMap createMap(ConcurrentLongIntMapBuilder builder) {
54+
return new ConcurrentBusyWaitingLongIntMap(
55+
builder.buckets,
56+
builder.initialCapacity,
57+
builder.loadFactor,
58+
builder.defaultValue);
59+
}
60+
},
61+
BLOCKING {
62+
@Override
63+
LongIntMap createMap(ConcurrentLongIntMapBuilder builder) {
64+
return new ConcurrentLongIntMap(
65+
builder.buckets,
66+
builder.initialCapacity,
67+
builder.loadFactor,
68+
builder.defaultValue);
69+
}
70+
};
71+
72+
abstract LongIntMap createMap(ConcurrentLongIntMapBuilder builder);
73+
}
74+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.trivago.fastutilconcurrentwrapper;
2+
3+
import it.unimi.dsi.fastutil.longs.Long2IntFunction;
4+
5+
import java.util.function.BiFunction;
6+
7+
public interface LongIntMap extends PrimitiveLongKeyMap {
8+
9+
int DEFAULT_VALUE = 0;
10+
11+
/**
12+
* @param key key to get
13+
* @return configured LongIntMap.getDefaultValue(), if the key is not present
14+
*/
15+
int get(long key);
16+
17+
int put(long key, int value);
18+
19+
int getDefaultValue();
20+
21+
int remove(long key);
22+
23+
boolean remove(long key, int value);
24+
25+
int computeIfAbsent(long key, Long2IntFunction mappingFunction);
26+
27+
int computeIfPresent(long key, BiFunction<Long, Integer, Integer> mappingFunction);
28+
}
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
package com.trivago.fastutilconcurrentwrapper.map;
2+
3+
import com.trivago.fastutilconcurrentwrapper.LongIntMap;
4+
import com.trivago.fastutilconcurrentwrapper.LongLongMap;
5+
import com.trivago.fastutilconcurrentwrapper.wrapper.PrimitiveFastutilLongIntWrapper;
6+
import com.trivago.fastutilconcurrentwrapper.wrapper.PrimitiveFastutilLongLongWrapper;
7+
import it.unimi.dsi.fastutil.longs.Long2IntFunction;
8+
import it.unimi.dsi.fastutil.longs.Long2LongFunction;
9+
10+
import java.util.concurrent.locks.Lock;
11+
import java.util.function.BiFunction;
12+
13+
public class ConcurrentBusyWaitingLongIntMap extends PrimitiveConcurrentMap implements LongIntMap {
14+
15+
private final LongIntMap[] maps;
16+
private final int defaultValue;
17+
18+
public ConcurrentBusyWaitingLongIntMap(int numBuckets,
19+
int initialCapacity,
20+
float loadFactor,
21+
int defaultValue) {
22+
super(numBuckets);
23+
24+
this.maps = new LongIntMap[numBuckets];
25+
this.defaultValue = defaultValue;
26+
27+
for (int i = 0; i < numBuckets; i++) {
28+
maps[i] = new PrimitiveFastutilLongIntWrapper(initialCapacity, loadFactor, defaultValue);
29+
}
30+
}
31+
32+
@Override
33+
public int size() {
34+
return super.size(maps);
35+
}
36+
37+
@Override
38+
public boolean isEmpty() {
39+
return super.isEmpty(maps);
40+
}
41+
42+
@Override
43+
public boolean containsKey(long key) {
44+
int bucket = getBucket(key);
45+
46+
Lock readLock = locks[bucket].readLock();
47+
48+
while (true) {
49+
if (readLock.tryLock()) {
50+
try {
51+
return maps[bucket].containsKey(key);
52+
} finally {
53+
readLock.unlock();
54+
}
55+
}
56+
}
57+
}
58+
59+
@Override
60+
public int get(long key) {
61+
int bucket = getBucket(key);
62+
63+
Lock readLock = locks[bucket].readLock();
64+
65+
while (true) {
66+
if (readLock.tryLock()) {
67+
try {
68+
return maps[bucket].get(key);
69+
} finally {
70+
readLock.unlock();
71+
}
72+
}
73+
}
74+
}
75+
76+
@Override
77+
public int put(long key, int value) {
78+
int bucket = getBucket(key);
79+
80+
Lock writeLock = locks[bucket].writeLock();
81+
82+
while (true) {
83+
if (writeLock.tryLock()) {
84+
try {
85+
return maps[bucket].put(key, value);
86+
} finally {
87+
writeLock.unlock();
88+
}
89+
}
90+
}
91+
}
92+
93+
@Override
94+
public int getDefaultValue() {
95+
return defaultValue;
96+
}
97+
98+
@Override
99+
public int remove(long key) {
100+
int bucket = getBucket(key);
101+
102+
Lock writeLock = locks[bucket].writeLock();
103+
104+
while (true) {
105+
if (writeLock.tryLock()) {
106+
try {
107+
return maps[bucket].remove(key);
108+
} finally {
109+
writeLock.unlock();
110+
}
111+
}
112+
}
113+
}
114+
115+
@Override
116+
public boolean remove(long key, int value) {
117+
int bucket = getBucket(key);
118+
119+
Lock writeLock = locks[bucket].writeLock();
120+
121+
while (true) {
122+
if (writeLock.tryLock()) {
123+
try {
124+
return maps[bucket].remove(key, value);
125+
} finally {
126+
writeLock.unlock();
127+
}
128+
}
129+
}
130+
}
131+
132+
@Override
133+
public int computeIfAbsent(long key, Long2IntFunction mappingFunction) {
134+
int bucket = getBucket(key);
135+
136+
Lock writeLock = locks[bucket].writeLock();
137+
138+
while (true) {
139+
if (writeLock.tryLock()) {
140+
try {
141+
return maps[bucket].computeIfAbsent(key, mappingFunction);
142+
} finally {
143+
writeLock.unlock();
144+
}
145+
}
146+
}
147+
}
148+
149+
@Override
150+
public int computeIfPresent(long key, BiFunction<Long, Integer, Integer> mappingFunction) {
151+
int bucket = getBucket(key);
152+
153+
Lock writeLock = locks[bucket].writeLock();
154+
155+
while (true) {
156+
if (writeLock.tryLock()) {
157+
try {
158+
return maps[bucket].computeIfPresent(key, mappingFunction);
159+
} finally {
160+
writeLock.unlock();
161+
}
162+
}
163+
}
164+
}
165+
}

0 commit comments

Comments
 (0)