KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jalisto > se > impl > cache > WeakReferenceCache


1 /*
2  * Jalisto - JAva LIght STOrage
3  * Copyright (C) 2000-2005 Xcalia http://www.xcalia.com
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
18  *
19  * Xcalia
20  * 71, rue Desnouettes
21  * 75014 Paris - France
22  * http://www.xcalia.com
23  */

24 package org.objectweb.jalisto.se.impl.cache;
25
26 import org.objectweb.jalisto.se.api.cache.JalistoCache;
27 import org.objectweb.jalisto.se.impl.trace.Trace;
28
29 import java.io.PrintStream JavaDoc;
30 import java.lang.ref.ReferenceQueue JavaDoc;
31 import java.util.*;
32
33 public class WeakReferenceCache implements JalistoCache {
34
35     public WeakReferenceCache() {
36         table = new HashMap();
37         queue = new ReferenceQueue JavaDoc();
38     }
39
40     public void init(int size, String JavaDoc name, double clearPourcent) {
41         this.maxSize = size;
42         this.name = name;
43         this.cacheClearPourcent = clearPourcent;
44     }
45
46     public void setTrace(Trace trace) {
47         this.trace = trace;
48     }
49
50     public boolean isEmpty() {
51         return table.isEmpty();
52     }
53
54     public void clear() {
55         trace.println(Trace.CACHE, "{0} : clear()", name);
56         table.clear();
57         firstCell = null;
58         lastCell = null;
59     }
60
61     public boolean containsKey(Object JavaDoc key) {
62         return table.containsKey(key);
63     }
64
65     public boolean containsValue(Object JavaDoc value) {
66         throw new UnsupportedOperationException JavaDoc("not used in this implementation");
67     }
68
69     public Set entrySet() {
70         throw new UnsupportedOperationException JavaDoc("not used in this implementation");
71     }
72
73     public Object JavaDoc get(Object JavaDoc key) {
74         trace.println(Trace.CACHE, "{0} : get({1})", name, key);
75         Object JavaDoc result = table.get(key);
76         if (result != null) {
77             return ((WeakCacheCell) result).get();
78         }
79         return null;
80     }
81
82     public Set keySet() {
83         return table.keySet();
84     }
85
86     public Object JavaDoc put(Object JavaDoc key, Object JavaDoc value) {
87         trace.println(Trace.CACHE, "{0} : put({1}, {2})", name, key, value);
88         remove(key);
89         if (table.size() >= maxSize) {
90             makeSpace();
91         }
92         WeakCacheCell availableCacheCell = WeakCacheCell.newInstance(key, value, queue);
93         if (lastCell != null) {
94             lastCell.setNextCell(availableCacheCell);
95             availableCacheCell.setPrecedingCell(lastCell);
96             lastCell = availableCacheCell;
97         } else {
98             lastCell = availableCacheCell;
99             firstCell = availableCacheCell;
100         }
101         table.put(key, availableCacheCell);
102         return null;
103     }
104
105     public void putAll(Map map) {
106         Iterator keys = map.keySet().iterator();
107         while (keys.hasNext()) {
108             Object JavaDoc key = keys.next();
109             put(key, map.get(key));
110         }
111     }
112
113     public Object JavaDoc remove(Object JavaDoc key) {
114         trace.println(Trace.CACHE, "{0} : remove({1})", name, key);
115         if (containsKey(key)) {
116             synchronized (table) {
117                 WeakCacheCell cell = (WeakCacheCell) table.remove(key);
118                 if (cell.equals(firstCell)) {
119                     firstCell = cell.getNextCell();
120                 }
121                 if (cell.equals(lastCell)) {
122                     lastCell = cell.getPrecedingCell();
123                 }
124                 cell.delink();
125                 if (table.isEmpty()) {
126                     lastCell = null;
127                     firstCell = null;
128                 }
129                 return cell.get();
130             }
131         }
132         return null;
133     }
134
135     public int size() {
136         return table.size();
137     }
138
139     public synchronized void setMaxSize(int size) {
140         maxSize = size;
141         WeakCacheCell myFirst = firstCell;
142         synchronized (table) {
143             while (table.size() > maxSize) {
144                 WeakCacheCell mySecond = myFirst.getNextCell();
145                 table.remove(myFirst.getId());
146                 myFirst.delink();
147                 myFirst = mySecond;
148             }
149             if (table.isEmpty()) {
150                 lastCell = null;
151                 firstCell = null;
152             }
153             firstCell = myFirst;
154         }
155     }
156
157     public int getMaxSize() {
158         return maxSize;
159     }
160
161     public Collection values() {
162         throw new UnsupportedOperationException JavaDoc("not used in this implementation");
163     }
164
165
166     private void makeSpace() {
167         int nbrToRemove = (new Double JavaDoc(maxSize * cacheClearPourcent)).intValue() + 1;
168         trace.println(Trace.CACHE, "{0} : makeSpace() : clear {1} objects", name, new Integer JavaDoc(nbrToRemove));
169
170
171         int cleaned = cleanQueue();
172         if (cleaned < nbrToRemove) {
173             nbrToRemove = nbrToRemove - cleaned;
174             WeakCacheCell myFirst = firstCell;
175             synchronized (table) {
176                 for (int i = 0; i < nbrToRemove; i++) {
177                     WeakCacheCell mySecond = myFirst.getNextCell();
178                     if (mySecond == null) {
179                         throw new NullPointerException JavaDoc();
180                     }
181                     table.remove(myFirst.getId());
182                     myFirst.delink();
183                     myFirst = mySecond;
184                 }
185             }
186             firstCell = myFirst;
187         }
188     }
189
190     private int cleanQueue() {
191         trace.println(Trace.CACHE, "{0} : cleanQueue()", name);
192         WeakCacheCell ref = (WeakCacheCell) queue.poll();
193         int initSize = table.size();
194         if (initSize == 0) {
195             return 0;
196         }
197         if (ref != null) {
198             int i = 0;
199             synchronized (table) {
200                 while (ref != null) {
201                     table.remove(ref.getId());
202                     if (firstCell == ref) {
203                         firstCell = ref.getNextCell();
204                     }
205                     if (lastCell == ref) {
206                         lastCell = ref.getPrecedingCell();
207                     }
208                     ref.delink();
209                     i++;
210                     ref = (WeakCacheCell) queue.poll();
211                 }
212             }
213             return i;
214         }
215         return 0;
216     }
217
218     public void print(PrintStream JavaDoc out) {
219         out.println(table.toString());
220     }
221
222     public String JavaDoc toString() {
223         return table.toString();
224     }
225
226
227     private WeakCacheCell firstCell;
228     private WeakCacheCell lastCell;
229     private HashMap table;
230     private ReferenceQueue JavaDoc queue;
231     private String JavaDoc name;
232     private double cacheClearPourcent;
233     private int maxSize;
234     private Trace trace;
235 }
236
Popular Tags