Skip to content

Commit 161adec

Browse files
committed
PR feedback - name of ValueCache
1 parent ccbf15a commit 161adec

10 files changed

+73
-65
lines changed

README.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -322,13 +322,13 @@ will be given the same future and hence the same value.
322322

323323
This cache can only work local to the JVM, since its caches `CompletableFuture`s which cannot be serialised across a network say.
324324

325-
The second level cache is a value cache represented by the interface `org.dataloader.CachedValueStore`. By default, this is not enabled and is a no-op.
325+
The second level cache is a value cache represented by the interface `org.dataloader.ValueCache`. By default, this is not enabled and is a no-op.
326326

327327
The value cache uses an async API pattern to encapsulate the idea that the value cache could be in a remote place such as REDIS or Memcached.
328328

329329
## Custom future caches
330330

331-
The default cache behind `DataLoader` is an in memory `HashMap`. There is no expiry on this, and it lives for as long as the data loader
331+
The default future cache behind `DataLoader` is an in memory `HashMap`. There is no expiry on this, and it lives for as long as the data loader
332332
lives.
333333

334334
However, you can create your own custom cache and supply it to the data loader on construction via the `org.dataloader.CacheMap` interface.
@@ -346,13 +346,15 @@ As stated above, a custom `org.dataloader.CacheMap` is a local cache of futures
346346

347347
## Custom value caches
348348

349-
You will need to create your own implementations of the `org.dataloader.CachedValueStore` if your want to use an external cache.
349+
You will need to create your own implementations of the `org.dataloader.ValueCache` if your want to use an external cache.
350350

351-
This library does not ship with any implementations of `CachedValueStore` because it does not want to have
352-
production dependencies on external cache libraries.
351+
This library does not ship with any implementations of `ValueCache` because it does not want to have
352+
production dependencies on external cache libraries, but you can easily write your own.
353353

354-
The API of `CachedValueStore` has been designed to be asynchronous because it is expected that the value cache could be outside
355-
your JVM. It uses `Future`s to get and set values into cache, which may involve a network call and hence exceptional failures to get
354+
The tests have an example based on [Caffeine](https://github.com/ben-manes/caffeine).
355+
356+
The API of `ValueCache` has been designed to be asynchronous because it is expected that the value cache could be outside
357+
your JVM. It uses `CompleteableFuture`s to get and set values into cache, which may involve a network call and hence exceptional failures to get
356358
or set values.
357359

358360

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

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,14 @@
2222
import java.util.concurrent.CompletableFuture;
2323

2424
/**
25-
* Cache map interface for data loaders that use caching.
25+
* CacheMap is used by data loaders that use caching promises to values aka {@link CompletableFuture}<V>. A better name for this
26+
* class might have been FutureCache but that is history now.
2627
* <p>
27-
* The default implementation used by the data loader is based on a {@link java.util.LinkedHashMap}. Note that the
28-
* implementation could also have used a regular {@link java.util.Map} instead of this {@link CacheMap}, but
29-
* this aligns better to the reference data loader implementation provided by Facebook
28+
* The default implementation used by the data loader is based on a {@link java.util.LinkedHashMap}.
3029
* <p>
31-
* This is really a cache of completed {@link CompletableFuture} values in memory. It is used, when caching is enabled, to
32-
* give back the same future to any code that may call it. if you need a cache of the underlying values that is possible external to the JVM
33-
* then you will want to use {{@link CachedValueStore}} which is designed for external cache access.
30+
* This is really a cache of completed {@link CompletableFuture}&lt;V> values in memory. It is used, when caching is enabled, to
31+
* give back the same future to any code that may call it. If you need a cache of the underlying values that is possible external to the JVM
32+
* then you will want to use {{@link ValueCache}} which is designed for external cache access.
3433
*
3534
* @param <K> type parameter indicating the type of the cache keys
3635
* @param <V> type parameter indicating the type of the data that is cached

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public class DataLoader<K, V> {
6767
private final DataLoaderHelper<K, V> helper;
6868
private final StatisticsCollector stats;
6969
private final CacheMap<Object, V> futureCache;
70-
private final CachedValueStore<Object, V> cachedValueStore;
70+
private final ValueCache<Object, V> valueCache;
7171

7272
/**
7373
* Creates new DataLoader with the specified batch loader function and default options
@@ -416,11 +416,11 @@ public DataLoader(BatchLoader<K, V> batchLoadFunction, DataLoaderOptions options
416416
DataLoader(Object batchLoadFunction, DataLoaderOptions options, Clock clock) {
417417
DataLoaderOptions loaderOptions = options == null ? new DataLoaderOptions() : options;
418418
this.futureCache = determineFutureCache(loaderOptions);
419-
this.cachedValueStore = determineCachedValueStore(loaderOptions);
419+
this.valueCache = determineValueCache(loaderOptions);
420420
// order of keys matter in data loader
421421
this.stats = nonNull(loaderOptions.getStatisticsCollector());
422422

423-
this.helper = new DataLoaderHelper<>(this, batchLoadFunction, loaderOptions, this.futureCache, this.cachedValueStore, this.stats, clock);
423+
this.helper = new DataLoaderHelper<>(this, batchLoadFunction, loaderOptions, this.futureCache, this.valueCache, this.stats, clock);
424424
}
425425

426426

@@ -430,8 +430,8 @@ private CacheMap<Object, V> determineFutureCache(DataLoaderOptions loaderOptions
430430
}
431431

432432
@SuppressWarnings("unchecked")
433-
private CachedValueStore<Object, V> determineCachedValueStore(DataLoaderOptions loaderOptions) {
434-
return (CachedValueStore<Object, V>) loaderOptions.cachedValueStore().orElseGet(CachedValueStore::defaultCachedValueStore);
433+
private ValueCache<Object, V> determineValueCache(DataLoaderOptions loaderOptions) {
434+
return (ValueCache<Object, V>) loaderOptions.valueCache().orElseGet(ValueCache::defaultValueCache);
435435
}
436436

437437
/**
@@ -652,7 +652,7 @@ public DataLoader<K, V> clear(K key, BiConsumer<Void, Throwable> handler) {
652652
Object cacheKey = getCacheKey(key);
653653
synchronized (this) {
654654
futureCache.delete(cacheKey);
655-
cachedValueStore.delete(key).whenComplete(handler);
655+
valueCache.delete(key).whenComplete(handler);
656656
}
657657
return this;
658658
}
@@ -677,14 +677,14 @@ public DataLoader<K, V> clearAll() {
677677
public DataLoader<K, V> clearAll(BiConsumer<Void, Throwable> handler) {
678678
synchronized (this) {
679679
futureCache.clear();
680-
cachedValueStore.clear().whenComplete(handler);
680+
valueCache.clear().whenComplete(handler);
681681
}
682682
return this;
683683
}
684684

685685
/**
686686
* Primes the cache with the given key and value. Note this will only prime the future cache
687-
* and not the value store. Use {@link CachedValueStore#set(Object, Object)} if you want
687+
* and not the value store. Use {@link ValueCache#set(Object, Object)} if you want
688688
* o prime it with values before use
689689
*
690690
* @param key the key

src/main/java/org/dataloader/DataLoaderHelper.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ Object getCallContext() {
6363
private final Object batchLoadFunction;
6464
private final DataLoaderOptions loaderOptions;
6565
private final CacheMap<Object, V> futureCache;
66-
private final CachedValueStore<Object, V> cachedValueStore;
66+
private final ValueCache<Object, V> valueCache;
6767
private final List<LoaderQueueEntry<K, CompletableFuture<V>>> loaderQueue;
6868
private final StatisticsCollector stats;
6969
private final Clock clock;
@@ -73,14 +73,14 @@ Object getCallContext() {
7373
Object batchLoadFunction,
7474
DataLoaderOptions loaderOptions,
7575
CacheMap<Object, V> futureCache,
76-
CachedValueStore<Object, V> cachedValueStore,
76+
ValueCache<Object, V> valueCache,
7777
StatisticsCollector stats,
7878
Clock clock) {
7979
this.dataLoader = dataLoader;
8080
this.batchLoadFunction = batchLoadFunction;
8181
this.loaderOptions = loaderOptions;
8282
this.futureCache = futureCache;
83-
this.cachedValueStore = cachedValueStore;
83+
this.valueCache = valueCache;
8484
this.loaderQueue = new ArrayList<>();
8585
this.stats = stats;
8686
this.clock = clock;
@@ -307,7 +307,7 @@ private CompletableFuture<V> loadFromCache(K key, Object loadContext, boolean ba
307307
*/
308308
final CompletableFuture<V> future = new CompletableFuture<>();
309309

310-
cachedValueStore.get(cacheKey).whenComplete((cachedValue, getCallEx) -> {
310+
valueCache.get(cacheKey).whenComplete((cachedValue, getCallEx) -> {
311311
if (getCallEx == null) {
312312
future.complete(cachedValue);
313313
} else {
@@ -324,7 +324,7 @@ private CompletableFuture<V> loadFromCache(K key, Object loadContext, boolean ba
324324
private BiConsumer<V, Throwable> setValueIntoCacheAndCompleteFuture(Object cacheKey, CompletableFuture<V> future) {
325325
return (result, loadCallEx) -> {
326326
if (loadCallEx == null) {
327-
cachedValueStore.set(cacheKey, result)
327+
valueCache.set(cacheKey, result)
328328
.whenComplete((v, setCallExIgnored) -> future.complete(result));
329329
} else {
330330
future.completeExceptionally(loadCallEx);

src/main/java/org/dataloader/DataLoaderOptions.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public class DataLoaderOptions {
4040
private boolean cachingExceptionsEnabled;
4141
private CacheKey<?> cacheKeyFunction;
4242
private CacheMap<?,?> cacheMap;
43-
private CachedValueStore<?,?> cachedValueStore;
43+
private ValueCache<?,?> valueCache;
4444
private int maxBatchSize;
4545
private Supplier<StatisticsCollector> statisticsCollector;
4646
private BatchLoaderContextProvider environmentProvider;
@@ -259,26 +259,25 @@ public DataLoaderOptions setBatchLoaderContextProvider(BatchLoaderContextProvide
259259
}
260260

261261
/**
262-
* Gets the (optional) cache store implementation that is used for value storage, if caching is enabled.
262+
* Gets the (optional) cache store implementation that is used for value caching, if caching is enabled.
263263
* <p>
264264
* If missing, a no-op implementation will be used.
265265
*
266266
* @return an optional with the cache store instance, or empty
267267
*/
268-
public Optional<CachedValueStore<?,?>> cachedValueStore() {
269-
return Optional.ofNullable(cachedValueStore);
268+
public Optional<ValueCache<?,?>> valueCache() {
269+
return Optional.ofNullable(valueCache);
270270
}
271271

272272
/**
273-
* Sets the value store implementation to use for caching values, if caching is enabled.
273+
* Sets the value cache implementation to use for caching values, if caching is enabled.
274274
*
275-
* @param cachedValueStore the cache store instance
275+
* @param valueCache the value cache instance
276276
*
277277
* @return the data loader options for fluent coding
278278
*/
279-
public DataLoaderOptions setCachedValueStore(CachedValueStore<?,?> cachedValueStore) {
280-
this.cachedValueStore = cachedValueStore;
279+
public DataLoaderOptions setValueCache(ValueCache<?,?> valueCache) {
280+
this.valueCache = valueCache;
281281
return this;
282282
}
283-
284283
}

src/main/java/org/dataloader/CachedValueStore.java renamed to src/main/java/org/dataloader/ValueCache.java

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,26 @@
11
package org.dataloader;
22

33
import org.dataloader.annotations.PublicSpi;
4-
import org.dataloader.impl.NoOpCachedValueStore;
4+
import org.dataloader.impl.NoOpValueCache;
55

66
import java.util.concurrent.CompletableFuture;
77

88
/**
9-
* Cache value store for data loaders that use caching and want a long-lived or external cache.
9+
* The {@link ValueCache} is used by data loaders that use caching and want a long-lived or external cache
10+
* of values. The {@link ValueCache} is used as a place to cache values when they come back from
11+
* <p>
12+
* It differs from {@link CacheMap} which is in fact a cache of promises to values aka {@link CompletableFuture}&lt;V> and it rather suited
13+
* to be a wrapper of a long lived or external value cache. {@link CompletableFuture}s cant be easily placed in an external cache
14+
* outside the JVM say, hence the need for the {@link ValueCache}.
15+
* <p>
16+
* {@link DataLoader}s use a two stage cache strategy if caching is enabled. If the {@link CacheMap} already has the promise to a value
17+
* that is used. If not then the {@link ValueCache} is asked for a value, if it has one then that is returned (and cached as a promise in the {@link CacheMap}.
18+
* If there is no value then the key is queued and loaded via the {@link BatchLoader} calls. The returned values will then be stored in
19+
* the {@link ValueCache} and the promises to those values are also stored in the {@link CacheMap}.
1020
* <p>
1121
* The default implementation is a no-op store which replies with the key always missing and doesn't
1222
* store any actual results. This is to avoid duplicating the stored data between the {@link CacheMap}
13-
* and the store.
23+
* out of the box.
1424
* <p>
1525
* The API signature uses completable futures because the backing implementation MAY be a remote external cache
1626
* and hence exceptions may happen in retrieving values.
@@ -21,20 +31,20 @@
2131
* @author <a href="https://github.com/craig-day">Craig Day</a>
2232
*/
2333
@PublicSpi
24-
public interface CachedValueStore<K, V> {
34+
public interface ValueCache<K, V> {
2535

2636

2737
/**
28-
* Creates a new store, using the default no-op implementation.
38+
* Creates a new value cache, using the default no-op implementation.
2939
*
3040
* @param <K> the type of cache keys
3141
* @param <V> the type of cache values
3242
*
3343
* @return the cache store
3444
*/
35-
static <K, V> CachedValueStore<K, V> defaultCachedValueStore() {
45+
static <K, V> ValueCache<K, V> defaultValueCache() {
3646
//noinspection unchecked
37-
return (CachedValueStore<K, V>) NoOpCachedValueStore.NOOP;
47+
return (ValueCache<K, V>) NoOpValueCache.NOOP;
3848
}
3949

4050
/**
@@ -46,7 +56,6 @@ static <K, V> CachedValueStore<K, V> defaultCachedValueStore() {
4656
*
4757
* @return a future containing the cached value (which maybe null) or exceptionally completed future if the key does
4858
* not exist in the cache.
49-
*
5059
*/
5160
CompletableFuture<V> get(K key);
5261

src/main/java/org/dataloader/impl/NoOpCachedValueStore.java renamed to src/main/java/org/dataloader/impl/NoOpValueCache.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package org.dataloader.impl;
22

33

4-
import org.dataloader.CachedValueStore;
4+
import org.dataloader.ValueCache;
55
import org.dataloader.annotations.Internal;
66

77
import java.util.concurrent.CompletableFuture;
88

99
/**
10-
* Implementation of {@link CachedValueStore} that does nothing.
10+
* Implementation of {@link ValueCache} that does nothing.
1111
* <p>
1212
* We don't want to store values in memory twice, so when using the default store we just
1313
* say we never have the key and complete the other methods by doing nothing.
@@ -18,9 +18,9 @@
1818
* @author <a href="https://github.com/craig-day">Craig Day</a>
1919
*/
2020
@Internal
21-
public class NoOpCachedValueStore<K, V> implements CachedValueStore<K, V> {
21+
public class NoOpValueCache<K, V> implements ValueCache<K, V> {
2222

23-
public static NoOpCachedValueStore<?, ?> NOOP = new NoOpCachedValueStore<>();
23+
public static NoOpValueCache<?, ?> NOOP = new NoOpValueCache<>();
2424

2525
/**
2626
* {@inheritDoc}

src/test/java/org/dataloader/DataLoaderCachedValueStoreTest.java renamed to src/test/java/org/dataloader/DataLoaderValueCacheTest.java

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
import com.github.benmanes.caffeine.cache.Cache;
44
import com.github.benmanes.caffeine.cache.Caffeine;
5-
import org.dataloader.fixtures.CaffeineCachedValueStore;
6-
import org.dataloader.fixtures.CustomCachedValueStore;
5+
import org.dataloader.fixtures.CaffeineValueCache;
6+
import org.dataloader.fixtures.CustomValueCache;
77
import org.junit.Test;
88

99
import java.util.ArrayList;
@@ -14,7 +14,6 @@
1414
import static java.util.Arrays.asList;
1515
import static java.util.Collections.emptyList;
1616
import static java.util.Collections.singletonList;
17-
import static java.util.concurrent.CompletableFuture.completedFuture;
1817
import static org.awaitility.Awaitility.await;
1918
import static org.dataloader.DataLoaderOptions.newOptions;
2019
import static org.dataloader.fixtures.TestKit.idLoader;
@@ -25,7 +24,7 @@
2524
import static org.junit.Assert.assertThat;
2625
import static org.junit.Assert.assertTrue;
2726

28-
public class DataLoaderCachedValueStoreTest {
27+
public class DataLoaderValueCacheTest {
2928

3029
@Test
3130
public void test_by_default_we_have_no_value_caching() {
@@ -63,9 +62,9 @@ public void test_by_default_we_have_no_value_caching() {
6362

6463
@Test
6564
public void should_accept_a_remote_value_store_for_caching() {
66-
CustomCachedValueStore customStore = new CustomCachedValueStore();
65+
CustomValueCache customStore = new CustomValueCache();
6766
List<List<String>> loadCalls = new ArrayList<>();
68-
DataLoaderOptions options = newOptions().setCachedValueStore(customStore);
67+
DataLoaderOptions options = newOptions().setValueCache(customStore);
6968
DataLoader<String, String> identityLoader = idLoader(options, loadCalls);
7069

7170
// Fetches as expected
@@ -116,10 +115,10 @@ public void can_use_caffeine_for_caching() {
116115
.maximumSize(100)
117116
.build();
118117

119-
CachedValueStore<String, Object> customStore = new CaffeineCachedValueStore(caffeineCache);
118+
ValueCache<String, Object> customStore = new CaffeineValueCache(caffeineCache);
120119

121120
List<List<String>> loadCalls = new ArrayList<>();
122-
DataLoaderOptions options = newOptions().setCachedValueStore(customStore);
121+
DataLoaderOptions options = newOptions().setValueCache(customStore);
123122
DataLoader<String, String> identityLoader = idLoader(options, loadCalls);
124123

125124
// Fetches as expected
@@ -147,7 +146,7 @@ public void can_use_caffeine_for_caching() {
147146

148147
@Test
149148
public void will_invoke_loader_if_CACHE_GET_call_throws_exception() {
150-
CustomCachedValueStore customStore = new CustomCachedValueStore() {
149+
CustomValueCache customStore = new CustomValueCache() {
151150

152151
@Override
153152
public CompletableFuture<Object> get(String key) {
@@ -161,7 +160,7 @@ public CompletableFuture<Object> get(String key) {
161160
customStore.set("b", "From Cache");
162161

163162
List<List<String>> loadCalls = new ArrayList<>();
164-
DataLoaderOptions options = newOptions().setCachedValueStore(customStore);
163+
DataLoaderOptions options = newOptions().setValueCache(customStore);
165164
DataLoader<String, String> identityLoader = idLoader(options, loadCalls);
166165

167166
CompletableFuture<String> fA = identityLoader.load("a");
@@ -177,7 +176,7 @@ public CompletableFuture<Object> get(String key) {
177176

178177
@Test
179178
public void will_still_work_if_CACHE_SET_call_throws_exception() {
180-
CustomCachedValueStore customStore = new CustomCachedValueStore() {
179+
CustomValueCache customStore = new CustomValueCache() {
181180
@Override
182181
public CompletableFuture<Object> set(String key, Object value) {
183182
if (key.equals("a")) {
@@ -188,7 +187,7 @@ public CompletableFuture<Object> set(String key, Object value) {
188187
};
189188

190189
List<List<String>> loadCalls = new ArrayList<>();
191-
DataLoaderOptions options = newOptions().setCachedValueStore(customStore);
190+
DataLoaderOptions options = newOptions().setValueCache(customStore);
192191
DataLoader<String, String> identityLoader = idLoader(options, loadCalls);
193192

194193
CompletableFuture<String> fA = identityLoader.load("a");

0 commit comments

Comments
 (0)