V value = newEntries.get(key); if (value == null) { throw new InvalidCacheLoadException("loadAll failed to return a value for " + key);
throw new InvalidCacheLoadException(loader + " returned null map from loadAll"); throw new InvalidCacheLoadException(loader + " returned null keys or values from loadAll");
@Override public Map<K, V> loadAll(Iterable<? extends K> keys) { try { Map<K, V> loaded = cacheLoader.loadAll(keys); if (loaded == null) { throw new InvalidCacheLoadException("null map"); } Map<K, V> result = new HashMap<>(loaded.size()); loaded.forEach((key, value) -> { if ((key == null) || (value == null)) { nullBulkLoad.set(true); } else { result.put(key, value); } }); return result; } catch (RuntimeException | Error e) { throw e; } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new CacheLoaderException(e); } catch (Exception e) { throw new CacheLoaderException(e); } } }
V waitForLoadingValue(ReferenceEntry<K, V> e, K key, ValueReference<K, V> valueReference) throws ExecutionException { if (!valueReference.isLoading()) { throw new AssertionError(); } checkState(!Thread.holdsLock(e), "Recursive load"); // don't consider expiration as we're concurrent with loading try { V value = valueReference.waitForValue(); if (value == null) { throw new InvalidCacheLoadException("CacheLoader returned null for key " + key + "."); } // re-read ticker now that loading has completed long now = map.ticker.read(); recordRead(e, now); return value; } finally { statsCounter.recordMisses(1); } }
V waitForLoadingValue(ReferenceEntry<K, V> e, K key, ValueReference<K, V> valueReference) throws ExecutionException { if (!valueReference.isLoading()) { throw new AssertionError(); } checkState(!Thread.holdsLock(e), "Recursive load of: %s", key); // don't consider expiration as we're concurrent with loading try { V value = valueReference.waitForValue(); if (value == null) { throw new InvalidCacheLoadException("CacheLoader returned null for key " + key + "."); } // re-read ticker now that loading has completed long now = map.ticker.read(); recordRead(e, now); return value; } finally { statsCounter.recordMisses(1); } }
@Override public V reload(K key, V oldValue) { try { V value = Futures.getUnchecked(cacheLoader.reload(key, oldValue)); if (value == null) { throw new InvalidCacheLoadException("null value"); } return value; } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new CacheLoaderException(e); } catch (Exception e) { Throwables.throwIfUnchecked(e); throw new RuntimeException(e); } } }
@Override public V load(K key) { try { V value = cacheLoader.load(key); if (value == null) { throw new InvalidCacheLoadException("null value"); } return value; } catch (RuntimeException | Error e) { throw e; } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new CacheLoaderException(e); } catch (Exception e) { throw new CacheLoaderException(e); } }
@SuppressWarnings("serial") @DataProvider(name = "exceptions") public Object[][] createExceptions() { return new Object[][] { { new ExecutionException() { } }, { new UncheckedExecutionException() { } }, { new InvalidCacheLoadException("foo") } }; }
@SuppressWarnings("serial") @DataProvider(name = "exceptions") public Object[][] createExceptions() { return new Object[][] { { new ExecutionException() { } }, { new UncheckedExecutionException() { } }, { new InvalidCacheLoadException("foo") } }; }
throw new InvalidCacheLoadException(loader + " returned null map from loadAll"); throw new InvalidCacheLoadException(loader + " returned null keys or values from loadAll");
V value = newEntries.get(key); if (value == null) { throw new InvalidCacheLoadException("loadAll failed to return a value for " + key);
/** Waits uninterruptibly for {@code newValue} to be loaded, and then records loading stats. */ V getAndRecordStats( K key, int hash, LoadingValueReference<K, V> loadingValueReference, ListenableFuture<V> newValue) throws ExecutionException { V value = null; try { value = getUninterruptibly(newValue); if (value == null) { throw new InvalidCacheLoadException("CacheLoader returned null for key " + key + "."); } statsCounter.recordLoadSuccess(loadingValueReference.elapsedNanos()); storeLoadedValue(key, hash, loadingValueReference, value); return value; } finally { if (value == null) { statsCounter.recordLoadException(loadingValueReference.elapsedNanos()); removeLoadingValue(key, hash, loadingValueReference); } } }
@Override @SuppressWarnings({"PMD.PreserveStackTrace", "PMD.ExceptionAsFlowControl", "NullAway"}) public V get(K key, Callable<? extends V> valueLoader) throws ExecutionException { requireNonNull(valueLoader); try { return cache.get(key, k -> { try { V value = valueLoader.call(); if (value == null) { throw new InvalidCacheLoadException("null value"); } return value; } catch (InvalidCacheLoadException e) { throw e; } catch (RuntimeException e) { throw new UncheckedExecutionException(e); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new CacheLoaderException(e); } catch (Exception e) { throw new CacheLoaderException(e); } catch (Error e) { throw new ExecutionError(e); } }); } catch (CacheLoaderException e) { throw new ExecutionException(e.getCause()); } }
V waitForLoadingValue(ReferenceEntry<K, V> e, K key, ValueReference<K, V> valueReference) throws ExecutionException { if (!valueReference.isLoading()) { throw new AssertionError(); } checkState(!Thread.holdsLock(e), "Recursive load of: %s", key); // don't consider expiration as we're concurrent with loading try { V value = valueReference.waitForValue(); if (value == null) { throw new InvalidCacheLoadException("CacheLoader returned null for key " + key + "."); } // re-read ticker now that loading has completed long now = map.ticker.read(); recordRead(e, now); return value; } finally { statsCounter.recordMisses(1); } }
@Override @SuppressWarnings({"PMD.PreserveStackTrace", "PMD.AvoidCatchingNPE"}) public ImmutableMap<K, V> getAll(Iterable<? extends K> keys) throws ExecutionException { try { Map<K, V> result = cache.getAll(keys); if (nullBulkLoad.get()) { nullBulkLoad.set(false); throw new InvalidCacheLoadException("null key or value"); } for (K key : keys) { if (!result.containsKey(key)) { throw new InvalidCacheLoadException("loadAll failed to return a value for " + key); } } return ImmutableMap.copyOf(result); } catch (NullPointerException | InvalidCacheLoadException e) { throw e; } catch (CacheLoaderException e) { throw new ExecutionException(e.getCause()); } catch (Exception e) { throw new UncheckedExecutionException(e); } catch (Error e) { throw new ExecutionError(e); } }
V waitForLoadingValue(ReferenceEntry<K, V> e, K key, ValueReference<K, V> valueReference) throws ExecutionException { if (!valueReference.isLoading()) { throw new AssertionError(); } checkState(!Thread.holdsLock(e), "Recursive load of: %s", key); // don't consider expiration as we're concurrent with loading try { V value = valueReference.waitForValue(); if (value == null) { throw new InvalidCacheLoadException("CacheLoader returned null for key " + key + "."); } // re-read ticker now that loading has completed long now = map.ticker.read(); recordRead(e, now); return value; } finally { statsCounter.recordMisses(1); } }
@Override public V load(K key) { try { V value = cacheLoader.load(key); if (value == null) { throw new InvalidCacheLoadException("null value"); } return value; } catch (RuntimeException | Error e) { throw e; } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new CacheLoaderException(e); } catch (Exception e) { throw new CacheLoaderException(e); } }
@Override public V reload(K key, V oldValue) { try { V value = Futures.getUnchecked(cacheLoader.reload(key, oldValue)); if (value == null) { throw new InvalidCacheLoadException("null value"); } return value; } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new CacheLoaderException(e); } catch (Exception e) { Throwables.throwIfUnchecked(e); throw new RuntimeException(e); } } }
/** Waits uninterruptibly for {@code newValue} to be loaded, and then records loading stats. */ V getAndRecordStats( K key, int hash, LoadingValueReference<K, V> loadingValueReference, ListenableFuture<V> newValue) throws ExecutionException { V value = null; try { value = getUninterruptibly(newValue); if (value == null) { throw new InvalidCacheLoadException("CacheLoader returned null for key " + key + "."); } statsCounter.recordLoadSuccess(loadingValueReference.elapsedNanos()); storeLoadedValue(key, hash, loadingValueReference, value); return value; } finally { if (value == null) { statsCounter.recordLoadException(loadingValueReference.elapsedNanos()); removeLoadingValue(key, hash, loadingValueReference); } } }
V waitForLoadingValue(ReferenceEntry<K, V> e, K key, ValueReference<K, V> valueReference) throws ExecutionException { if (!valueReference.isLoading()) { throw new AssertionError(); } checkState(!Thread.holdsLock(e), "Recursive load of: %s", key); // don't consider expiration as we're concurrent with loading try { V value = valueReference.waitForValue(); if (value == null) { throw new InvalidCacheLoadException("CacheLoader returned null for key " + key + "."); } // re-read ticker now that loading has completed long now = map.ticker.read(); recordRead(e, now); return value; } finally { statsCounter.recordMisses(1); } }