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); } }
/** * 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); } } }
public void testBulkLoad_partial() throws ExecutionException { final Object extraKey = new Object(); final Object extraValue = new Object(); CacheLoader<Object, Object> loader = new CacheLoader<Object, Object>() { @Override public Object load(Object key) throws Exception { throw new AssertionError(); } @Override public Map<Object, Object> loadAll(Iterable<? extends Object> keys) throws Exception { Map<Object, Object> result = Maps.newHashMap(); // ignore request keys result.put(extraKey, extraValue); return result; } }; LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader); Object[] lookupKeys = new Object[] { new Object(), new Object(), new Object() }; try { cache.getAll(asList(lookupKeys)); fail(); } catch (InvalidCacheLoadException expected) {} assertSame(extraValue, cache.asMap().get(extraKey)); }
public void testBulkLoadNull() throws ExecutionException { LoadingCache<Object, Object> cache = CacheBuilder.newBuilder() .recordStats() .build(bulkLoader(constantLoader(null))); CacheStats stats = cache.stats(); assertEquals(0, stats.missCount()); assertEquals(0, stats.loadSuccessCount()); assertEquals(0, stats.loadExceptionCount()); assertEquals(0, stats.hitCount()); try { cache.getAll(asList(new Object())); fail(); } catch (InvalidCacheLoadException expected) {} stats = cache.stats(); assertEquals(1, stats.missCount()); assertEquals(0, stats.loadSuccessCount()); assertEquals(1, stats.loadExceptionCount()); assertEquals(0, stats.hitCount()); }
public Optional<Repository> getStorableRepo(final String repoName, final StorableIndexInfo indexInfo) { try { return Optional.fromNullable(cache.get(repoName, new Callable<Repository>() { @Override public Repository call() throws Exception { Repository repo = getStorableRepo(repoName); if (repo != null) { if (indexInfo != null && indexInfo.getIndexDefinitions().size() > 0) { repo.setIndexProducer(new IndexProducer(indexInfo.getIndexDefinitions())); } return repo; } else { return null; } } })); } catch (ExecutionException | InvalidCacheLoadException e) { log.error(String.format("Error initializing repo for name [%s]: %s", repoName, ExceptionToString.format(e))); return Optional.absent(); } }
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); } }
/** * 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); } } }
/** 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); } } }
public void testBulkLoadNull() throws ExecutionException { LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(bulkLoader(constantLoader(null))); CacheStats stats = cache.stats(); assertEquals(0, stats.missCount()); assertEquals(0, stats.loadSuccessCount()); assertEquals(0, stats.loadExceptionCount()); assertEquals(0, stats.hitCount()); try { cache.getAll(asList(new Object())); fail(); } catch (InvalidCacheLoadException expected) { } stats = cache.stats(); assertEquals(1, stats.missCount()); assertEquals(0, stats.loadSuccessCount()); assertEquals(1, stats.loadExceptionCount()); assertEquals(0, stats.hitCount()); }
public void testGet_computeNull() { LoadingCache<Object, Object> cache = CacheBuilder.newBuilder() .maximumSize(0) .removalListener(listener) .build(constantLoader(null)); try { cache.getUnchecked(new Object()); fail(); } catch (InvalidCacheLoadException e) { /* expected */ } assertTrue(listener.isEmpty()); checkEmpty(cache); }
/** * 该entry以及存在,等待完成,被加载进来 * * @param e * @param key * @param valueReference * @return * @throws ExecutionException */ 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();// 获取value引用 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);// 处理access队列 return value; } finally { statsCounter.recordMisses(1); } }
/** * 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);// 非中断方式调用future.get方法获取值 if (value == null) { throw new InvalidCacheLoadException("CacheLoader returned null for key " + key + "."); } statsCounter.recordLoadSuccess(loadingValueReference.elapsedNanos()); // 线程安全地把key和value存放到cache中。 storeLoadedValue(key, hash, loadingValueReference, value); return value; } finally { if (value == null) { statsCounter.recordLoadException(loadingValueReference.elapsedNanos()); removeLoadingValue(key, hash, loadingValueReference); } } }