KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > suberic > util > cache > AbstractSizedCache


1 package net.suberic.util.cache;
2 import java.util.*;
3
4 /**
5  * This is a simple implementation of a sized cache. It uses
6  * SizedCacheEntry objects to store wrap its values and to keep track
7  * the items' sizes and last accessed times.
8  */

9 public abstract class AbstractSizedCache {
10   
11   protected HashMap cacheTable = new HashMap();
12
13   protected LinkedList sortedKeys = new LinkedList();
14
15   protected long size = 0;
16
17   private long maxSize = 0;
18
19   private long maxEntrySize = 0;
20
21   private SizedCacheEntryFactory factory = null;
22  
23   /**
24    * Adds an object to the Cache.
25    */

26   public synchronized void add(Object JavaDoc key, Object JavaDoc value) {
27     if (value == null) {
28       invalidateCache(key);
29     } else {
30       SizedCacheEntry origEntry = (SizedCacheEntry) cacheTable.get(key);
31       if (origEntry == null || ! origEntry.equals(value)) {
32     invalidateCache(key);
33     
34     SizedCacheEntry sce = getFactory().createCacheEntry(value);
35     
36     if (getMaxEntrySize() >= 0 && sce.getSize() < getMaxEntrySize()) {
37       if (getMaxSize() >= 0) {
38         while (sce.getSize() + getSize() > getMaxSize()) {
39           // keep removing the last entry in the table until there's
40
// enough space.
41
Object JavaDoc lastAccessedKey = sortedKeys.getLast();
42           invalidateCache(lastAccessedKey);
43         }
44       }
45       cacheTable.put(key, sce);
46       size += sce.getSize();
47       reorderEntry(key);
48     }
49       }
50     }
51   }
52     
53   /**
54    * Gets an object from the Cache. If the object is not available,
55    * returns null.
56    */

57   public synchronized Object JavaDoc get(Object JavaDoc key) {
58     SizedCacheEntry sce = (SizedCacheEntry) cacheTable.get(key);
59     if (sce != null) {
60       Object JavaDoc returnValue = sce.getCachedValue();
61       sce.touchEntry();
62       reorderEntry(sce);
63       return returnValue;
64     } else
65       return null;
66   }
67
68   /**
69    * Removes an object from the Cache.
70    */

71   public synchronized void invalidateCache(Object JavaDoc key) {
72     SizedCacheEntry value = (SizedCacheEntry) cacheTable.get(key);
73     if (value != null) {
74       size -= value.getSize();
75       value.removeFromCache();
76     }
77
78     sortedKeys.remove(key);
79     cacheTable.remove(key);
80   }
81
82   /**
83    * Invalidates the entire cache.
84    */

85   public synchronized void invalidateCache() {
86     Iterator it = cacheTable.keySet().iterator();
87     while (it.hasNext()) {
88       Object JavaDoc key = it.next();
89       SizedCacheEntry entry = (SizedCacheEntry) cacheTable.get(key);
90       if (entry != null) {
91     entry.removeFromCache();
92       }
93       cacheTable.remove(key);
94     }
95   }
96
97   /**
98    * Reorders the entry in the sortedKeys list.
99    */

100   private void reorderEntry(Object JavaDoc key) {
101     sortedKeys.remove(key);
102     sortedKeys.addFirst(key);
103   }
104
105   /**
106    * Gets the size limit for the cache.
107    */

108   public long getMaxSize() {
109     return maxSize;
110   }
111
112   /**
113    * Sets the size limit for the cache.
114    */

115   public void setMaxSize(long newSize) {
116     maxSize = newSize;
117   }
118
119   /**
120    * Gets the size limit for individual entries in the cache.
121    */

122   public long getMaxEntrySize() {
123     return maxEntrySize;
124   }
125
126   /**
127    * Sets the size limit for individual entries in the cache.
128    */

129   public void setMaxEntrySize(long newSize) {
130     maxEntrySize = newSize;
131   }
132
133   /**
134    * Gets the current size of the cache.
135    */

136   public long getSize() {
137     return size;
138   }
139
140   /**
141    * Gets the SizedCacheEntryFactory for this cache.
142    */

143   public SizedCacheEntryFactory getFactory() {
144     return factory;
145   }
146
147   /**
148    * Sets the SizedCacheEntryFactory for this cache.
149    */

150   public void setFactory(SizedCacheEntryFactory newFactory) {
151     if (newFactory != null) {
152       factory = newFactory;
153     }
154   }
155 }
156
Popular Tags