Example #1
0
  /**
   * 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]--;
    }
  }
Example #2
0
  /**
   * 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;
  }
Example #3
0
  /**
   * 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;
      }
    }
  }
Example #4
0
  /**
   * 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;
  }