4949@ Internal
5050class DataLoaderHelper <K , V > {
5151
52- static class LoaderQueueEntry <K , V > {
52+ private static class LoaderQueueEntry <K , V > {
5353
5454 final K key ;
5555 final CompletableFuture <V > value ;
@@ -155,11 +155,8 @@ CompletableFuture<V> load(K key, Object loadContext) {
155155 try {
156156 CompletableFuture <V > cachedFuture = futureCache .get (cacheKey );
157157 if (cachedFuture != null ) {
158- // We already have a promise for this key, no need to check value cache or queue up load
159- stats .incrementCacheHitCount (new IncrementCacheHitCountStatisticsContext <>(key , loadContext ));
160- ctx .onDispatched ();
161- cachedFuture .whenComplete (ctx ::onCompleted );
162- return cachedFuture ;
158+ // We already have a promise for this key, no need to check value cache or queue this load
159+ return incrementCacheHitAndReturnCF (ctx , key , loadContext , cachedFuture );
163160 }
164161 } catch (Exception ignored ) {
165162 }
@@ -170,11 +167,8 @@ CompletableFuture<V> load(K key, Object loadContext) {
170167 if (futureCachingEnabled ) {
171168 CompletableFuture <V > cachedFuture = futureCache .putIfAbsentAtomically (cacheKey , loadCallFuture );
172169 if (cachedFuture != null ) {
173- // another thread was faster and created a matching CF ... hence this is really a cachehit and we are done
174- stats .incrementCacheHitCount (new IncrementCacheHitCountStatisticsContext <>(key , loadContext ));
175- ctx .onDispatched ();
176- cachedFuture .whenComplete (ctx ::onCompleted );
177- return cachedFuture ;
170+ // another thread was faster and created a matching CF ... hence this is really a cache hit and we are done
171+ return incrementCacheHitAndReturnCF (ctx , key , loadContext , cachedFuture );
178172 }
179173 }
180174 addEntryToLoaderQueue (key , loadCallFuture , loadContext );
@@ -186,12 +180,9 @@ CompletableFuture<V> load(K key, Object loadContext) {
186180 CompletableFuture <V > cachedFuture = futureCache .putIfAbsentAtomically (cacheKey , loadCallFuture );
187181 if (cachedFuture != null ) {
188182 // another thread was faster and the loader was invoked twice with the same key
189- // we are disregarding the resul of our dispatch call and use the already cached value
183+ // we are disregarding the result of our dispatch call and use the already cached value
190184 // meaning this is a cache hit and we are done
191- stats .incrementCacheHitCount (new IncrementCacheHitCountStatisticsContext <>(key , loadContext ));
192- ctx .onDispatched ();
193- cachedFuture .whenComplete (ctx ::onCompleted );
194- return cachedFuture ;
185+ return incrementCacheHitAndReturnCF (ctx , key , loadContext , cachedFuture );
195186 }
196187 }
197188 }
@@ -201,6 +192,13 @@ CompletableFuture<V> load(K key, Object loadContext) {
201192 return loadCallFuture ;
202193 }
203194
195+ private CompletableFuture <V > incrementCacheHitAndReturnCF (DataLoaderInstrumentationContext <Object > ctx , K key , Object loadContext , CompletableFuture <V > cachedFuture ) {
196+ stats .incrementCacheHitCount (new IncrementCacheHitCountStatisticsContext <>(key , loadContext ));
197+ ctx .onDispatched ();
198+ cachedFuture .whenComplete (ctx ::onCompleted );
199+ return cachedFuture ;
200+ }
201+
204202 private void addEntryToLoaderQueue (K key , CompletableFuture <V > future , Object loadContext ) {
205203 while (true ) {
206204 LoaderQueueEntry <K , V > prev = loaderQueue .get ();
@@ -223,6 +221,7 @@ Object getCacheKeyWithContext(K key, Object context) {
223221 loaderOptions .cacheKeyFunction ().get ().getKeyWithContext (key , context ) : key ;
224222 }
225223
224+ @ SuppressWarnings ("unchecked" )
226225 DispatchResult <V > dispatch () {
227226 DataLoaderInstrumentationContext <DispatchResult <?>> instrCtx = ctxOrNoopCtx (instrumentation ().beginDispatch (dataLoader ));
228227
@@ -232,6 +231,8 @@ DispatchResult<V> dispatch() {
232231 while (true ) {
233232 loaderQueueEntryHead = loaderQueue .get ();
234233 if (loaderQueue .compareAndSet (loaderQueueEntryHead , null )) {
234+ // one or more threads competed and this one won. This thread holds
235+ // the loader queue root in the local variable loaderQueueEntryHead
235236 break ;
236237 }
237238 }
0 commit comments