Returns the result of calling CacheLoader#loadAll, or null if loader doesn't implement loadAll.
(Set<? extends K> keys, CacheLoader<? super K, V> loader)
| 4075 | */ |
| 4076 | |
| 4077 | @Nullable |
| 4078 | Map<K, V> loadAll(Set<? extends K> keys, CacheLoader<? super K, V> loader) throws ExecutionException { |
| 4079 | checkNotNull(loader); |
| 4080 | checkNotNull(keys); |
| 4081 | Stopwatch stopwatch = Stopwatch.createStarted(); |
| 4082 | Map<K, V> result; |
| 4083 | boolean success = false; |
| 4084 | try { |
| 4085 | @SuppressWarnings("unchecked") // safe since all keys extend K |
| 4086 | Map<K, V> map = (Map<K, V>) loader.loadAll(keys); |
| 4087 | result = map; |
| 4088 | success = true; |
| 4089 | } catch (UnsupportedLoadingOperationException e) { |
| 4090 | success = true; |
| 4091 | throw e; |
| 4092 | } catch (InterruptedException e) { |
| 4093 | Thread.currentThread().interrupt(); |
| 4094 | throw new ExecutionException(e); |
| 4095 | } catch (RuntimeException e) { |
| 4096 | throw new UncheckedExecutionException(e); |
| 4097 | } catch (Exception e) { |
| 4098 | throw new ExecutionException(e); |
| 4099 | } catch (Error e) { |
| 4100 | throw new ExecutionError(e); |
| 4101 | } finally { |
| 4102 | if (!success) { |
| 4103 | globalStatsCounter.recordLoadException(stopwatch.elapsed(NANOSECONDS)); |
| 4104 | } |
| 4105 | } |
| 4106 | if (result == null) { |
| 4107 | globalStatsCounter.recordLoadException(stopwatch.elapsed(NANOSECONDS)); |
| 4108 | throw new InvalidCacheLoadException(loader + " returned null map from loadAll"); |
| 4109 | } |
| 4110 | stopwatch.stop(); |
| 4111 | // TODO(fry): batch by segment |
| 4112 | boolean nullsPresent = false; |
| 4113 | for (Map.Entry<K, V> entry : result.entrySet()) { |
| 4114 | K key = entry.getKey(); |
| 4115 | V value = entry.getValue(); |
| 4116 | if (key == null || value == null) { |
| 4117 | // delay failure until non-null entries are stored |
| 4118 | nullsPresent = true; |
| 4119 | } else { |
| 4120 | put(key, value); |
| 4121 | } |
| 4122 | } |
| 4123 | if (nullsPresent) { |
| 4124 | globalStatsCounter.recordLoadException(stopwatch.elapsed(NANOSECONDS)); |
| 4125 | throw new InvalidCacheLoadException(loader + " returned null keys or values from loadAll"); |
| 4126 | } |
| 4127 | |
| 4128 | // TODO(fry): record count of loaded entries |
| 4129 | globalStatsCounter.recordLoadSuccess(stopwatch.elapsed(NANOSECONDS)); |
| 4130 | return result; |
| 4131 | } |
| 4132 | |
| 4133 | /** |
| 4134 | * Returns the internal entry for the specified key. The entry may be loading, expired, or |
no test coverage detected