KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > knowgate > dataobjs > DBSubsetCache


1 /*
2   Copyright (C) 2003 Know Gate S.L. All rights reserved.
3                       C/O�a, 107 1�2 28050 Madrid (Spain)
4
5   Redistribution and use in source and binary forms, with or without
6   modification, are permitted provided that the following conditions
7   are met:
8
9   1. Redistributions of source code must retain the above copyright
10      notice, this list of conditions and the following disclaimer.
11
12   2. The end-user documentation included with the redistribution,
13      if any, must include the following acknowledgment:
14      "This product includes software parts from hipergate
15      (http://www.hipergate.org/)."
16      Alternately, this acknowledgment may appear in the software itself,
17      if and wherever such third-party acknowledgments normally appear.
18
19   3. The name hipergate must not be used to endorse or promote products
20      derived from this software without prior written permission.
21      Products derived from this software may not be called hipergate,
22      nor may hipergate appear in their name, without prior written
23      permission.
24
25   This library is distributed in the hope that it will be useful,
26   but WITHOUT ANY WARRANTY; without even the implied warranty of
27   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
28
29   You should have received a copy of hipergate License with this code;
30   if not, visit http://www.hipergate.org or mail to info@hipergate.org
31 */

32
33 package com.knowgate.dataobjs;
34
35 import java.lang.System JavaDoc;
36 import java.util.TreeMap JavaDoc;
37 import java.util.Iterator JavaDoc;
38 import java.lang.Thread JavaDoc;
39
40 final class DBSubsetCacheReaper extends Thread JavaDoc {
41
42     private DBSubsetCache oDBCache;
43
44     DBSubsetCacheReaper(DBSubsetCache objDBCache) {
45         oDBCache = objDBCache;
46     }
47
48     private void reapEntries() {
49       // Position of last recently used entry to discard
50
int iLRU = oDBCache.iTopIndex-oDBCache.iUsed;
51       // Count of entries to discard (20% of cache capacity)
52
int iDiscardCount = (oDBCache.capacity()*2)/10;
53       int iComma; // Delimiter position "Table,Key"
54
String JavaDoc sEntry; // Full entry descriptor "Table,Key"
55
String JavaDoc sTable; // Entry related table
56
String JavaDoc sKey; // Entry key
57

58       // Discard bottom 20% entries
59
for (int i=iLRU; i<iLRU+iDiscardCount; i++) {
60         sEntry = oDBCache.getKey(iLRU);
61         if (null!=sEntry) {
62           iComma = sEntry.indexOf(',');
63           sTable = sEntry.substring(0, iComma);
64           sKey = sEntry.substring(iComma+1);
65           oDBCache.expire(sKey);
66         } // fi(LRUList[])
67
} // next (i)
68

69       oDBCache.iUsed-=iDiscardCount; // Decrement used slots count
70
} // reapEntries()
71

72     public void run() {
73       reapEntries();
74     }
75 } // DBSubsetCache
76

77 // ============================================================
78

79   /**
80    *
81    * <p>Local Cache for DBSubset Objects</p>
82    * @version 3.0
83    */

84
85 public final class DBSubsetCache {
86
87       /**
88        * <p>Default constructor</p>
89        * Cache capacity is set to 100
90        */

91       public DBSubsetCache() {
92       iUsed = 0;
93       iTopIndex = 0;
94       iCacheCapacity = 100;
95       LRUList = new String JavaDoc[iCacheCapacity];
96       for (int s=0; s<iCacheCapacity; s++) LRUList[s] = null;
97       oCache = new TreeMap JavaDoc();
98     }
99
100     /**
101      *
102      * @param iCapacity Maximum number of entries that cache can hold
103      */

104
105   public DBSubsetCache(int iCapacity) {
106     iUsed = 0;
107     iTopIndex = 0;
108     iCacheCapacity = iCapacity;
109     LRUList = new String JavaDoc[iCacheCapacity];
110     for (int s=0; s<iCacheCapacity; s++) LRUList[s] = null;
111     oCache = new TreeMap JavaDoc();
112   }
113
114   // ----------------------------------------------------------
115

116   /**
117    * Get Maximum number of entries that cache can hold
118    */

119
120   public int capacity() {
121     return iCacheCapacity;
122   }
123
124   // ----------------------------------------------------------
125

126   /**
127    * Add new entry to cache
128    * @param sTableName Associated table (optional)
129    * @param sKey Unique key for cache entry
130    * @param oDBSS Stored DBSubset
131    */

132   public synchronized void put(String JavaDoc sTableName, String JavaDoc sKey, DBSubset oDBSS) {
133     int iIndex = iTopIndex%iCacheCapacity; iTopIndex++; iUsed++;
134     DBCacheEntry oEntry = new DBCacheEntry(oDBSS, sTableName, iIndex);
135     DBSubsetCacheReaper oReaper;
136
137     if (null==sTableName) sTableName="none";
138
139     oCache.put(sKey, oEntry);
140     LRUList[iIndex] = sTableName + "," + sKey;
141
142     if (iUsed>=iCacheCapacity-1) {
143       oReaper = new DBSubsetCacheReaper(this);
144       oReaper.run();
145     } // fi (iUsed>=iCacheCapacity-1)
146
} // put()
147

148   // ----------------------------------------------------------
149

150   /**
151    * Remove a cache entry
152    * @param sKey Unique key for cache entry
153    * @return <b>true</b> if cache already contained an entry with given key, <b>false</b> if no entry was removed from cache.
154    */

155
156   public synchronized boolean expire(String JavaDoc sKey) {
157     Object JavaDoc objEntry = oCache.get(sKey);
158
159     if (null!=objEntry) {
160       setKey(null, ((DBCacheEntry) objEntry).iIndex);
161       oCache.remove(sKey);
162     }
163     return null!=objEntry ? true : false;
164   } // remove()
165

166   // ----------------------------------------------------------
167

168   /**
169    * Replace a cache entry
170    * @param sTableName Associated table (optional)
171    * @param sKey Unique key for cache entry
172    * @param oDBSS New DBSubset to be stored
173    */

174
175   public void replace(String JavaDoc sTableName, String JavaDoc sKey, DBSubset oDBSS) {
176
177     expire(sKey);
178     put(sTableName, sKey, oDBSS);
179   } // replace()
180

181   // ----------------------------------------------------------
182

183   /**
184    * Clear cache
185    */

186
187   public synchronized void clear() {
188     oCache.clear();
189     for (int s=0; s<iCacheCapacity; s++) LRUList[s] = null;
190     iTopIndex=0;
191     iUsed=0;
192   } // clear()
193

194   // ----------------------------------------------------------
195

196   /**
197    * Remove all entries from cache that are registers from a given table
198    * @param sTable Table Name
199    */

200
201   public synchronized void clear(String JavaDoc sTable) {
202     Iterator JavaDoc oIter = oCache.keySet().iterator();
203     String JavaDoc sKey;
204     DBCacheEntry oEntry;
205
206     if (sTable==null) sTable = "none";
207
208     while (oIter.hasNext()) {
209       sKey = (String JavaDoc) oIter.next();
210       oEntry = (DBCacheEntry) oCache.get(sKey);
211       if (sTable.equals(oEntry.sTable))
212         expire(sKey);
213     } // wend
214
} // clear()
215

216   // ----------------------------------------------------------
217

218   /**
219    * Get DBSubset from cache
220    * @param sKey Unique key for cache entry
221    * @return DBSubset reference or <b>null</if no DBSubset with such key was found
222    */

223
224   public DBSubset get(String JavaDoc sKey) {
225     Object JavaDoc oObj = oCache.get(sKey);
226     DBCacheEntry oEntry;
227
228     if (oObj!=null) {
229       oEntry = (DBCacheEntry) oObj;
230       oEntry.iTimesUsed++;
231       oEntry.lastUsed = System.currentTimeMillis();
232       return oEntry.oDBSubset;
233     }
234     else
235       return null;
236   } // get()
237

238   // ----------------------------------------------------------
239

240   /**
241    * Get DBCacheEntry from cache
242    * @param sKey Unique key for cache entry
243    * @return DBCacheEntry reference or <b>null</if no DBCacheEntry with such key was found
244    */

245
246   public DBCacheEntry getEntry(String JavaDoc sKey) {
247     Object JavaDoc oObj = oCache.get(sKey);
248     DBCacheEntry oEntry;
249
250     if (oObj!=null) {
251       oEntry = (DBCacheEntry) oObj;
252       oEntry.iTimesUsed++;
253       oEntry.lastUsed = System.currentTimeMillis();
254       return oEntry;
255     }
256     else
257       return null;
258   } // getEntry()
259

260   // ----------------------------------------------------------
261

262   public String JavaDoc getKey(int iEntryIndex) {
263     return LRUList[iEntryIndex % iCacheCapacity];
264   }
265
266   // ----------------------------------------------------------
267

268   public void setKey(String JavaDoc sKey, int iEntryIndex) {
269     LRUList[iEntryIndex % iCacheCapacity] = sKey;
270   }
271
272   // ----------------------------------------------------------
273

274   public class DBCacheEntry {
275     public long lastModified;
276     public long lastUsed;
277     public int iTimesUsed;
278     public int iIndex;
279     public String JavaDoc sTable;
280     public DBSubset oDBSubset;
281
282     DBCacheEntry (DBSubset oDBSS, String JavaDoc sTbl, int iIdx) {
283       sTable = sTbl;
284       iIndex = iIdx;
285       iTimesUsed = 0;
286       lastUsed = lastModified = System.currentTimeMillis();
287       oDBSubset = oDBSS;
288     }
289   } // DBCacheEntry
290

291   private int iCacheCapacity; // N�mero m�ximo de entradas en el cache
292
private String JavaDoc LRUList[]; // Slots usados por el algoritmo de limpieza Least Recently Used
293
private TreeMap JavaDoc oCache; // B-Tree con las entradas del cache
294

295   public int iTopIndex; // M�ximo �ndice en el cache (siempre de accede m�dulo la capacidad)
296
public int iUsed; // Contador de entradas actualmente en uso
297
} // DBSubsetCache
298
Free Books   Free Magazines  
Popular Tags