具体文件LruMemoryCache
在我看来,应该用的数据结构是arraylist,然后将各个key值的索引数字记录下来,然后去更新对应的索引,不对啊,这个是LFU!!
好吧,应该用一个链表来把数据串起来,然后去更新数据。核心问题点是如何在buffer满的时候移除老的数据呢??直接移除吧!!自己搞混了LFU和LRU导致思路混乱。
private final LinkedHashMap<String, Bitmap> map;
private final int maxSize;
/** Size of this cache in bytes */
private int size;
从上面看出数据结构是LinkedHashMap(我自己可能会搞个Linked 然后把Map存进去)
还有就是maxSize,size,这两个变量作为裁剪的变量@Override public final Bitmap get(String key) { if (key == null) { throw new NullPointerException("key == null"); } synchronized (this) { return map.get(key); } }
直接用map里面取到数据,取的时候,会将数据先断开连接,然后放在链表的尾巴上去,这个时候是最新用的数据。具体实现:private void makeTail(LinkedEntry<K, V> e) { // Unlink e e.prv.nxt = e.nxt; e.nxt.prv = e.prv; // Relink e as tail LinkedEntry<K, V> header = this.header; LinkedEntry<K, V> oldTail = header.prv; e.nxt = header; e.prv = oldTail; oldTail.nxt = header.prv = e; modCount++; }
@Override public final boolean put(String key, Bitmap value) { if (key == null || value == null) { throw new NullPointerException("key == null || value == null"); } synchronized (this) { size += sizeOf(key, value); Bitmap previous = map.put(key, value); if (previous != null) { size -= sizeOf(key, previous); } } trimToSize(maxSize); return true; }
上述代码将数据会存到map中,然后更新size,最重要的是对数组做裁剪
具体裁剪的代码如下:
private void trimToSize(int maxSize) { while (true) { String key; Bitmap value; synchronized (this) { if (size < 0 || (map.isEmpty() && size != 0)) { throw new IllegalStateException(getClass().getName() + ".sizeOf() is reporting inconsistent results!"); } //裁剪完成了,直接中断循环 if (size <= maxSize || map.isEmpty()) { break; } Map.Entry<String, Bitmap> toEvict = map.entrySet().iterator().next(); if (toEvict == null) { break; } key = toEvict.getKey(); value = toEvict.getValue(); map.remove(key); size -= sizeOf(key, value); } } }
上述代码用迭代器来取,先取最老的数据,然后每次做裁剪,如果裁剪到内存以内,那么终止裁剪