/** * 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]--; } }
/** * this item is just added to the cache * * @param item <code>CacheItem</code> that was created * @return a overflow item; may be null * <p>Cache bucket is already synchronized by the caller */ protected CacheItem itemAdded(CacheItem item) { CacheItem overflow = null; if (!(item instanceof LruCacheItem)) return null; LruCacheItem lc = (LruCacheItem) item; int index = getIndex(item.hashCode()); int segment = (index / segmentSize); LruCacheItem[] list = lists[segment]; // update the LRU synchronized (list) { if (list[LRU_HEAD] != null) { list[LRU_HEAD].lPrev = lc; lc.lNext = list[LRU_HEAD]; } else list[LRU_TAIL] = lc; list[LRU_HEAD] = lc; listsLength[segment]++; if (isThresholdReached()) { overflow = trimLru(trimIndex); // go round robin for the next trim incrementTrimIndex(); } } return overflow; }