1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.cache;
17
18 import java.io.ByteArrayOutputStream;
19 import java.io.FileOutputStream;
20 import java.io.FileInputStream;
21 import java.io.ObjectOutputStream;
22 import java.io.ObjectInputStream;
23 import java.io.BufferedOutputStream;
24 import java.io.BufferedInputStream;
25 import java.io.Serializable;
26 import java.io.IOException;
27 import java.io.File;
28
29
30
31
32
33
34 public class SimpleCache extends BaseCache implements Cache {
35 protected GroupMap _gm = null;
36 protected EvictionPolicy _ep = null;
37 protected StashPolicy _sp = null;
38 protected Stash _stash = null;
39 protected boolean _wantsSerialized = false;
40 protected File _persistFile = null;
41
42 protected long _numRetrieveRequested = 0;
43 protected long _numRetrieveFound = 0;
44 protected long _numStoreRequested = 0;
45 protected long _numStoreStored = 0;
46 protected long _numCleared = 0;
47
48 public SimpleCache(Stash stash) {
49 this(stash,null,null,null);
50 }
51
52 public SimpleCache(Stash stash, EvictionPolicy ep) {
53 this(stash,ep,null,null);
54 }
55
56 public SimpleCache(Stash stash, EvictionPolicy ep, StashPolicy sp) {
57 this(stash,ep,sp,null,null);
58 }
59
60 public SimpleCache(Stash stash, EvictionPolicy ep, StashPolicy sp, GroupMap tm) {
61 this(stash,ep,sp,tm,null);
62 }
63
64 public SimpleCache(Stash stash, EvictionPolicy ep, StashPolicy sp, GroupMap tm, File persistFile) {
65 _gm = tm;
66 if(null != _gm) { tm.setCache(this); }
67 _stash = stash;
68 _stash.setCache(this);
69 _ep = ep;
70 if(null != _ep) { _ep.setCache(this); }
71 _sp = sp;
72 if(null != _sp) { _sp.setCache(this); }
73 _wantsSerialized = _stash.wantsSerializedForm() || ((null == _sp) ? false : _sp.wantsSerializedForm());
74 _persistFile = persistFile;
75 }
76
77 public synchronized long getStat(CacheStat stat) throws UnsupportedOperationException {
78 if(stat.equals(CacheStat.CUR_CAPACITY)) {
79 try {
80 return (long)(1000F * _stash.capacity());
81 } catch(Exception e) {
82 throw new UnsupportedOperationException();
83 }
84 } else if(stat.equals(CacheStat.NUM_CLEARED)) {
85 throw new UnsupportedOperationException();
86 } else if(stat.equals(CacheStat.NUM_RETRIEVE_FOUND)) {
87 return _numRetrieveFound;
88 } else if(stat.equals(CacheStat.NUM_RETRIEVE_NOT_FOUND)) {
89 return (_numRetrieveRequested - _numRetrieveFound);
90 } else if(stat.equals(CacheStat.NUM_RETRIEVE_REQUESTED)) {
91 return _numRetrieveRequested;
92 } else if(stat.equals(CacheStat.NUM_STORE_NOT_STORED)) {
93 return (_numStoreRequested - _numStoreStored);
94 } else if(stat.equals(CacheStat.NUM_STORE_REQUESTED)) {
95 return _numStoreRequested;
96 } else if(stat.equals(CacheStat.NUM_STORE_STORED)) {
97 return _numStoreStored;
98 } else {
99 throw new UnsupportedOperationException("CacheStat \"" + stat.toString() + "\" not recoginzed.");
100 }
101 }
102
103 public static SimpleCache readFromFile(String f) throws IOException, ClassNotFoundException {
104 return SimpleCache.readFromFile(new File(f));
105 }
106
107 public static SimpleCache readFromFile(File f) throws IOException, ClassNotFoundException {
108 ObjectInputStream in = null;
109 try {
110 in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(f)));
111 return (SimpleCache)(in.readObject());
112 } catch(ClassNotFoundException e) {
113 e.fillInStackTrace();
114 throw e;
115 } catch(IOException e) {
116 e.fillInStackTrace();
117 throw e;
118 } finally {
119 try { in.close(); } catch(Exception e) { }
120 }
121 }
122
123 protected synchronized void writeToFile() {
124 if(null == _persistFile) {
125 return;
126 } else {
127 ObjectOutputStream out = null;
128 try {
129 out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(_persistFile)));
130 out.writeObject(this);
131 out.flush();
132 } catch(Exception e) {
133 e.printStackTrace();
134 } finally {
135 try { out.close(); } catch(Exception e) { }
136 }
137 }
138 }
139
140 public Serializable[] getKeysForGroup(Serializable group) {
141 if(null == _gm) {
142 throw new IllegalStateException("no group map right now");
143 } else {
144 return _gm.getKeysForGroup(group);
145 }
146 }
147
148 public synchronized boolean store(Serializable key, Serializable val, Long expiry, Long cost, Serializable group) {
149 if(contains(key)) {
150 clear(key);
151 }
152 _numStoreRequested++;
153 if(null != expiry) {
154 if(expiry.longValue() <= System.currentTimeMillis()) {
155 return false;
156 }
157 }
158
159 broadcastStoreRequested(key,val,expiry,cost,group);
160 byte[] serform = null;
161 if(_wantsSerialized) {
162 ByteArrayOutputStream byout = null;
163 ObjectOutputStream out = null;
164 try {
165 byout = new ByteArrayOutputStream();
166 out = new ObjectOutputStream(byout);
167 out.writeObject(val);
168 out.flush();
169 serform = byout.toByteArray();
170 } catch(IOException e) {
171 serform = null;
172 } finally {
173 try { byout.close(); } catch(Exception e) { }
174 try { out.close(); } catch(Exception e) { }
175 }
176 }
177 if(_sp == null || _sp.shouldStore(key,val,expiry,cost,serform)) {
178 switch(_stash.canStore(key,val,expiry,cost,group,serform)) {
179 case Stash.YES:
180 _stash.store(key,val,expiry,cost,group,serform);
181 broadcastStored(key,val,expiry,cost,group);
182 _numStoreStored++;
183 writeToFile();
184 return true;
185 case Stash.NO_FULL:
186 if(tryToEvict()) {
187 return store(key,val,expiry,cost,group);
188 } else {
189 broadcastNotStored(key,val,expiry,cost,group);
190 return false;
191 }
192 case Stash.NO_NOT_STORABLE:
193 case Stash.NO:
194 default:
195 broadcastNotStored(key,val,expiry,cost,group);
196 return false;
197 }
198 } else {
199 broadcastNotStored(key,val,expiry,cost,group);
200 return false;
201 }
202 }
203
204 public synchronized Serializable retrieve(Serializable key) {
205 _numRetrieveRequested++;
206 broadcastRetrieveRequested(key);
207 Serializable obj = _stash.retrieve(key);
208 if(null == obj) {
209 broadcastNotRetrieved(key);
210 return null;
211 } else {
212 broadcastRetrieved(key);
213 _numRetrieveFound++;
214 return obj;
215 }
216 }
217
218 public synchronized boolean contains(Serializable key) {
219 return _stash.contains(key);
220 }
221
222 public synchronized void clear(Serializable key) {
223 _numCleared++;
224 _stash.clear(key);
225 broadcastCleared(key);
226 writeToFile();
227 }
228
229 public synchronized void clear() {
230 _stash.clear();
231 broadcastCleared();
232 writeToFile();
233 }
234
235 protected synchronized boolean tryToEvict() {
236 if(null == _ep) {
237 return false;
238 } else {
239 Serializable key = _ep.getEvictionCandidate();
240 if(null == key) {
241 return false;
242 } else {
243 clear(key);
244 return true;
245 }
246 }
247 }
248
249 public static void main(String[] args) throws Exception {
250 File cfile = null;
251 SimpleCache cache = null;
252 if(args.length > 0) {
253 ObjectInputStream in = null;
254 try {
255 in = new ObjectInputStream(new FileInputStream(new File(args[0])));
256 cache = (SimpleCache)(in.readObject());
257 } catch(Exception e) {
258 cache = null;
259 e.printStackTrace();
260 } finally {
261 try { in.close(); } catch(Exception e) { }
262 }
263 }
264
265 if(null == cache) {
266 LRUEvictionPolicy ep = new LRUEvictionPolicy();
267 Stash s = new FileStash(10000L);
268 cache = new SimpleCache(s,ep,null,null,new File("persitent.ser"));
269
270 System.out.println(cache.store("Key1","Value1",null,null));
271 System.out.println(cache.store("Key2","Value2",new Long(System.currentTimeMillis() + 10000),null));
272 System.out.println(cache.store("Key3","Value3",new Long(System.currentTimeMillis() + 9000),null));
273 System.out.println(cache.store("Key4","Value4",new Long(System.currentTimeMillis() + 8000),null));
274 System.out.println(cache.store("Key5","Value5",new Long(System.currentTimeMillis() + 7000),null));
275 System.out.println(cache.store("Key6","Value6",new Long(System.currentTimeMillis() + 6000),null));
276 System.out.println(cache.store("Key7","Value7",new Long(System.currentTimeMillis() + 5000),null));
277 System.out.println(cache.store("Key8","Value8",new Long(System.currentTimeMillis() + 4000),null));
278 System.out.println(cache.store("Key9","Value9",new Long(System.currentTimeMillis() + 3000),null));
279 System.out.println(cache.store("Key10","Value10",new Long(System.currentTimeMillis() + 40000),null));
280 System.out.println(cache.store("Key11","Value11",new Long(System.currentTimeMillis() + 30000),null));
281 System.out.println(cache.store("Key12","Value12",new Long(System.currentTimeMillis() + 20000),null));
282
283 if(args.length > 0) {
284 ObjectOutputStream out = null;
285 try {
286 out = new ObjectOutputStream(new FileOutputStream(new File(args[0])));
287 out.writeObject(cache);
288 } catch(Exception e) {
289 e.printStackTrace();
290 } finally {
291 try { out.close(); } catch(Exception e) { }
292 }
293 }
294 }
295
296 for(int i=0;i<12;i++) {
297 System.out.println("Key1\t" + cache.retrieve("Key1"));
298 System.out.println("Key2\t" + cache.retrieve("Key2"));
299 System.out.println("Key3\t" + cache.retrieve("Key3"));
300 System.out.println("Key4\t" + cache.retrieve("Key4"));
301 System.out.println("Key5\t" + cache.retrieve("Key5"));
302 System.out.println("Key6\t" + cache.retrieve("Key6"));
303 System.out.println("Key7\t" + cache.retrieve("Key7"));
304 System.out.println("Key8\t" + cache.retrieve("Key8"));
305 System.out.println("Key9\t" + cache.retrieve("Key9"));
306 System.out.println("Key10\t" + cache.retrieve("Key10"));
307 System.out.println("Key11\t" + cache.retrieve("Key11"));
308 System.out.println("Key12\t" + cache.retrieve("Key12"));
309
310 System.out.println();
311 Thread.sleep(1000L);
312 }
313 }
314 }