KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > io > ExpiringCache


1 /*
2  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
3  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
4  */

5
6 /*
7  * @(#)ExpiringCache.java 1.5 04/02/13
8  */

9
10 package java.io;
11
12 import java.util.Iterator JavaDoc;
13 import java.util.Map JavaDoc;
14 import java.util.LinkedHashMap JavaDoc;
15 import java.util.Set JavaDoc;
16
17 class ExpiringCache {
18     private long millisUntilExpiration;
19     private Map JavaDoc map;
20     // Clear out old entries every few queries
21
private int queryCount;
22     private int queryOverflow = 300;
23     private int MAX_ENTRIES = 200;
24
25     static class Entry {
26         private long timestamp;
27         private String JavaDoc val;
28         
29         Entry(long timestamp, String JavaDoc val) {
30             this.timestamp = timestamp;
31             this.val = val;
32         }
33
34         long timestamp() { return timestamp; }
35         void setTimestamp(long timestamp) { this.timestamp = timestamp; }
36
37         String JavaDoc val() { return val; }
38         void setVal(String JavaDoc val) { this.val = val; }
39     }
40
41     ExpiringCache() {
42         this(30000);
43     }
44
45     ExpiringCache(long millisUntilExpiration) {
46         this.millisUntilExpiration = millisUntilExpiration;
47         map = new LinkedHashMap JavaDoc() {
48             protected boolean removeEldestEntry(Map.Entry JavaDoc eldest) {
49               return size() > MAX_ENTRIES;
50             }
51           };
52     }
53
54     synchronized String JavaDoc get(String JavaDoc key) {
55         if (++queryCount >= queryOverflow) {
56             cleanup();
57         }
58         Entry entry = entryFor(key);
59         if (entry != null) {
60             return entry.val();
61         }
62         return null;
63     }
64
65     synchronized void put(String JavaDoc key, String JavaDoc val) {
66         if (++queryCount >= queryOverflow) {
67             cleanup();
68         }
69         Entry entry = entryFor(key);
70         if (entry != null) {
71             entry.setTimestamp(System.currentTimeMillis());
72             entry.setVal(val);
73         } else {
74             map.put(key, new Entry(System.currentTimeMillis(), val));
75         }
76     }
77
78     synchronized void clear() {
79         map.clear();
80     }
81
82     private Entry entryFor(String JavaDoc key) {
83         Entry entry = (Entry) map.get(key);
84         if (entry != null) {
85             long delta = System.currentTimeMillis() - entry.timestamp();
86             if (delta < 0 || delta >= millisUntilExpiration) {
87                 map.remove(key);
88                 entry = null;
89             }
90         }
91         return entry;
92     }
93
94     private void cleanup() {
95         Set JavaDoc keySet = map.keySet();
96         // Avoid ConcurrentModificationExceptions
97
String JavaDoc[] keys = new String JavaDoc[keySet.size()];
98         int i = 0;
99         for (Iterator JavaDoc iter = keySet.iterator(); iter.hasNext(); ) {
100             String JavaDoc key = (String JavaDoc) iter.next();
101             keys[i++] = key;
102         }
103         for (int j = 0; j < keys.length; j++) {
104             entryFor(keys[j]);
105         }
106         queryCount = 0;
107     }
108 }
109
Popular Tags