KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > appserv > util > cache > BoundedMultiLruCache


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 /**
25  * Copyright 2000-2001 by iPlanet/Sun Microsystems, Inc.,
26  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
27  * All rights reserved.
28  */

29  
30 package com.sun.appserv.util.cache;
31
32 import java.text.MessageFormat JavaDoc;
33
34 import java.util.Properties JavaDoc;
35 import java.util.Map JavaDoc;
36 import java.util.ResourceBundle JavaDoc;
37
38 /**
39  * MultiLruCache -- in-memory bounded LRU cache with multiple LRU lists
40  * Underlying Hashtable is made into logical segments, with each segment
41  * having its own LRU list.
42  */

43 public class BoundedMultiLruCache extends MultiLruCache {
44
45     // upper bound on the cache size
46
protected long maxSize = Constants.DEFAULT_MAX_CACHE_SIZE;
47     protected long currentSize;
48     private Object JavaDoc currentSizeLk = new Object JavaDoc();
49
50     /**
51      * initialize the LRU cache
52      * @param maxCapacity maximum number of entries this cache may hold
53      */

54     public void init(int maxCapacity, Properties JavaDoc props) throws Exception JavaDoc {
55         super.init(maxCapacity, props);
56         currentSize = 0;
57
58         if (props != null) {
59             String JavaDoc strMaxSize = props.getProperty("MaxSize");
60             int multiplier = 1;
61             long size = -1;
62
63             String JavaDoc prop = strMaxSize;
64             if (prop != null) {
65                 int index;
66
67                 // upper case the string
68
prop = prop.toUpperCase();
69
70                 // look for 200KB or 80Kb or 1MB or 2Mb like suffixes
71
if ((index = prop.indexOf("KB")) != -1) {
72                     multiplier = Constants.KB;
73                     prop = prop.substring(0, index);
74                 } else if ((index = prop.indexOf("MB")) != -1) {
75                     multiplier = Constants.MB;
76                     prop = prop.substring(0, index);
77                 }
78
79                 try {
80                     size = Long.parseLong(prop.trim());
81                 } catch (NumberFormatException JavaDoc nfe) {}
82             }
83
84             // sanity check and convert
85
if (size > 0)
86                 maxSize = (size * multiplier);
87             else {
88                 String JavaDoc msg = _rb.getString("cache.BoundedMultiLruCache.illegalMaxSize");
89
90                 Object JavaDoc[] params = { strMaxSize };
91                 msg = MessageFormat.format(msg, params);
92
93                 throw new IllegalArgumentException JavaDoc(msg);
94             }
95         }
96     }
97
98     /**
99      * this item is just added to the cache
100      * @param item <code>CacheItem</code> that was created
101      * @return a overflow item; may be null
102      *
103      * Cache bucket is already synchronized by the caller
104      */

105     protected CacheItem itemAdded(CacheItem item) {
106         LruCacheItem overflow = (LruCacheItem) super.itemAdded(item);
107
108         // update the size
109
if (overflow != null) {
110             decrementCurrentSize(overflow.getSize());
111         }
112         incrementCurrentSize(item.getSize());
113
114         return overflow;
115     }
116
117     /**
118      * item value has been refreshed
119      * @param item <code>CacheItem</code> that was refreshed
120      * @param oldSize size of the previous value that was refreshed
121      * Cache bucket is already synchronized by the caller
122      */

123     protected void itemRefreshed(CacheItem item, int oldSize) {
124         super.itemRefreshed(item, oldSize);
125
126         /** reduce the cache by the size of the size of the previous value
127          * and increment by the value being refreshed with.
128          */

129         decrementCurrentSize(oldSize);
130         incrementCurrentSize(item.getSize());
131     }
132
133     /**
134      * item value has been removed from the cache
135      * @param item <code>CacheItem</code> that was just removed
136      *
137      * Cache bucket is already synchronized by the caller
138      */

139     protected void itemRemoved(CacheItem item) {
140         super.itemRemoved(item);
141
142         // update the size
143
decrementCurrentSize(item.getSize());
144     }
145
146     /**
147      * has cache reached its threshold
148      * @return true when the cache reached its threshold
149      */

150     protected boolean isThresholdReached() {
151         return (currentSize > maxSize || super.isThresholdReached());
152     }
153
154     /**
155      * synchronized counter updates
156      */

157     protected final void incrementCurrentSize(int size) {
158         synchronized(currentSizeLk) {
159             currentSize += size;
160         }
161     }
162
163     protected final void decrementCurrentSize(int size) {
164         synchronized(currentSizeLk) {
165             currentSize -= size;
166         }
167     }
168
169     /**
170      * get generic stats from subclasses
171      */

172
173     /**
174      * get the desired statistic counter
175      * @param key to corresponding stat
176      * @return an Object corresponding to the stat
177      * See also: Constant.java for the key
178      */

179     public Object JavaDoc getStatByName(String JavaDoc key) {
180         Object JavaDoc stat = super.getStatByName(key);
181
182         if (stat == null && key != null) {
183             if (key.equals(Constants.STAT_BOUNDEDMULTILRUCACHE_CURRENT_SIZE))
184                 stat = new Long JavaDoc(currentSize);
185             else if (key.equals(Constants.STAT_BOUNDEDMULTILRUCACHE_MAX_SIZE)) {
186                 if (maxSize == Constants.DEFAULT_MAX_CACHE_SIZE)
187                     stat = Constants.STAT_DEFAULT;
188                 else
189                     stat = new Long JavaDoc(maxSize);
190             }
191         }
192
193         return stat;
194     }
195
196     public Map JavaDoc getStats() {
197         Map JavaDoc stats = super.getStats();
198
199         // cache size in KB
200
stats.put(Constants.STAT_BOUNDEDMULTILRUCACHE_CURRENT_SIZE,
201                             new Long JavaDoc(currentSize));
202         if (maxSize == Constants.DEFAULT_MAX_CACHE_SIZE) {
203             stats.put(Constants.STAT_BOUNDEDMULTILRUCACHE_MAX_SIZE,
204                                 Constants.STAT_DEFAULT);
205         } else {
206             stats.put(Constants.STAT_BOUNDEDMULTILRUCACHE_MAX_SIZE,
207                                 new Long JavaDoc(maxSize));
208         }
209         return stats;
210     }
211 }
212
Popular Tags