diff options
Diffstat (limited to 'android/guava/src/com/google/common/cache/LocalCache.java')
-rw-r--r-- | android/guava/src/com/google/common/cache/LocalCache.java | 206 |
1 files changed, 133 insertions, 73 deletions
diff --git a/android/guava/src/com/google/common/cache/LocalCache.java b/android/guava/src/com/google/common/cache/LocalCache.java index f3744e59c..239afe204 100644 --- a/android/guava/src/com/google/common/cache/LocalCache.java +++ b/android/guava/src/com/google/common/cache/LocalCache.java @@ -28,7 +28,6 @@ import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.GwtIncompatible; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Equivalence; -import com.google.common.base.Function; import com.google.common.base.Stopwatch; import com.google.common.base.Ticker; import com.google.common.cache.AbstractCache.SimpleStatsCounter; @@ -51,10 +50,13 @@ import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.SettableFuture; import com.google.common.util.concurrent.UncheckedExecutionException; import com.google.common.util.concurrent.Uninterruptibles; +import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.google.errorprone.annotations.concurrent.GuardedBy; +import com.google.errorprone.annotations.concurrent.LazyInit; import com.google.j2objc.annotations.RetainedWith; import com.google.j2objc.annotations.Weak; import java.io.IOException; +import java.io.InvalidObjectException; import java.io.ObjectInputStream; import java.io.Serializable; import java.lang.ref.Reference; @@ -69,7 +71,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.Map; -import java.util.Map.Entry; import java.util.NoSuchElementException; import java.util.Queue; import java.util.Set; @@ -256,8 +257,8 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> removalListener = builder.getRemovalListener(); removalNotificationQueue = (removalListener == NullListener.INSTANCE) - ? LocalCache.<RemovalNotification<K, V>>discardingQueue() - : new ConcurrentLinkedQueue<RemovalNotification<K, V>>(); + ? LocalCache.discardingQueue() + : new ConcurrentLinkedQueue<>(); ticker = builder.getTicker(recordsTime()); entryFactory = EntryFactory.getFactory(keyStrength, usesAccessEntries(), usesWriteEntries()); @@ -455,8 +456,11 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> @Override <K, V> ReferenceEntry<K, V> copyEntry( - Segment<K, V> segment, ReferenceEntry<K, V> original, ReferenceEntry<K, V> newNext) { - ReferenceEntry<K, V> newEntry = super.copyEntry(segment, original, newNext); + Segment<K, V> segment, + ReferenceEntry<K, V> original, + ReferenceEntry<K, V> newNext, + K key) { + ReferenceEntry<K, V> newEntry = super.copyEntry(segment, original, newNext, key); copyAccessEntry(original, newEntry); return newEntry; } @@ -470,8 +474,11 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> @Override <K, V> ReferenceEntry<K, V> copyEntry( - Segment<K, V> segment, ReferenceEntry<K, V> original, ReferenceEntry<K, V> newNext) { - ReferenceEntry<K, V> newEntry = super.copyEntry(segment, original, newNext); + Segment<K, V> segment, + ReferenceEntry<K, V> original, + ReferenceEntry<K, V> newNext, + K key) { + ReferenceEntry<K, V> newEntry = super.copyEntry(segment, original, newNext, key); copyWriteEntry(original, newEntry); return newEntry; } @@ -485,8 +492,11 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> @Override <K, V> ReferenceEntry<K, V> copyEntry( - Segment<K, V> segment, ReferenceEntry<K, V> original, ReferenceEntry<K, V> newNext) { - ReferenceEntry<K, V> newEntry = super.copyEntry(segment, original, newNext); + Segment<K, V> segment, + ReferenceEntry<K, V> original, + ReferenceEntry<K, V> newNext, + K key) { + ReferenceEntry<K, V> newEntry = super.copyEntry(segment, original, newNext, key); copyAccessEntry(original, newEntry); copyWriteEntry(original, newEntry); return newEntry; @@ -508,8 +518,11 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> @Override <K, V> ReferenceEntry<K, V> copyEntry( - Segment<K, V> segment, ReferenceEntry<K, V> original, ReferenceEntry<K, V> newNext) { - ReferenceEntry<K, V> newEntry = super.copyEntry(segment, original, newNext); + Segment<K, V> segment, + ReferenceEntry<K, V> original, + ReferenceEntry<K, V> newNext, + K key) { + ReferenceEntry<K, V> newEntry = super.copyEntry(segment, original, newNext, key); copyAccessEntry(original, newEntry); return newEntry; } @@ -523,8 +536,11 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> @Override <K, V> ReferenceEntry<K, V> copyEntry( - Segment<K, V> segment, ReferenceEntry<K, V> original, ReferenceEntry<K, V> newNext) { - ReferenceEntry<K, V> newEntry = super.copyEntry(segment, original, newNext); + Segment<K, V> segment, + ReferenceEntry<K, V> original, + ReferenceEntry<K, V> newNext, + K key) { + ReferenceEntry<K, V> newEntry = super.copyEntry(segment, original, newNext, key); copyWriteEntry(original, newEntry); return newEntry; } @@ -538,8 +554,11 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> @Override <K, V> ReferenceEntry<K, V> copyEntry( - Segment<K, V> segment, ReferenceEntry<K, V> original, ReferenceEntry<K, V> newNext) { - ReferenceEntry<K, V> newEntry = super.copyEntry(segment, original, newNext); + Segment<K, V> segment, + ReferenceEntry<K, V> original, + ReferenceEntry<K, V> newNext, + K key) { + ReferenceEntry<K, V> newEntry = super.copyEntry(segment, original, newNext, key); copyAccessEntry(original, newEntry); copyWriteEntry(original, newEntry); return newEntry; @@ -587,13 +606,18 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> /** * Copies an entry, assigning it a new {@code next} entry. * - * @param original the entry to copy + * @param original the entry to copy. But avoid calling {@code getKey} on it: Instead, use the + * {@code key} parameter. That way, we prevent the key from being garbage collected in the + * case of weak keys. If we create a new entry with a key that is null at construction time, + * we're not sure if entry will necessarily ever be garbage collected. * @param newNext entry in the same bucket + * @param key the key to copy from the original entry to the new one. Use this in preference to + * {@code original.getKey()}. */ // Guarded By Segment.this <K, V> ReferenceEntry<K, V> copyEntry( - Segment<K, V> segment, ReferenceEntry<K, V> original, ReferenceEntry<K, V> newNext) { - return newEntry(segment, original.getKey(), original.getHash(), newNext); + Segment<K, V> segment, ReferenceEntry<K, V> original, ReferenceEntry<K, V> newNext, K key) { + return newEntry(segment, key, original.getHash(), newNext); } // Guarded By Segment.this @@ -661,8 +685,8 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> void notifyNewValue(@CheckForNull V newValue); /** - * Returns true if a new value is currently loading, regardless of whether or not there is an - * existing value. It is assumed that the return value of this method is constant for any given + * Returns true if a new value is currently loading, regardless of whether there is an existing + * value. It is assumed that the return value of this method is constant for any given * ValueReference instance. */ boolean isLoading(); @@ -680,6 +704,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> /** Placeholder. Indicates that the value hasn't been set yet. */ static final ValueReference<Object, Object> UNSET = new ValueReference<Object, Object>() { + @CheckForNull @Override public Object get() { return null; @@ -690,6 +715,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> return 0; } + @CheckForNull @Override public ReferenceEntry<Object, Object> getEntry() { return null; @@ -713,6 +739,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> return false; } + @CheckForNull @Override public Object waitForValue() { return null; @@ -731,6 +758,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> private enum NullEntry implements ReferenceEntry<Object, Object> { INSTANCE; + @CheckForNull @Override public ValueReference<Object, Object> getValueReference() { return null; @@ -739,6 +767,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> @Override public void setValueReference(ValueReference<Object, Object> valueReference) {} + @CheckForNull @Override public ReferenceEntry<Object, Object> getNext() { return null; @@ -749,6 +778,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> return 0; } + @CheckForNull @Override public Object getKey() { return null; @@ -902,11 +932,13 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> return true; } + @CheckForNull @Override public Object peek() { return null; } + @CheckForNull @Override public Object poll() { return null; @@ -1740,9 +1772,9 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> /** * Gets the value from an entry. Returns null if the entry is invalid, partially-collected, - * loading, or expired. Unlike {@link Segment#getLiveValue} this method does not attempt to - * cleanup stale entries. As such it should only be called outside of a segment context, such as - * during iteration. + * loading, or expired. Unlike {@link Segment#getLiveValue} this method does not attempt to clean + * up stale entries. As such it should only be called outside a segment context, such as during + * iteration. */ @CheckForNull V getLiveValue(ReferenceEntry<K, V> entry, long now) { @@ -1946,24 +1978,16 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> this.statsCounter = checkNotNull(statsCounter); initTable(newEntryArray(initialCapacity)); - keyReferenceQueue = map.usesKeyReferences() ? new ReferenceQueue<K>() : null; + keyReferenceQueue = map.usesKeyReferences() ? new ReferenceQueue<>() : null; - valueReferenceQueue = map.usesValueReferences() ? new ReferenceQueue<V>() : null; + valueReferenceQueue = map.usesValueReferences() ? new ReferenceQueue<>() : null; recencyQueue = - map.usesAccessQueue() - ? new ConcurrentLinkedQueue<ReferenceEntry<K, V>>() - : LocalCache.<ReferenceEntry<K, V>>discardingQueue(); + map.usesAccessQueue() ? new ConcurrentLinkedQueue<>() : LocalCache.discardingQueue(); - writeQueue = - map.usesWriteQueue() - ? new WriteQueue<K, V>() - : LocalCache.<ReferenceEntry<K, V>>discardingQueue(); + writeQueue = map.usesWriteQueue() ? new WriteQueue<>() : LocalCache.discardingQueue(); - accessQueue = - map.usesAccessQueue() - ? new AccessQueue<K, V>() - : LocalCache.<ReferenceEntry<K, V>>discardingQueue(); + accessQueue = map.usesAccessQueue() ? new AccessQueue<>() : LocalCache.discardingQueue(); } AtomicReferenceArray<ReferenceEntry<K, V>> newEntryArray(int size) { @@ -1988,9 +2012,11 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> * Copies {@code original} into a new entry chained to {@code newNext}. Returns the new entry, * or {@code null} if {@code original} was already garbage collected. */ + @CheckForNull @GuardedBy("this") ReferenceEntry<K, V> copyEntry(ReferenceEntry<K, V> original, ReferenceEntry<K, V> newNext) { - if (original.getKey() == null) { + K key = original.getKey(); + if (key == null) { // key collected return null; } @@ -2002,7 +2028,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> return null; } - ReferenceEntry<K, V> newEntry = map.entryFactory.copyEntry(this, original, newNext); + ReferenceEntry<K, V> newEntry = map.entryFactory.copyEntry(this, original, newNext, key); newEntry.setValueReference(valueReference.copyFor(this.valueReferenceQueue, value, newEntry)); return newEntry; } @@ -2023,6 +2049,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> // loading + @CanIgnoreReturnValue V get(K key, int hash, CacheLoader<? super K, V> loader) throws ExecutionException { checkNotNull(key); checkNotNull(loader); @@ -2208,15 +2235,12 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> CacheLoader<? super K, V> loader) { final ListenableFuture<V> loadingFuture = loadingValueReference.loadFuture(key, loader); loadingFuture.addListener( - new Runnable() { - @Override - public void run() { - try { - getAndRecordStats(key, hash, loadingValueReference, loadingFuture); - } catch (Throwable t) { - logger.log(Level.WARNING, "Exception thrown during refresh", t); - loadingValueReference.setException(t); - } + () -> { + try { + getAndRecordStats(key, hash, loadingValueReference, loadingFuture); + } catch (Throwable t) { + logger.log(Level.WARNING, "Exception thrown during refresh", t); + loadingValueReference.setException(t); } }, directExecutor()); @@ -2224,6 +2248,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> } /** Waits uninterruptibly for {@code newValue} to be loaded, and then records loading stats. */ + @CanIgnoreReturnValue V getAndRecordStats( K key, int hash, @@ -2271,6 +2296,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> * {@code null} if another thread is performing the refresh or if an error occurs during * refresh. */ + @CanIgnoreReturnValue @CheckForNull V refresh(K key, int hash, CacheLoader<? super K, V> loader, boolean checkTime) { final LoadingValueReference<K, V> loadingValueReference = @@ -2482,7 +2508,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> // An entry may be in the recency queue despite it being removed from // the map . This can occur when the entry was concurrently read while a // writer is removing it from the segment or after a clear has removed - // all of the segment's entries. + // all the segment's entries. if (accessQueue.contains(e)) { accessQueue.add(e); } @@ -2688,6 +2714,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> } } + @CanIgnoreReturnValue @CheckForNull V put(K key, int hash, V value, boolean onlyIfAbsent) { lock(); @@ -3042,6 +3069,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> } } + @CanIgnoreReturnValue boolean storeLoadedValue( K key, int hash, LoadingValueReference<K, V> oldValueReference, V newValue) { lock(); @@ -3194,6 +3222,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> } /** Removes an entry whose key has been garbage collected. */ + @CanIgnoreReturnValue boolean reclaimKey(ReferenceEntry<K, V> entry, int hash) { lock(); try { @@ -3229,6 +3258,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> } /** Removes an entry whose value has been garbage collected. */ + @CanIgnoreReturnValue boolean reclaimValue(K key, int hash, ValueReference<K, V> valueReference) { lock(); try { @@ -3266,12 +3296,13 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> return false; } finally { unlock(); - if (!isHeldByCurrentThread()) { // don't cleanup inside of put + if (!isHeldByCurrentThread()) { // don't clean up inside of put postWriteCleanup(); } } } + @CanIgnoreReturnValue boolean removeLoadingValue(K key, int hash, LoadingValueReference<K, V> valueReference) { lock(); try { @@ -3307,6 +3338,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> @VisibleForTesting @GuardedBy("this") + @CanIgnoreReturnValue boolean removeEntry(ReferenceEntry<K, V> entry, int hash, RemovalCause cause) { int newCount = this.count - 1; AtomicReferenceArray<ReferenceEntry<K, V>> table = this.table; @@ -3417,10 +3449,12 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> return oldValue.getWeight(); } + @CanIgnoreReturnValue public boolean set(@CheckForNull V newValue) { return futureValue.set(newValue); } + @CanIgnoreReturnValue public boolean setException(Throwable t) { return futureValue.setException(t); } @@ -3459,12 +3493,9 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> // *before* returning newValue from the cache query. return transform( newValue, - new Function<V, V>() { - @Override - public V apply(V newValue) { - LoadingValueReference.this.set(newValue); - return newValue; - } + newResult -> { + LoadingValueReference.this.set(newResult); + return newResult; }, directExecutor()); } catch (Throwable t) { @@ -3570,12 +3601,14 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> return true; } + @CheckForNull @Override public ReferenceEntry<K, V> peek() { ReferenceEntry<K, V> next = head.getNextInWriteQueue(); return (next == head) ? null : next; } + @CheckForNull @Override public ReferenceEntry<K, V> poll() { ReferenceEntry<K, V> next = head.getNextInWriteQueue(); @@ -3589,6 +3622,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> @Override @SuppressWarnings("unchecked") + @CanIgnoreReturnValue public boolean remove(Object o) { ReferenceEntry<K, V> e = (ReferenceEntry<K, V>) o; ReferenceEntry<K, V> previous = e.getPreviousInWriteQueue(); @@ -3638,6 +3672,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> @Override public Iterator<ReferenceEntry<K, V>> iterator() { return new AbstractSequentialIterator<ReferenceEntry<K, V>>(peek()) { + @CheckForNull @Override protected ReferenceEntry<K, V> computeNext(ReferenceEntry<K, V> previous) { ReferenceEntry<K, V> next = previous.getNextInWriteQueue(); @@ -3709,12 +3744,14 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> return true; } + @CheckForNull @Override public ReferenceEntry<K, V> peek() { ReferenceEntry<K, V> next = head.getNextInAccessQueue(); return (next == head) ? null : next; } + @CheckForNull @Override public ReferenceEntry<K, V> poll() { ReferenceEntry<K, V> next = head.getNextInAccessQueue(); @@ -3728,6 +3765,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> @Override @SuppressWarnings("unchecked") + @CanIgnoreReturnValue public boolean remove(Object o) { ReferenceEntry<K, V> e = (ReferenceEntry<K, V>) o; ReferenceEntry<K, V> previous = e.getPreviousInAccessQueue(); @@ -3777,6 +3815,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> @Override public Iterator<ReferenceEntry<K, V>> iterator() { return new AbstractSequentialIterator<ReferenceEntry<K, V>>(peek()) { + @CheckForNull @Override protected ReferenceEntry<K, V> computeNext(ReferenceEntry<K, V> previous) { ReferenceEntry<K, V> next = previous.getNextInAccessQueue(); @@ -3807,19 +3846,19 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> */ long sum = 0L; Segment<K, V>[] segments = this.segments; - for (int i = 0; i < segments.length; ++i) { - if (segments[i].count != 0) { + for (Segment<K, V> segment : segments) { + if (segment.count != 0) { return false; } - sum += segments[i].modCount; + sum += segment.modCount; } if (sum != 0L) { // recheck unless no modifications - for (int i = 0; i < segments.length; ++i) { - if (segments[i].count != 0) { + for (Segment<K, V> segment : segments) { + if (segment.count != 0) { return false; } - sum -= segments[i].modCount; + sum -= segment.modCount; } return sum == 0L; } @@ -3829,8 +3868,8 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> long longSize() { Segment<K, V>[] segments = this.segments; long sum = 0; - for (int i = 0; i < segments.length; ++i) { - sum += Math.max(0, segments[i].count); // see https://github.com/google/guava/issues/2108 + for (Segment<K, V> segment : segments) { + sum += Math.max(0, segment.count); // see https://github.com/google/guava/issues/2108 } return sum; } @@ -3840,6 +3879,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> return Ints.saturatedCast(longSize()); } + @CanIgnoreReturnValue // TODO(b/27479612): consider removing this @Override @CheckForNull public V get(@CheckForNull Object key) { @@ -3850,6 +3890,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> return segmentFor(hash).get(key, hash); } + @CanIgnoreReturnValue // TODO(b/27479612): consider removing this V get(K key, CacheLoader<? super K, V> loader) throws ExecutionException { int hash = hash(checkNotNull(key)); return segmentFor(hash).get(key, hash, loader); @@ -3867,7 +3908,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> return value; } - @SuppressWarnings("MissingOverride") // Supermethod will not exist if we build with --release 7. + @Override @CheckForNull public V getOrDefault(@CheckForNull Object key, @CheckForNull V defaultValue) { V result = get(key); @@ -4013,6 +4054,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> * Returns the internal entry for the specified key. The entry may be loading, expired, or * partially collected. */ + @CheckForNull ReferenceEntry<K, V> getEntry(@CheckForNull Object key) { // does not impact recency ordering if (key == null) { @@ -4077,6 +4119,8 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> return false; } + @CheckForNull + @CanIgnoreReturnValue @Override public V put(K key, V value) { checkNotNull(key); @@ -4085,6 +4129,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> return segmentFor(hash).put(key, hash, value, false); } + @CheckForNull @Override public V putIfAbsent(K key, V value) { checkNotNull(key); @@ -4100,6 +4145,8 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> } } + @CheckForNull + @CanIgnoreReturnValue @Override public V remove(@CheckForNull Object key) { if (key == null) { @@ -4109,6 +4156,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> return segmentFor(hash).remove(key, hash); } + @CanIgnoreReturnValue @Override public boolean remove(@CheckForNull Object key, @CheckForNull Object value) { if (key == null || value == null) { @@ -4118,6 +4166,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> return segmentFor(hash).remove(key, hash, value); } + @CanIgnoreReturnValue @Override public boolean replace(K key, @CheckForNull V oldValue, V newValue) { checkNotNull(key); @@ -4129,6 +4178,8 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> return segmentFor(hash).replace(key, hash, oldValue, newValue); } + @CheckForNull + @CanIgnoreReturnValue @Override public V replace(K key, V value) { checkNotNull(key); @@ -4151,7 +4202,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> } } - @RetainedWith @CheckForNull Set<K> keySet; + @LazyInit @RetainedWith @CheckForNull Set<K> keySet; @Override public Set<K> keySet() { @@ -4160,7 +4211,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> return (ks != null) ? ks : (keySet = new KeySet()); } - @RetainedWith @CheckForNull Collection<V> values; + @LazyInit @RetainedWith @CheckForNull Collection<V> values; @Override public Collection<V> values() { @@ -4169,7 +4220,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> return (vs != null) ? vs : (values = new Values()); } - @RetainedWith @CheckForNull Set<Entry<K, V>> entrySet; + @LazyInit @RetainedWith @CheckForNull Set<Entry<K, V>> entrySet; @Override @GwtIncompatible // Not supported. @@ -4398,7 +4449,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> private static <E> ArrayList<E> toArrayList(Collection<E> c) { // Avoid calling ArrayList(Collection), which may call back into toArray. - ArrayList<E> result = new ArrayList<E>(c.size()); + ArrayList<E> result = new ArrayList<>(c.size()); Iterators.addAll(result, c.iterator()); return result; } @@ -4583,7 +4634,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> builder.expireAfterAccess(expireAfterAccessNanos, TimeUnit.NANOSECONDS); } if (weigher != OneWeigher.INSTANCE) { - builder.weigher(weigher); + Object unused = builder.weigher(weigher); if (maxWeight != UNSET_INT) { builder.maximumWeight(maxWeight); } @@ -4654,7 +4705,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> } @Override - public final V apply(K key) { + public V apply(K key) { return autoDelegate.apply(key); } @@ -4672,7 +4723,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> final LocalCache<K, V> localCache; LocalManualCache(CacheBuilder<? super K, ? super V> builder) { - this(new LocalCache<K, V>(builder, null)); + this(new LocalCache<>(builder, null)); } private LocalManualCache(LocalCache<K, V> localCache) { @@ -4763,6 +4814,10 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> Object writeReplace() { return new ManualSerializationProxy<>(localCache); } + + private void readObject(ObjectInputStream in) throws InvalidObjectException { + throw new InvalidObjectException("Use ManualSerializationProxy"); + } } static class LocalLoadingCache<K, V> extends LocalManualCache<K, V> @@ -4770,7 +4825,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> LocalLoadingCache( CacheBuilder<? super K, ? super V> builder, CacheLoader<? super K, V> loader) { - super(new LocalCache<K, V>(builder, checkNotNull(loader))); + super(new LocalCache<>(builder, checkNotNull(loader))); } // LoadingCache methods @@ -4780,6 +4835,7 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> return localCache.getOrLoad(key); } + @CanIgnoreReturnValue // TODO(b/27479612): consider removing this @Override public V getUnchecked(K key) { try { @@ -4812,5 +4868,9 @@ class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> Object writeReplace() { return new LoadingSerializationProxy<>(localCache); } + + private void readObject(ObjectInputStream in) throws InvalidObjectException { + throw new InvalidObjectException("Use LoadingSerializationProxy"); + } } } |