View Javadoc

1   /*
2    * Copyright 2001-2004 The Apache Software Foundation
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  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   * tk.
31   * @version $Id: SimpleCache.java 155435 2005-02-26 13:17:27Z dirkv $
32   * @author Rodney Waldhoff
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); // stash cannot be null
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 }