diff options
author | Yohann Roussel <yroussel@google.com> | 2014-03-19 16:25:37 +0100 |
---|---|---|
committer | Yohann Roussel <yroussel@google.com> | 2014-03-20 15:13:33 +0100 |
commit | 4eceb95409e844fdc33c9c706e1dc307bfd40303 (patch) | |
tree | ee9f4f3fc79f757c79081c336bce4f1782c6ccd8 /guava/src/com/google/common/cache/AbstractCache.java | |
parent | 3d2402901b1a6462e2cf47a6fd09711f327961c3 (diff) | |
download | toolchain_jack-4eceb95409e844fdc33c9c706e1dc307bfd40303.zip toolchain_jack-4eceb95409e844fdc33c9c706e1dc307bfd40303.tar.gz toolchain_jack-4eceb95409e844fdc33c9c706e1dc307bfd40303.tar.bz2 |
Initial Jack import.
Change-Id: I953cf0a520195a7187d791b2885848ad0d5a9b43
Diffstat (limited to 'guava/src/com/google/common/cache/AbstractCache.java')
-rw-r--r-- | guava/src/com/google/common/cache/AbstractCache.java | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/guava/src/com/google/common/cache/AbstractCache.java b/guava/src/com/google/common/cache/AbstractCache.java new file mode 100644 index 0000000..0d98a2d --- /dev/null +++ b/guava/src/com/google/common/cache/AbstractCache.java @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2011 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.cache; + +import com.google.common.annotations.Beta; +import com.google.common.annotations.GwtCompatible; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; + +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ExecutionException; + +/** + * This class provides a skeletal implementation of the {@code Cache} interface to minimize the + * effort required to implement this interface. + * + * <p>To implement a cache, the programmer needs only to extend this class and provide an + * implementation for the {@link #put} and {@link #getIfPresent} methods. {@link #getAllPresent} is + * implemented in terms of {@link #getIfPresent}; {@link #putAll} is implemented in terms of + * {@link #put}, {@link #invalidateAll(Iterable)} is implemented in terms of {@link #invalidate}. + * The method {@link #cleanUp} is a no-op. All other methods throw an + * {@link UnsupportedOperationException}. + * + * @author Charles Fry + * @since 10.0 + */ +@Beta +@GwtCompatible +public abstract class AbstractCache<K, V> implements Cache<K, V> { + + /** Constructor for use by subclasses. */ + protected AbstractCache() {} + + /** + * @since 11.0 + */ + @Override + public V get(K key, Callable<? extends V> valueLoader) throws ExecutionException { + throw new UnsupportedOperationException(); + } + + /** + * This implementation of {@code getAllPresent} lacks any insight into the internal cache data + * structure, and is thus forced to return the query keys instead of the cached keys. This is only + * possible with an unsafe cast which requires {@code keys} to actually be of type {@code K}. + * + * {@inheritDoc} + * + * @since 11.0 + */ + @Override + public ImmutableMap<K, V> getAllPresent(Iterable<?> keys) { + Map<K, V> result = Maps.newLinkedHashMap(); + for (Object key : keys) { + if (!result.containsKey(key)) { + @SuppressWarnings("unchecked") + K castKey = (K) key; + result.put(castKey, getIfPresent(key)); + } + } + return ImmutableMap.copyOf(result); + } + + /** + * @since 11.0 + */ + @Override + public void put(K key, V value) { + throw new UnsupportedOperationException(); + } + + /** + * @since 12.0 + */ + @Override + public void putAll(Map<? extends K, ? extends V> m) { + for (Map.Entry<? extends K, ? extends V> entry : m.entrySet()) { + put(entry.getKey(), entry.getValue()); + } + } + + @Override + public void cleanUp() {} + + @Override + public long size() { + throw new UnsupportedOperationException(); + } + + @Override + public void invalidate(Object key) { + throw new UnsupportedOperationException(); + } + + /** + * @since 11.0 + */ + @Override + public void invalidateAll(Iterable<?> keys) { + for (Object key : keys) { + invalidate(key); + } + } + + @Override + public void invalidateAll() { + throw new UnsupportedOperationException(); + } + + @Override + public CacheStats stats() { + throw new UnsupportedOperationException(); + } + + @Override + public ConcurrentMap<K, V> asMap() { + throw new UnsupportedOperationException(); + } + + /** + * Accumulates statistics during the operation of a {@link Cache} for presentation by {@link + * Cache#stats}. This is solely intended for consumption by {@code Cache} implementors. + * + * @since 10.0 + */ + @Beta + public interface StatsCounter { + /** + * Records cache hits. This should be called when a cache request returns a cached value. + * + * @param count the number of hits to record + * @since 11.0 + */ + public void recordHits(int count); + + /** + * Records cache misses. This should be called when a cache request returns a value that was + * not found in the cache. This method should be called by the loading thread, as well as by + * threads blocking on the load. Multiple concurrent calls to {@link Cache} lookup methods with + * the same key on an absent value should result in a single call to either + * {@code recordLoadSuccess} or {@code recordLoadException} and multiple calls to this method, + * despite all being served by the results of a single load operation. + * + * @param count the number of misses to record + * @since 11.0 + */ + public void recordMisses(int count); + + /** + * Records the successful load of a new entry. This should be called when a cache request + * causes an entry to be loaded, and the loading completes successfully. In contrast to + * {@link #recordMisses}, this method should only be called by the loading thread. + * + * @param loadTime the number of nanoseconds the cache spent computing or retrieving the new + * value + */ + public void recordLoadSuccess(long loadTime); + + /** + * Records the failed load of a new entry. This should be called when a cache request causes + * an entry to be loaded, but an exception is thrown while loading the entry. In contrast to + * {@link #recordMisses}, this method should only be called by the loading thread. + * + * @param loadTime the number of nanoseconds the cache spent computing or retrieving the new + * value prior to an exception being thrown + */ + public void recordLoadException(long loadTime); + + /** + * Records the eviction of an entry from the cache. This should only been called when an entry + * is evicted due to the cache's eviction strategy, and not as a result of manual {@linkplain + * Cache#invalidate invalidations}. + */ + public void recordEviction(); + + /** + * Returns a snapshot of this counter's values. Note that this may be an inconsistent view, as + * it may be interleaved with update operations. + */ + public CacheStats snapshot(); + } + + /** + * A thread-safe {@link StatsCounter} implementation for use by {@link Cache} implementors. + * + * @since 10.0 + */ + @Beta + public static final class SimpleStatsCounter implements StatsCounter { + private final LongAdder hitCount = new LongAdder(); + private final LongAdder missCount = new LongAdder(); + private final LongAdder loadSuccessCount = new LongAdder(); + private final LongAdder loadExceptionCount = new LongAdder(); + private final LongAdder totalLoadTime = new LongAdder(); + private final LongAdder evictionCount = new LongAdder(); + + /** + * Constructs an instance with all counts initialized to zero. + */ + public SimpleStatsCounter() {} + + /** + * @since 11.0 + */ + @Override + public void recordHits(int count) { + hitCount.add(count); + } + + /** + * @since 11.0 + */ + @Override + public void recordMisses(int count) { + missCount.add(count); + } + + @Override + public void recordLoadSuccess(long loadTime) { + loadSuccessCount.increment(); + totalLoadTime.add(loadTime); + } + + @Override + public void recordLoadException(long loadTime) { + loadExceptionCount.increment(); + totalLoadTime.add(loadTime); + } + + @Override + public void recordEviction() { + evictionCount.increment(); + } + + @Override + public CacheStats snapshot() { + return new CacheStats( + hitCount.sum(), + missCount.sum(), + loadSuccessCount.sum(), + loadExceptionCount.sum(), + totalLoadTime.sum(), + evictionCount.sum()); + } + + /** + * Increments all counters by the values in {@code other}. + */ + public void incrementBy(StatsCounter other) { + CacheStats otherStats = other.snapshot(); + hitCount.add(otherStats.hitCount()); + missCount.add(otherStats.missCount()); + loadSuccessCount.add(otherStats.loadSuccessCount()); + loadExceptionCount.add(otherStats.loadExceptionCount()); + totalLoadTime.add(otherStats.totalLoadTime()); + evictionCount.add(otherStats.evictionCount()); + } + } +} |