LruCacheの使用とソースの詳細解析

8886 ワード

最初に引用を説明する準備ができましたが、ネット上には多くの優れた枠組みがあります.キャッシュについてはこれは基本的に全部使っています.
  LRUは、Least Recently Usedが最近少なくともアルゴリズムを使用する.実はLruCacheの役割はキャッシュの要素を並べ替えることです.設定されたメモリ値を超えると最低使用されます.一番早い元素を使って先に回収します.
LruCacheの声明:
LruCache , 。
。 , ( , , , , ,LruCache ):
    //lrucache           ,        remove       
    int cacheSize = 4; //      
    LruCache bitmapCache = new LruCache(cacheSize) {
        //         
        protected int sizeOf(String key, Bitmap value) {
            return 1;
        }
    }}

, 。
LruCache :
    //lrucache         ,        remove       
    int cacheSize = 4 * 1024 * 1024; // 4MiB
    LruCache bitmapCache = new LruCache(cacheSize) {
        //       bitmap        
        protected int sizeOf(String key, Bitmap value) {
            return value.getByteCount();
        }
    }}
    //    
	public  void  setItem(String key,Bitmap bitmap){
		cache.put(key, bitmap);
	}
	//    
	public  Bitmap  getItem(String key){
		return cache.get(key);
	}

LruCache , , 1/8. 。 : , :

    //  map,      lru   ,           
    private final LinkedHashMap map;

    //          
    private int size;
    //         
    private int maxSize;
    //remove      
    private int evictionCount;
    //     
    private int hitCount;
    //       
    private int missCount;

    //    
    public LruCache(int maxSize) {
        if (maxSize <= 0) {
            throw new IllegalArgumentException("maxSize <= 0");
        }
        this.maxSize = maxSize;
        //   map
        this.map = new LinkedHashMap(0, 0.75f, true);
    }
     public void resize(int maxSize) {
        if (maxSize <= 0) {
            throw new IllegalArgumentException("maxSize <= 0");
        }

        synchronized (this) {
            this.maxSize = maxSize;
        }
        trimToSize(maxSize);
    }

   // map     
    public final V get(K key) {
        if (key == null) {
            throw new NullPointerException("key == null");
        }

        V mapValue;
        synchronized (this) {
            mapValue = map.get(key);
            if (mapValue != null) {
                hitCount++;
                return mapValue;
            }
            missCount++;
        }

       
        V createdValue = create(key);
        if (createdValue == null) {
            return null;
        }

        synchronized (this) {
            createCount++;
            mapValue = map.put(key, createdValue);

            if (mapValue != null) {
                // There was a conflict so undo that last put
                map.put(key, mapValue);
            } else {
                size += safeSizeOf(key, createdValue);
            }
        }

        if (mapValue != null) {
            entryRemoved(false, key, createdValue, mapValue);
            return mapValue;
        } else {
            trimToSize(maxSize);
            return createdValue;
        }
    }

   //    
    public final V put(K key, V value) {
        if (key == null || value == null) {
            throw new NullPointerException("key == null || value == null");
        }

        V previous;
        synchronized (this) {
            putCount++;
            size += safeSizeOf(key, value);
            previous = map.put(key, value);
            if (previous != null) {
                size -= safeSizeOf(key, previous);
            }
        }

        if (previous != null) {
            entryRemoved(false, key, previous, value);
        }

        trimToSize(maxSize);
        return previous;
    }

   // size>maxsizes,         
    public void trimToSize(int maxSize) {
        while (true) {
            K key;
            V value;
            synchronized (this) {
                if (size < 0 || (map.isEmpty() && size != 0)) {
                    throw new IllegalStateException(getClass().getName()
                            + ".sizeOf() is reporting inconsistent results!");
                }

                if (size <= maxSize) {
                    break;
                }

                Map.Entry toEvict = map.eldest();
                if (toEvict == null) {
                    break;
                }

                key = toEvict.getKey();
                value = toEvict.getValue();
                map.remove(key);
                size -= safeSizeOf(key, value);
                evictionCount++;
            }

            entryRemoved(true, key, value, null);
        }
    }

   //      
    public final V remove(K key) {
        if (key == null) {
            throw new NullPointerException("key == null");
        }

        V previous;
        synchronized (this) {
            previous = map.remove(key);
            if (previous != null) {
                size -= safeSizeOf(key, previous);
            }
        }

        if (previous != null) {
            entryRemoved(false, key, previous, null);
        }

        return previous;
    }

    //    (    )
    protected int sizeOf(K key, V value) {
        return 1;
    }

   //      
    public final void evictAll() {
        trimToSize(-1); // -1 will evict 0-sized elements
    }

, , map 。 lruCache LinkedHashMap 。
LinkedHashMap,HashMap,AbstractMap,Map , <<LinkedHashMap >>, :