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