KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > Yasna > forum > database > DbCacheManager


1 /**
2  * Copyright (C) 2001 Yasna.com. All rights reserved.
3  *
4  * ===================================================================
5  * The Apache Software License, Version 1.1
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in
16  * the documentation and/or other materials provided with the
17  * distribution.
18  *
19  * 3. The end-user documentation included with the redistribution,
20  * if any, must include the following acknowledgment:
21  * "This product includes software developed by
22  * Yasna.com (http://www.yasna.com)."
23  * Alternately, this acknowledgment may appear in the software itself,
24  * if and wherever such third-party acknowledgments normally appear.
25  *
26  * 4. The names "Yazd" and "Yasna.com" must not be used to
27  * endorse or promote products derived from this software without
28  * prior written permission. For written permission, please
29  * contact yazd@yasna.com.
30  *
31  * 5. Products derived from this software may not be called "Yazd",
32  * nor may "Yazd" appear in their name, without prior written
33  * permission of Yasna.com.
34  *
35  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38  * DISCLAIMED. IN NO EVENT SHALL YASNA.COM OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46  * SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of Yasna.com. For more information
51  * on Yasna.com, please see <http://www.yasna.com>.
52  */

53
54 /**
55  * Copyright (C) 2000 CoolServlets.com. All rights reserved.
56  *
57  * ===================================================================
58  * The Apache Software License, Version 1.1
59  *
60  * Redistribution and use in source and binary forms, with or without
61  * modification, are permitted provided that the following conditions
62  * are met:
63  *
64  * 1. Redistributions of source code must retain the above copyright
65  * notice, this list of conditions and the following disclaimer.
66  *
67  * 2. Redistributions in binary form must reproduce the above copyright
68  * notice, this list of conditions and the following disclaimer in
69  * the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3. The end-user documentation included with the redistribution,
73  * if any, must include the following acknowledgment:
74  * "This product includes software developed by
75  * CoolServlets.com (http://www.coolservlets.com)."
76  * Alternately, this acknowledgment may appear in the software itself,
77  * if and wherever such third-party acknowledgments normally appear.
78  *
79  * 4. The names "Jive" and "CoolServlets.com" must not be used to
80  * endorse or promote products derived from this software without
81  * prior written permission. For written permission, please
82  * contact webmaster@coolservlets.com.
83  *
84  * 5. Products derived from this software may not be called "Jive",
85  * nor may "Jive" appear in their name, without prior written
86  * permission of CoolServlets.com.
87  *
88  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
89  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
90  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91  * DISCLAIMED. IN NO EVENT SHALL COOLSERVLETS.COM OR
92  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
93  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
94  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
95  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
97  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
98  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
99  * SUCH DAMAGE.
100  * ====================================================================
101  *
102  * This software consists of voluntary contributions made by many
103  * individuals on behalf of CoolServlets.com. For more information
104  * on CoolServlets.com, please see <http://www.coolservlets.com>.
105  */

106
107 package com.Yasna.forum.database;
108
109 import com.Yasna.util.*;
110
111 /**
112  * Central cache management of all caches used by Yazd.
113  */

114 public class DbCacheManager {
115
116     public static int USER_CACHE = 0;
117     public static int USER_ID_CACHE = 1;
118     public static int GROUP_CACHE = 2;
119     public static int GROUP_ID_CACHE = 3;
120     public static int FORUM_CACHE = 4;
121     public static int FORUM_ID_CACHE = 5;
122     public static int THREAD_CACHE = 6;
123     public static int MESSAGE_CACHE = 7;
124     public static int USER_PERMS_CACHE = 8;
125     public static int CATEGORY_CACHE = 9;
126     public static int CATEGORY_ID_CACHE = 10;
127     public static int FORUM_GROUP_CACHE = 11;
128     public static int THREAD_TYPE_ID_CACHE = 12;
129
130     protected Cache[] caches;
131
132     private boolean cacheEnabled = true;
133
134     public DbCacheManager() {
135         int MINUTE = 1000*60;
136         int HOUR = MINUTE*60;
137
138         caches = new Cache[13];
139
140         //Initialize all cache structures
141
caches[USER_CACHE] = new Cache(256*1024, 10*MINUTE);
142         caches[USER_ID_CACHE] = new Cache(128*1024, 10*MINUTE);
143         caches[GROUP_CACHE] = new Cache(128*1024, 1*HOUR);
144         caches[GROUP_ID_CACHE] = new Cache(128*1024, 1*HOUR);
145         caches[FORUM_CACHE] = new Cache(128*1024, 20*MINUTE);
146         caches[FORUM_ID_CACHE] = new Cache(128*1024, 20*MINUTE);
147         caches[THREAD_CACHE] = new Cache(128*1024, 20*MINUTE);
148         caches[MESSAGE_CACHE] = new Cache(512*1024, 1*HOUR);
149         caches[CATEGORY_CACHE] = new Cache(128*1024, 1*HOUR);
150         caches[CATEGORY_ID_CACHE] = new Cache(128*1024, 1*HOUR);
151         caches[FORUM_GROUP_CACHE] = new Cache(128*1024, 1*HOUR);
152         //The user permissions cache is a special one. It's actually a Cache
153
//of Cache objects. Each of the cache objects in the main cache
154
//corresponds to a particular forum, and is used to cache the
155
//permissions that a user has for a forum. In order to handle this
156
//requirement, we use a special subclass of Cache.
157
caches[USER_PERMS_CACHE] = new UserPermsCache(256*1024, 2*HOUR);
158         caches[THREAD_TYPE_ID_CACHE] = new Cache(128*1024, 1*HOUR);
159     }
160
161     public Cache getCache(int cacheType) {
162         return caches[cacheType];
163     }
164
165     public void add(int cacheType, Object JavaDoc key, Cacheable object) {
166         caches[cacheType].add(key, object);
167     }
168
169     public Cacheable get(int cacheType, Object JavaDoc key) {
170         if (!cacheEnabled) {
171             return null;
172         }
173         return caches[cacheType].get(key);
174     }
175
176     public void remove(int cacheType, Object JavaDoc key) {
177         caches[cacheType].remove(key);
178         //when cache becomes distributed, we'd send out an expire message
179
//here to all other yazd servers.
180
}
181
182     public void removeUserPerm(Object JavaDoc userID) {
183         Object JavaDoc [] values = caches[USER_PERMS_CACHE].values().toArray();
184         for (int i=0; i<values.length; i++) {
185             Cache cache = (Cache)((CacheObject)values[i]).object;
186             cache.remove(userID);
187         }
188         //when cache becomes distributed, we'd send out an expire message
189
//here to all other yazd servers.
190
}
191
192     public void removeUserPerm(Object JavaDoc userID, Object JavaDoc forumID) {
193         Cache cache = (Cache)caches[USER_PERMS_CACHE].get(forumID);
194         if (cache != null) {
195             cache.remove(userID);
196         }
197         //when cache becomes distributed, we'd send out an expire message
198
//here to all other yazd servers.
199
}
200
201     public void clear(int cacheType) {
202         caches[cacheType].clear();
203         //when cache becomes distributed, we'd send out an expire message
204
//here to all other yazd servers.
205
}
206
207     public boolean isCacheEnabled() {
208         return cacheEnabled;
209     }
210
211     public void setCacheEnabled(boolean cacheEnabled) {
212         this.cacheEnabled = cacheEnabled;
213     }
214 }
215
216 /**
217  * Special purpose Cache to hold all of the different user permission cache
218  * objects. The main feature is that new caches are automatically created so
219  * that calling get() never returns null.
220  */

221 class UserPermsCache extends Cache {
222
223     public UserPermsCache(int size, long expireTime) {
224         super(size, expireTime);
225     }
226
227     public synchronized Cacheable get(Object JavaDoc key) {
228         Cache subCache = (Cache)super.get(key);
229         if (subCache == null) {
230             //cache has expired, or is not there, so put a new one in there.
231
//Cache objects only need to last as long as a user's session
232
//does. Half an hour is a reasonable amount of time for this.
233
subCache = new Cache(2*1024, 30*1000*60);
234             add(key, subCache);
235         }
236         return subCache;
237     }
238
239     public synchronized void remove(Object JavaDoc key) {
240         CacheObject cacheObject = (CacheObject)cachedObjectsHash.get(key);
241         //If the object is not in cache, stop trying to remove it.
242
if (cacheObject == null) {
243             return;
244         }
245         //remove from the hash map
246
cachedObjectsHash.remove(key);
247         //remove from the cache order list
248
cacheObject.lastAccessedListNode.remove();
249         cacheObject.ageListNode.remove();
250         //remove references to linked list nodes
251
cacheObject.ageListNode = null;
252         cacheObject.lastAccessedListNode = null;
253         //removed the object, so subtract its size from the total.
254
size -= cacheObject.size;
255
256         //Finally, clear the sub-cache to make sure memory is released.
257
((Cache)cacheObject.object).clear();
258     }
259
260     /**
261      * Returns the current size in bytes of the cache. The base getSize() method
262      * does not work correctly because the sub-caches are empty when we first
263      * add them rather than the normal cache assumption that objects are near
264      * the size that they will always be.
265      *
266      * @return the size of the cache in bytes.
267      */

268     public int getSize() {
269         int size = 0;
270         Object JavaDoc [] values = values().toArray();
271         for (int i=0; i<values.length; i++) {
272             Cache cache = (Cache)values[i];
273             size += cache.getSize();
274         }
275         return size;
276     }
277 }
278
279
Popular Tags