/** * this item is accessed * * @param item <code>CacheItem</code> accessed * <p>Cache bucket is already synchronized by the caller */ protected void itemAccessed(CacheItem item) { int index = getIndex(item.hashCode()); int segment = (index / segmentSize); LruCacheItem[] list = lists[segment]; if (!(item instanceof LruCacheItem)) return; LruCacheItem lc = (LruCacheItem) item; // update the LRU list synchronized (list) { LruCacheItem prev = lc.lPrev; LruCacheItem next = lc.lNext; if (prev != null) { // put the item at the head of LRU list lc.lPrev = null; lc.lNext = list[LRU_HEAD]; list[LRU_HEAD].lPrev = lc; list[LRU_HEAD] = lc; // patch up the previous neighbors prev.lNext = next; if (next != null) next.lPrev = prev; else list[LRU_TAIL] = prev; } } }
/** * item value has been removed from the cache * * @param item <code>CacheItem</code> that was just removed * <p>Cache bucket is already synchronized by the caller */ protected void itemRemoved(CacheItem item) { if (!(item instanceof LruCacheItem)) return; LruCacheItem l = (LruCacheItem) item; int index = getIndex(item.hashCode()); int segment = (index / segmentSize); LruCacheItem[] list = lists[segment]; // remove the item from the LRU list synchronized (list) { // if the item is already trimmed from the LRU list, nothing to do. if (l.isTrimmed) return; LruCacheItem prev = l.lPrev; LruCacheItem next = l.lNext; // patch up the neighbors and make sure head/tail are correct if (prev != null) prev.lNext = next; else list[LRU_HEAD] = next; if (next != null) next.lPrev = prev; else list[LRU_TAIL] = prev; listsLength[segment]--; } }
/** * remove an lru item from one of the LRU lists * * @param the LRU segment index to trim * @return the item that was successfully trimmed */ protected CacheItem trimLru(int segment) { LruCacheItem[] list = lists[segment]; LruCacheItem l = null; l = list[LRU_TAIL]; list[LRU_TAIL] = l.lPrev; list[LRU_TAIL].lNext = null; l.lPrev = null; listsLength[segment]--; l.isTrimmed = true; trimCount++; return l; }