Skip to content

Commit 7b5041c

Browse files
committed
remove any Reentrant locks in favor of a CAS linked list
1 parent 77bac05 commit 7b5041c

File tree

7 files changed

+161
-153
lines changed

7 files changed

+161
-153
lines changed

src/main/java/org/dataloader/CacheMap.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ static <K, V> CacheMap<K, V> simpleMap() {
9090
*
9191
* @return the cache map for fluent coding
9292
*/
93-
CacheMap<K, V> set(K key, CompletableFuture<V> value);
93+
CompletableFuture<V> setIfAbsent(K key, CompletableFuture<V> value);
9494

9595
/**
9696
* Deletes the entry with the specified key from the cache map, if it exists.

src/main/java/org/dataloader/DataLoader.java

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@
3535
import java.util.Map;
3636
import java.util.Optional;
3737
import java.util.concurrent.CompletableFuture;
38-
import java.util.concurrent.locks.Lock;
39-
import java.util.concurrent.locks.ReentrantLock;
4038
import java.util.function.BiConsumer;
4139
import java.util.function.Consumer;
4240

@@ -65,6 +63,7 @@
6563
*
6664
* @param <K> type parameter indicating the type of the data load keys
6765
* @param <V> type parameter indicating the type of the data that is returned
66+
*
6867
* @author <a href="https://github.com/aschrijver/">Arnold Schrijver</a>
6968
* @author <a href="https://github.com/bbakerman/">Brad Baker</a>
7069
*/
@@ -79,7 +78,6 @@ public class DataLoader<K, V extends @Nullable Object> {
7978
private final ValueCache<K, V> valueCache;
8079
private final DataLoaderOptions options;
8180
private final Object batchLoadFunction;
82-
final Lock lock;
8381

8482
@VisibleForTesting
8583
DataLoader(@Nullable String name, Object batchLoadFunction, @Nullable DataLoaderOptions options) {
@@ -96,7 +94,6 @@ public class DataLoader<K, V extends @Nullable Object> {
9694
this.batchLoadFunction = nonNull(batchLoadFunction);
9795
this.options = loaderOptions;
9896
this.name = name;
99-
this.lock = new ReentrantLock();
10097
this.helper = new DataLoaderHelper<>(this, batchLoadFunction, loaderOptions, this.futureCache, this.valueCache, this.stats, clock);
10198
}
10299

@@ -136,6 +133,7 @@ public Object getBatchLoadFunction() {
136133
* This allows you to change the current {@link DataLoader} and turn it into a new one
137134
*
138135
* @param builderConsumer the {@link DataLoaderFactory.Builder} consumer for changing the {@link DataLoader}
136+
*
139137
* @return a newly built {@link DataLoader} instance
140138
*/
141139
public DataLoader<K, V> transform(Consumer<DataLoaderFactory.Builder<K, V>> builderConsumer) {
@@ -170,6 +168,7 @@ public Duration getTimeSinceDispatch() {
170168
* and returned from cache).
171169
*
172170
* @param key the key to load
171+
*
173172
* @return the future of the value
174173
*/
175174
public CompletableFuture<V> load(K key) {
@@ -187,6 +186,7 @@ public CompletableFuture<V> load(K key) {
187186
* NOTE : This will NOT cause a data load to happen. You must call {@link #load(Object)} for that to happen.
188187
*
189188
* @param key the key to check
189+
*
190190
* @return an Optional to the future of the value
191191
*/
192192
public Optional<CompletableFuture<V>> getIfPresent(K key) {
@@ -205,6 +205,7 @@ public Optional<CompletableFuture<V>> getIfPresent(K key) {
205205
* NOTE : This will NOT cause a data load to happen. You must call {@link #load(Object)} for that to happen.
206206
*
207207
* @param key the key to check
208+
*
208209
* @return an Optional to the future of the value
209210
*/
210211
public Optional<CompletableFuture<V>> getIfCompleted(K key) {
@@ -224,6 +225,7 @@ public Optional<CompletableFuture<V>> getIfCompleted(K key) {
224225
*
225226
* @param key the key to load
226227
* @param keyContext a context object that is specific to this key
228+
*
227229
* @return the future of the value
228230
*/
229231
public CompletableFuture<V> load(@NonNull K key, @Nullable Object keyContext) {
@@ -239,6 +241,7 @@ public CompletableFuture<V> load(@NonNull K key, @Nullable Object keyContext) {
239241
* and returned from cache).
240242
*
241243
* @param keys the list of keys to load
244+
*
242245
* @return the composite future of the list of values
243246
*/
244247
public CompletableFuture<List<V>> loadMany(List<K> keys) {
@@ -258,6 +261,7 @@ public CompletableFuture<List<V>> loadMany(List<K> keys) {
258261
*
259262
* @param keys the list of keys to load
260263
* @param keyContexts the list of key calling context objects
264+
*
261265
* @return the composite future of the list of values
262266
*/
263267
public CompletableFuture<List<V>> loadMany(List<K> keys, List<Object> keyContexts) {
@@ -288,6 +292,7 @@ public CompletableFuture<List<V>> loadMany(List<K> keys, List<Object> keyContext
288292
* {@link org.dataloader.MappedBatchLoaderWithContext} to help retrieve data.
289293
*
290294
* @param keysAndContexts the map of keys to their respective contexts
295+
*
291296
* @return the composite future of the map of keys and values
292297
*/
293298
public CompletableFuture<Map<K, V>> loadMany(Map<K, ?> keysAndContexts) {
@@ -358,6 +363,7 @@ public int dispatchDepth() {
358363
* on the next load request.
359364
*
360365
* @param key the key to remove
366+
*
361367
* @return the data loader for fluent coding
362368
*/
363369
public DataLoader<K, V> clear(K key) {
@@ -371,17 +377,13 @@ public DataLoader<K, V> clear(K key) {
371377
*
372378
* @param key the key to remove
373379
* @param handler a handler that will be called after the async remote clear completes
380+
*
374381
* @return the data loader for fluent coding
375382
*/
376383
public DataLoader<K, V> clear(K key, BiConsumer<Void, Throwable> handler) {
377384
Object cacheKey = getCacheKey(key);
378-
try {
379-
lock.lock();
380-
futureCache.delete(cacheKey);
381-
valueCache.delete(key).whenComplete(handler);
382-
} finally {
383-
lock.unlock();
384-
}
385+
futureCache.delete(cacheKey);
386+
valueCache.delete(key).whenComplete(handler);
385387
return this;
386388
}
387389

@@ -399,16 +401,12 @@ public DataLoader<K, V> clearAll() {
399401
* Clears the entire cache map of the loader, and of the cached value store.
400402
*
401403
* @param handler a handler that will be called after the async remote clear all completes
404+
*
402405
* @return the data loader for fluent coding
403406
*/
404407
public DataLoader<K, V> clearAll(BiConsumer<Void, Throwable> handler) {
405-
try {
406-
lock.lock();
407-
futureCache.clear();
408-
valueCache.clear().whenComplete(handler);
409-
} finally {
410-
lock.unlock();
411-
}
408+
futureCache.clear();
409+
valueCache.clear().whenComplete(handler);
412410
return this;
413411
}
414412

@@ -419,6 +417,7 @@ public DataLoader<K, V> clearAll(BiConsumer<Void, Throwable> handler) {
419417
*
420418
* @param key the key
421419
* @param value the value
420+
*
422421
* @return the data loader for fluent coding
423422
*/
424423
public DataLoader<K, V> prime(K key, V value) {
@@ -430,6 +429,7 @@ public DataLoader<K, V> prime(K key, V value) {
430429
*
431430
* @param key the key
432431
* @param error the exception to prime instead of a value
432+
*
433433
* @return the data loader for fluent coding
434434
*/
435435
public DataLoader<K, V> prime(K key, Exception error) {
@@ -443,18 +443,12 @@ public DataLoader<K, V> prime(K key, Exception error) {
443443
*
444444
* @param key the key
445445
* @param value the value
446+
*
446447
* @return the data loader for fluent coding
447448
*/
448449
public DataLoader<K, V> prime(K key, CompletableFuture<V> value) {
449450
Object cacheKey = getCacheKey(key);
450-
try {
451-
lock.lock();
452-
if (!futureCache.containsKey(cacheKey)) {
453-
futureCache.set(cacheKey, value);
454-
}
455-
} finally {
456-
lock.unlock();
457-
}
451+
futureCache.setIfAbsent(cacheKey, value);
458452
return this;
459453
}
460454

@@ -465,6 +459,7 @@ public DataLoader<K, V> prime(K key, CompletableFuture<V> value) {
465459
* If no cache key function is present in {@link DataLoaderOptions}, then the returned value equals the input key.
466460
*
467461
* @param key the input key
462+
*
468463
* @return the cache key after the input is transformed with the cache key function
469464
*/
470465
public Object getCacheKey(K key) {
@@ -503,8 +498,8 @@ public ValueCache<K, V> getValueCache() {
503498
@Override
504499
public String toString() {
505500
return "DataLoader{" +
506-
"name='" + name + '\'' +
507-
", stats=" + stats +
508-
'}';
501+
"name='" + name + '\'' +
502+
", stats=" + stats +
503+
'}';
509504
}
510505
}

0 commit comments

Comments
 (0)