View Javadoc

1   /**
2    *  Copyright 2003-2006 Greg Luck
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  
17  package net.sf.ehcache.store;
18  
19  import net.sf.ehcache.Cache;
20  import net.sf.ehcache.Element;
21  import net.sf.ehcache.CacheException;
22  import org.apache.commons.collections.SequencedHashMap;
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  
26  import java.io.Serializable;
27  import java.util.Iterator;
28  import java.util.LinkedHashMap;
29  import java.util.Set;
30  
31  /**
32   * First-In-First-Out (FIFO) implementation of MemoryStore.
33   *
34   * @author <a href="mailto:ssuravarapu@users.sourceforge.net">Surya Suravarapu</a>
35   * @version $Id: FifoMemoryStore.java 52 2006-04-24 14:50:03Z gregluck $
36   */
37  public final class FifoMemoryStore extends MemoryStore {
38      private static final Log LOG = LogFactory.getLog(FifoMemoryStore.class.getName());
39  
40      private final static int SEQUENCED_HASH_MAP = 1;
41  
42      private final static int LINKED_HASH_MAP = 2;
43  
44      /**
45       * One of the above declared static collection types
46       */
47      private int collectionType;
48  
49      /**
50       * Constructor for the FifoMemoryStore object.
51       * <p/>
52       * First tries to use {@link java.util.LinkedHashMap}. If not found uses
53       * Jakarta Commons collections.
54       */
55      public FifoMemoryStore(Cache cache, DiskStore diskStore) {
56          super(cache, diskStore);
57  
58          // Use LinkedHashMap for JDK 1.4 and higher
59          try {
60              Class.forName("java.util.LinkedHashMap");
61              map = new LinkedHashMap();
62              collectionType = LINKED_HASH_MAP;
63          } catch (ClassNotFoundException e) {
64              // If not JDK 1.4 use the commons collections
65              try {
66                  Class.forName("org.apache.commons.collections.SequencedHashMap");
67                  map = new SequencedHashMap();
68                  collectionType = SEQUENCED_HASH_MAP;
69              } catch (ClassNotFoundException ee) {
70                  LOG.error(ee.getMessage());
71              }
72          }
73      }
74  
75      /**
76       * Allow specialised actions over adding the element to the map
77       *
78       * @param element
79       */
80      protected final void doPut(Element element) throws CacheException {
81          if (isFull()) {
82              removeFirstElement();
83          }
84      }
85  
86  
87      /**
88       * Returns the first eligible element that can be taken out of the cache
89       * based on the FIFO policy
90       */
91      Element getFirstElement() {
92          if (map.size() == 0) {
93              return null;
94          }
95  
96          Element element = null;
97          Serializable key;
98  
99          if (collectionType == LINKED_HASH_MAP) {
100             Set keySet = map.keySet();
101             Iterator itr = keySet.iterator();
102             // The first element is the candidate to remove
103             if (itr.hasNext()) {
104                 key = (Serializable) itr.next();
105                 element = (Element) map.get(key);
106             }
107         } else if (collectionType == SEQUENCED_HASH_MAP) {
108             key = (Serializable) ((SequencedHashMap) map).getFirstKey();
109             element = (Element) map.get(key);
110         }
111 
112         return element;
113     }
114 
115     /**
116      * Remove the first element that is eligible to removed from the store
117      * based on the FIFO policy
118      */
119     private void removeFirstElement() throws CacheException {
120         Element element = getFirstElement();
121 
122         if (cache.isExpired(element)) {
123             remove(element.getObjectKey());
124             notifyExpiry(element);
125             return;
126         }
127         remove(element.getObjectKey());
128         evict(element);
129     }
130 }