中级农民
- 积分
- 109
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2012-7-27
- 最后登录
- 1970-1-1
|
- package easy;
- import java.util.*;
- import java.util.concurrent.Semaphore;
- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReentrantLock;
- public class RetainBestCache<K, T extends Rankable> {
- int entriesToRetain;
- private Map<K, T> cache;
- private TreeMap<Long, Set<K>> rankingKeySetMap;
- Semaphore semaphore;
- DataSource<K,T> ds;
- /* Constructor with a data source (assumed to be slow) and a cache size */
- public RetainBestCache(DataSource<K,T> ds, int entriesToRetain) {
- cache = new HashMap<>();
- rankingKeySetMap = new TreeMap<>();
- this.ds = ds;
- this.entriesToRetain = entriesToRetain;
- semaphore = new Semaphore(entriesToRetain);
- }
- /* Gets some data. If possible, retrieves it from cache to be fast. If the data is not cached,
- * retrieves it from the data source. If the cache is full, attempt to cache the returned data,
- * evicting the T with lowest rank among the ones that it has available
- * If there is a tie, the cache may choose any T with lowest rank to evict.
- */
- public T get(K key) {
- //implement here
- if(cache.containsKey(key)){
- return cache.get(key);
- }
- return fetchFromDS(key);
- }
- private T fetchFromDS(K key){
- if(cache.size() >= entriesToRetain){
- evitLowestRank();
- }
- T object = ds.get(key);
- try{
- semaphore.acquire();
- cache.put(key, object);
- long score = object.getRank();
- if(!rankingKeySetMap.containsKey(score)){
- rankingKeySetMap.put(score, new HashSet<>());
- }
- rankingKeySetMap.get(score).add(key);
- }
- catch (InterruptedException e){
- }
- finally {
- semaphore.release();
- }
- return object;
- }
- private void evitLowestRank(){
- Map.Entry<Long, Set<K>> entry = rankingKeySetMap.firstEntry();
- K key = entry.getValue().iterator().next();
- entry.getValue().remove(key);
- cache.remove(key);
- if(entry.getValue().size() == 0){
- rankingKeySetMap.remove(entry.getKey());
- }
- }
- }
- /*
- * For reference, here are the Rankable and DataSource interfaces.
- * You do not need to implement them, and should not make assumptions
- * about their implementations.
- */
- public interface Rankable {
- /**
- * Returns the Rank of this object, using some algorithm and potentially
- * the internal state of the Rankable.
- */
- long getRank();
- }
- public interface DataSource<K, T extends Rankable> {
- T get(K key);
- }
复制代码 |
|