Guava---Cache
Cache
概述
A semi-persistent mapping from keys to values.
Cache entries are manually added using {@link #get(Object, Callable)} or {@link #put(Object, Object)}, and are stored in the cache until either evicted or manually invalidated.
The common way to build instances is using {@link CacheBuilder}.
k-v半持久化映射;
Cache的entry 被手动使用get(Object, Callable), put(Object, Object);
创建Cache实例 通常使用CacheBuilder;
Implementations of this interface are expected to be thread-safe, and can be safely accessed by multiple concurrent threads.
Cache的实现应该是线程安全的;
/**
* @param <K> the type of the cache's keys, which are not permitted to be null
* @param <V> the type of the cache's values, which are not permitted to be null
*/
public interface Cache<K, V> {
/**
* Returns the value associated with {@code key} in this cache, or {@code null} if there is no cached value for {@code key}.
*/
V getIfPresent(@CompatibleWith("K") Object key);
/**
* Returns the value associated with {@code key} in this cache, obtaining that value from {@code loader} if necessary. 返回key关联的value,如果不存在,从Loader中获取
* The method improves upon the conventional "if cached, return; otherwise create, cache and return" pattern. 改进了 if cached, return; otherwise create, cache and return 的范式
* For further improvements, use {@link LoadingCache} and its {@link LoadingCache#get(Object) get(K)} method instead of this one.
*/
V get(K key, Callable<? extends V> loader) throws ExecutionException;
/**
* Associates {@code value} with {@code key} in this cache.
* If the cache previously contained a value associated with {@code key}, the old value is replaced by {@code value}. 如果key存在,new替换old
* Prefer {@link #get(Object, Callable)} when using the conventional "if cached, return; otherwise create, cache and return" pattern.
* @param key
* @param value
*/
void put(K key, V value);
/**
* Discards any cached value for key {@code key}.
*/
void invalidate(@CompatibleWith("K") Object key);
/**
* For discussion of <? extends Object>, see getAllPresent.
*/
void invalidateAll(Iterable<? extends Object> keys);
/**
* Discards all entries in the cache.
*/
void invalidateAll();
}
链路
CacheBuilder.newBuilder().build()
// com.google.common.cache.CacheBuilder.newBuilder
public final class CacheBuilder<K, V> {
private CacheBuilder() {
}
public static CacheBuilder<Object, Object> newBuilder() {
return new CacheBuilder<>();
}
public <K1 extends K, V1 extends V> Cache<K1, V1> build() {
checkWeightWithWeigher();
checkNonLoadingCache();
return new LocalCache.LocalManualCache<>(this);
}
}
// com.google.common.cache.LocalCache
class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> {
static class LocalManualCache<K, V> implements Cache<K, V>, Serializable {
final LocalCache<K, V> localCache;
private LocalManualCache(LocalCache<K, V> localCache) {
this.localCache = localCache;
}
}
}
Put
// com.google.common.cache.LocalCache
class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> {
static class LocalManualCache<K, V> implements Cache<K, V>, Serializable {
final LocalCache<K, V> localCache;
private LocalManualCache(LocalCache<K, V> localCache) {
this.localCache = localCache;
}
public void put(K key, V value) {
localCache.put(key, value);
}
}
static class Segment<K, V> extends ReentrantLock {
V put(K key, int hash, V value, boolean onlyIfAbsent) {
}
}
/** The segments, each of which is a specialized hash table. */
final Segment<K, V>[] segments;
/**
* Shift value for indexing within segments.
* Helps prevent entries that end up in the same segment from also ending up in the same bucket.
*/
final int segmentShift;
/**
* Mask value for indexing into segments.
* The upper bits of a key's hash code are used to choose the segment.
*/
final int segmentMask;
public V put(K key, V value) {
checkNotNull(key);
checkNotNull(value);
int hash = hash(key);
return segmentFor(hash).put(key, hash, value, false);
}
Segment<K, V> segmentFor(int hash) {
// TODO(fry): Lazily create segments?
return segments[(hash >>> segmentShift) & segmentMask];
}
}
浙公网安备 33010602011771号