Clover coverage report -
Coverage timestamp: Mo Mrz 6 2006 19:30:45 CET
file stats: LOC: 154   Methods: 7
NCLOC: 60   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
LRUCache.java 25% 77,8% 100% 76,3%
coverage coverage
 1    /*
 2    * Copyright (c) 2002-2003 by OpenSymphony
 3    * All rights reserved.
 4    */
 5    package com.opensymphony.oscache.base.algorithm;
 6   
 7    import org.apache.commons.logging.Log;
 8    import org.apache.commons.logging.LogFactory;
 9   
 10    import java.util.*;
 11   
 12    /**
 13    * <p>LRU (Least Recently Used) algorithm for the cache.</p>
 14    *
 15    * <p>Since release 2.3 this class requires Java 1.4
 16    * to use the <code>LinkedHashSet</code>. Use prior OSCache release which
 17    * require the Jakarta commons-collections <code>SequencedHashMap</code>
 18    * class or the <code>LinkedList</code> class if neither of the above
 19    * classes are available.</p>
 20    *
 21    * <p>No synchronization is required in this class since the
 22    * <code>AbstractConcurrentReadCache</code> already takes care of any
 23    * synchronization requirements.</p>
 24    *
 25    * @version $Revision: 1.3 $
 26    * @author <a href="mailto:salaman@teknos.com">Victor Salaman</a>
 27    * @author <a href="mailto:fbeauregard@pyxis-tech.com">Francois Beauregard</a>
 28    * @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
 29    * @author <a href="&#109;a&#105;&#108;&#116;&#111;:chris&#64;swebtec.&#99;&#111;&#109;">Chris Miller</a>
 30    */
 31    public class LRUCache extends AbstractConcurrentReadCache {
 32   
 33    private static final Log log = LogFactory.getLog(LRUCache.class);
 34   
 35    /**
 36    * Cache queue containing all cache keys.
 37    */
 38    private Collection list = new LinkedHashSet();
 39   
 40    /**
 41    * A flag indicating whether there is a removal operation in progress.
 42    */
 43    private volatile boolean removeInProgress = false;
 44   
 45    /**
 46    * Constructs an LRU Cache.
 47    */
 48  60 public LRUCache() {
 49  60 super();
 50    }
 51   
 52    /**
 53    * Constructors a LRU Cache of the specified capacity.
 54    *
 55    * @param capacity The maximum cache capacity.
 56    */
 57  36 public LRUCache(int capacity) {
 58  36 this();
 59  36 maxEntries = capacity;
 60    }
 61   
 62    /**
 63    * An item was retrieved from the list. The LRU implementation moves
 64    * the retrieved item's key to the front of the list.
 65    *
 66    * @param key The cache key of the item that was retrieved.
 67    */
 68  8258 protected void itemRetrieved(Object key) {
 69    // Prevent list operations during remove
 70  8258 while (removeInProgress) {
 71  0 try {
 72  0 Thread.sleep(5);
 73    } catch (InterruptedException ie) {
 74    }
 75    }
 76   
 77    // We need to synchronize here because AbstractConcurrentReadCache
 78    // doesn't prevent multiple threads from calling this method simultaneously.
 79  8258 synchronized (list) {
 80  8258 list.remove(key);
 81  8258 list.add(key);
 82    }
 83    }
 84   
 85    /**
 86    * An object was put in the cache. This implementation adds/moves the
 87    * key to the end of the list.
 88    *
 89    * @param key The cache key of the item that was put.
 90    */
 91  12303 protected void itemPut(Object key) {
 92    // Since this entry was just accessed, move it to the back of the list.
 93  12303 synchronized (list) { // A further fix for CACHE-44
 94  12303 list.remove(key);
 95  12303 list.add(key);
 96    }
 97    }
 98   
 99    /**
 100    * An item needs to be removed from the cache. The LRU implementation
 101    * removes the first element in the list (ie, the item that was least-recently
 102    * accessed).
 103    *
 104    * @return The key of whichever item was removed.
 105    */
 106  7228 protected Object removeItem() {
 107  7228 removeInProgress = true;
 108   
 109  7228 Object toRemove;
 110   
 111  7228 try {
 112  7228 toRemove = removeFirst();
 113    } catch (Exception e) {
 114    // List is empty.
 115    // this is theorically possible if we have more than the size concurrent
 116    // thread in getItem. Remove completed but add not done yet.
 117    // We simply wait for add to complete.
 118  0 do {
 119  0 try {
 120  0 Thread.sleep(5);
 121    } catch (InterruptedException ie) {
 122    }
 123  0 } while (list.size() == 0);
 124   
 125  0 toRemove = removeFirst();
 126    }
 127   
 128  7228 removeInProgress = false;
 129   
 130  7228 return toRemove;
 131    }
 132   
 133    /**
 134    * Remove specified key since that object has been removed from the cache.
 135    *
 136    * @param key The cache key of the item that was removed.
 137    */
 138  90 protected void itemRemoved(Object key) {
 139  90 list.remove(key);
 140    }
 141   
 142    /**
 143    * Removes the first object from the list of keys.
 144    *
 145    * @return the object that was removed
 146    */
 147  7228 private Object removeFirst() {
 148  7228 Iterator it = list.iterator();
 149  7228 Object toRemove = it.next();
 150  7228 it.remove();
 151   
 152  7228 return toRemove;
 153    }
 154    }