一、前言
关于taobao的tddl-common包(5.1.0)的com.taobao.tddl.common.utils.GoogleConcurrentLruCache最近最少使用置换算法,详见源码说明。
二、源码说明
package com.taobao.tddl.common.utils;@b@@b@import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;@b@import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap.Builder;@b@import com.googlecode.concurrentlinkedhashmap.EvictionListener;@b@import com.googlecode.concurrentlinkedhashmap.Weighers;@b@import java.util.Set;@b@import java.util.concurrent.atomic.AtomicLong;@b@@b@public class GoogleConcurrentLruCache<K, V>@b@{@b@ private ConcurrentLinkedHashMap<K, V> cache;@b@ private static final int DEFAULT_CAPACITY = 389;@b@ public static final int DEFAULT_CONCURENCY_LEVEL = 64;@b@ private AtomicLong get;@b@ private AtomicLong hit;@b@@b@ public GoogleConcurrentLruCache()@b@ {@b@ this(389);@b@ }@b@@b@ public GoogleConcurrentLruCache(int capacity)@b@ {@b@ this.get = new AtomicLong(0L);@b@ this.hit = new AtomicLong(0L);@b@@b@ if (capacity <= 0) {@b@ capacity = 389;@b@ }@b@@b@ this.cache = new ConcurrentLinkedHashMap.Builder().maximumWeightedCapacity(capacity).weigher(Weighers.singleton()).concurrencyLevel(64).build();@b@ }@b@@b@ public GoogleConcurrentLruCache(int capacity, EvictionListener<K, V> listener)@b@ {@b@ this.get = new AtomicLong(0L);@b@ this.hit = new AtomicLong(0L);@b@@b@ if (capacity <= 0) {@b@ capacity = 389;@b@ }@b@@b@ this.cache = new ConcurrentLinkedHashMap.Builder().maximumWeightedCapacity(capacity).weigher(Weighers.singleton()).concurrencyLevel(64).listener(listener).build();@b@ }@b@@b@ public long capacity()@b@ {@b@ return this.cache.capacity();@b@ }@b@@b@ public boolean isEmpty() {@b@ return this.cache.isEmpty();@b@ }@b@@b@ public int size() {@b@ return this.cache.size();@b@ }@b@@b@ public void clear() {@b@ this.cache.clear();@b@ }@b@@b@ public V get(Object key) {@b@ Object v = this.cache.get(key);@b@ this.get.addAndGet(1L);@b@ if (v != null) {@b@ this.hit.addAndGet(1L);@b@ }@b@@b@ return v;@b@ }@b@@b@ public void put(K key, V value) {@b@ this.cache.put(key, value);@b@ }@b@@b@ public boolean putIfAbsent(K key, V value) {@b@ return (this.cache.putIfAbsent(key, value) == null);@b@ }@b@@b@ public boolean replace(K key, V old, V value) {@b@ return this.cache.replace(key, old, value);@b@ }@b@@b@ public void remove(K key) {@b@ this.cache.remove(key);@b@ }@b@@b@ public Set<K> keySet() {@b@ return this.cache.keySet();@b@ }@b@@b@ public Set<K> hotKeySet(int n) {@b@ return this.cache.descendingKeySetWithLimit(n);@b@ }@b@@b@ public boolean containsKey(K key) {@b@ return this.cache.containsKey(key);@b@ }@b@@b@ public String getStatus() {@b@ StringBuilder sb = new StringBuilder();@b@ sb.append("current size:");@b@ sb.append(this.cache.size());@b@ sb.append(" get:");@b@ sb.append(this.get);@b@ sb.append(" hit:");@b@ sb.append(this.hit);@b@ sb.append(" hit ratio:");@b@ if (this.get.longValue() > 0L) {@b@ sb.append(this.hit.doubleValue() / this.get.doubleValue() * 100.0D);@b@ sb.append("%");@b@ } else {@b@ sb.append("--");@b@ }@b@@b@ this.get.set(0L);@b@ this.hit.set(0L);@b@@b@ return sb.toString();@b@ }@b@}