KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > broker > cache > ObjectCacheSoftImpl


1 package org.apache.ojb.broker.cache;
2
3 /* Copyright 2004-2005 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 import java.lang.ref.ReferenceQueue JavaDoc;
19 import java.lang.ref.SoftReference JavaDoc;
20 import java.util.HashMap JavaDoc;
21 import java.util.Properties JavaDoc;
22
23 import org.apache.commons.collections.LRUMap;
24 import org.apache.ojb.broker.Identity;
25 import org.apache.ojb.broker.PersistenceBroker;
26 import org.apache.ojb.broker.util.configuration.Configurable;
27 import org.apache.ojb.broker.util.configuration.Configuration;
28 import org.apache.ojb.broker.util.configuration.ConfigurationException;
29 import org.apache.ojb.broker.util.configuration.impl.OjbConfigurator;
30
31 /**
32  * A global {@link ObjectCache} implementation.
33  *
34  * @author matthew.baird
35  * @version $Id: ObjectCacheSoftImpl.java,v 1.7.2.2 2005/12/21 22:24:15 tomdz Exp $
36  */

37 public class ObjectCacheSoftImpl implements ObjectCache, Configurable
38 {
39     /**
40      * The static the cache map
41      */

42     private static SoftHashMap cache = null;
43
44     /**
45      * The size of the cache
46      */

47     private static int size = 10000;
48
49     /**
50      * Constructor called by ojb
51      *
52      * @param broker ignored parameter
53      * @param properties ignored parameter
54      */

55     public ObjectCacheSoftImpl(PersistenceBroker broker, Properties JavaDoc properties)
56     {
57         if (cache == null)
58         {
59             OjbConfigurator.getInstance().configure(this);
60             cache = new SoftHashMap(size);
61         }
62     }
63
64     /**
65      * @see org.apache.ojb.broker.util.configuration.Configurable#configure(org.apache.ojb.broker.util.configuration.Configuration)
66      */

67     public void configure(Configuration configuration) throws ConfigurationException
68     {
69         size = configuration.getInteger("ObjectCacheSoftImpl", size);
70     }
71
72     /**
73      * @see org.apache.ojb.broker.cache.ObjectCache#cache(org.apache.ojb.broker.Identity, java.lang.Object)
74      */

75     public void cache(Identity oid, Object JavaDoc obj)
76     {
77         synchronized(cache)
78         {
79             cache.put(oid, obj);
80         }
81     }
82
83     public boolean cacheIfNew(Identity oid, Object JavaDoc obj)
84     {
85         synchronized(cache)
86         {
87             if(cache.get(oid) == null)
88             {
89                 cache.put(oid, obj);
90                 return true;
91             }
92             return false;
93         }
94     }
95
96     /**
97      * @see org.apache.ojb.broker.cache.ObjectCache#lookup(org.apache.ojb.broker.Identity)
98      */

99     public Object JavaDoc lookup(Identity oid)
100     {
101         return cache.get(oid);
102     }
103
104     /**
105      * @see org.apache.ojb.broker.cache.ObjectCache#remove(org.apache.ojb.broker.Identity)
106      */

107     public void remove(Identity oid)
108     {
109         synchronized(cache)
110         {
111             cache.remove(oid);
112         }
113     }
114
115     /**
116      * @see org.apache.ojb.broker.cache.ObjectCache#clear()
117      */

118     public void clear()
119     {
120         cache.clear();
121     }
122
123     /**
124      * Kind of map using SoftReference to store values
125      */

126     public static final class SoftHashMap
127     {
128         /**
129          * The internal HashMap that will hold the SoftReference.
130          */

131         private HashMap JavaDoc hash;
132         /**
133          * The FIFO list of hard references, order of last access.
134          */

135         private LRUMap hardCacheMap;
136         /**
137          * Reference queue for cleared SoftReference objects.
138          */

139         private ReferenceQueue JavaDoc queue;
140
141         /**
142          * Construct a new hash map with the specified size
143          *
144          * @param hardSize the maximum capacity of this map
145          */

146         public SoftHashMap(final int hardSize)
147         {
148             hash = new HashMap JavaDoc();
149             hardCacheMap = new LRUMap(hardSize);
150             queue = new ReferenceQueue JavaDoc();
151         }
152
153         /**
154          * Put the key, value pair into the HashMap using a SoftValue object
155          *
156          * @param key the key
157          * @param value the value
158          * @return the old value
159          */

160         public Object JavaDoc put(Object JavaDoc key, Object JavaDoc value)
161         {
162             //check null since hashtable doesn't support null key or null value
163
if (key == null || value == null)
164             {
165                 return null;
166             }
167             processQueue(); // throw out garbage collected values first
168
hardCacheMap.put(key, value);
169             return hash.put(key, new SoftValue(value, key, queue));
170         }
171
172         /**
173          * Retrieve the value associated to a given key
174          *
175          * @param key the key
176          * @return the value associated to this key
177          */

178         public Object JavaDoc get(Object JavaDoc key)
179         {
180             // Check null since Hashtable doesn't support null key or null value
181
if (key == null)
182             {
183                 return null;
184             }
185             Object JavaDoc result = null;
186             // We get the SoftReference represented by that key
187
SoftReference JavaDoc softRef = (SoftReference JavaDoc) hash.get(key);
188             if (softRef != null)
189             {
190                 result = softRef.get();
191                 if (result == null)
192                 {
193                     // If the value has been garbage collected, remove the
194
// entry from the HashMap.
195
hash.remove(key);
196                 }
197                 else
198                 {
199                     if (!hardCacheMap.containsKey(key))
200                     {
201                         hardCacheMap.put(key, result);
202                     }
203                     else
204                     {
205                         hardCacheMap.get(key);
206                     }
207                 }
208             }
209             return result;
210         }
211
212         /**
213          * Remove the entry for this key
214          *
215          * @param key the key
216          * @return the old value
217          */

218         public Object JavaDoc remove(Object JavaDoc key)
219         {
220             processQueue(); // throw out garbage collected values first
221
Object JavaDoc retval = null;
222             Object JavaDoc value = hash.remove(key);
223             if (value != null)
224             {
225                 if (value instanceof SoftValue)
226                 {
227                     retval = ((SoftValue) value).get();
228                 }
229             }
230             return retval;
231         }
232
233         /**
234          * Clear the map
235          */

236         public void clear()
237         {
238             processQueue();
239             hash.clear();
240             hardCacheMap.clear();
241         }
242
243         /**
244          * Class derived from SoftReference, used to
245          * store the key of the map.
246          */

247         private class SoftValue extends SoftReference JavaDoc
248         {
249             /**
250              * the key
251              */

252             private final Object JavaDoc key; // always make data member final
253

254             /**
255              * Create a SoftValue given the object, key and queue
256              *
257              * @param k the object
258              * @param key the key
259              * @param q the reference queue
260              */

261             private SoftValue(final Object JavaDoc k, final Object JavaDoc key, final ReferenceQueue JavaDoc q)
262             {
263                 super(k, q);
264                 this.key = key;
265             }
266         }
267
268         /**
269          * Removes keys and objects that have been garbaged
270          */

271         private void processQueue()
272         {
273             SoftValue sv;
274             while ((sv = (SoftValue) queue.poll()) != null)
275             {
276                 hash.remove(sv.key); // we can access private data!
277
}
278         }
279
280     }
281 }
282
Popular Tags