KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdi > internal > ValueCache


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdi.internal;
12
13
14 import java.lang.ref.Reference JavaDoc;
15 import java.lang.ref.ReferenceQueue JavaDoc;
16 import java.lang.ref.SoftReference JavaDoc;
17 import java.util.ArrayList JavaDoc;
18 import java.util.Collection JavaDoc;
19 import java.util.Hashtable JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.List JavaDoc;
22 import java.util.Map JavaDoc;
23
24 /**
25  * This class is used to cache values.
26  * It uses soft references to store cached values. Once a value is garbage collected by the VM,
27  * the corresponding entry is removed from the cache on the next invocation of put() or get().
28  *
29  * Note that WeakHashMap can't be used for this purpose because in WeakHashMap
30  * soft references are only used for the keys, and values may not have 'strong' references
31  * to keys otherwise they will never be garbage collected.
32  *
33  */

34 public class ValueCache {
35     /**
36      * Map to store <key, Reference> pairs,
37      * where Reference is a soft reference to an Object.
38      */

39     private Map JavaDoc cacheTable = new Hashtable JavaDoc();
40     /**
41      * Map to store <Reference, key> pairs,
42      * to find the cacheTable-key of a garbage collected Reference.
43      */

44     private Map JavaDoc refTable = new Hashtable JavaDoc();
45     
46     /**
47      * The reference-queue that is registered with the soft references.
48      * The garbage collector will enqueue soft references that are garbage collected.
49      */

50     private ReferenceQueue JavaDoc refQueue = new ReferenceQueue JavaDoc();
51     
52     /**
53      * Clean up all entries from the table for which the values were garbage collected.
54      */

55     private void cleanup() {
56         Reference JavaDoc ref;
57         while ((ref = refQueue.poll()) != null) {
58             Object JavaDoc key = refTable.get(ref);
59             if (key != null)
60                 cacheTable.remove(key);
61             refTable.remove(ref);
62         }
63     }
64
65     /**
66      * Put a new entry in the cache under the given key.
67      */

68     public void put(Object JavaDoc key, Object JavaDoc value) {
69         cleanup();
70         SoftReference JavaDoc ref = new SoftReference JavaDoc(value, refQueue);
71         cacheTable.put(key, ref);
72         refTable.put(ref, key);
73     }
74
75     /**
76      * Get entry from the cache.
77      * @return Returns value that is cached under the given key,
78      * or null of one of the following is true:
79      * - The value has not been cached.
80      * - The value had been cached but is garbage collected.
81      */

82     public Object JavaDoc get(Object JavaDoc key) {
83         cleanup();
84         Object JavaDoc value = null;
85         SoftReference JavaDoc ref = (SoftReference JavaDoc)cacheTable.get(key);
86         if (ref != null) {
87             value = ref.get();
88         }
89         return value;
90     }
91     
92     /**
93      * Returns a Collection view of the values contained in this cache.
94      */

95     public Collection JavaDoc values() {
96         cleanup();
97         List JavaDoc returnValues = new ArrayList JavaDoc();
98         synchronized (cacheTable) {
99             Iterator JavaDoc iter = cacheTable.values().iterator();
100             SoftReference JavaDoc ref;
101             Object JavaDoc value;
102             while (iter.hasNext()) {
103                 ref = (SoftReference JavaDoc)iter.next();
104                 value = ref.get();
105                 if (value != null) {
106                     returnValues.add(value);
107                 }
108             }
109         }
110         return returnValues;
111     }
112     
113     /**
114      * Returns a Collection view of the values contained in this cache that have the same
115      * runtime class as the given Class.
116      */

117     public Collection JavaDoc valuesWithType(Class JavaDoc type) {
118         cleanup();
119         List JavaDoc returnValues = new ArrayList JavaDoc();
120         synchronized (cacheTable) {
121             Iterator JavaDoc iter = cacheTable.values().iterator();
122             SoftReference JavaDoc ref;
123             Object JavaDoc value;
124             while (iter.hasNext()) {
125                 ref = (SoftReference JavaDoc)iter.next();
126                 value = ref.get();
127                 if (value != null && value.getClass().equals(type)) {
128                     returnValues.add(value);
129                 }
130             }
131         }
132         return returnValues;
133     }
134
135     /**
136      * Removes the key and its corresponding value from this cache.
137      * @return Returns The value to which the key had been mapped in this hashtable,
138      * or null if the key did not have a mapping.
139      */

140     public Object JavaDoc remove(Object JavaDoc key) {
141         cleanup();
142         Object JavaDoc value = null;
143         SoftReference JavaDoc ref = (SoftReference JavaDoc)cacheTable.get(key);
144         if (ref != null) {
145             value = ref.get();
146             refTable.remove(ref);
147         }
148         cacheTable.remove(key);
149         return value;
150     }
151 }
152
Popular Tags