KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jmx > remote > util > CacheMap


1 /*
2  * @(#)CacheMap.java 1.4 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package com.sun.jmx.remote.util;
9
10 import java.lang.ref.SoftReference JavaDoc;
11 import java.util.Iterator JavaDoc;
12 import java.util.LinkedList JavaDoc;
13 import java.util.List JavaDoc;
14 import java.util.WeakHashMap JavaDoc;
15
16 /**
17  * <p>Like WeakHashMap, except that the keys of the <em>n</em> most
18  * recently-accessed entries are kept as {@link SoftReference soft
19  * references}. Accessing an element means creating it, or retrieving
20  * it with {@link #get(Object) get}. Because these entries are kept
21  * with soft references, they will tend to remain even if their keys
22  * are not referenced elsewhere. But if memory is short, they will
23  * be removed.</p>
24  */

25 public class CacheMap extends WeakHashMap JavaDoc {
26     /**
27      * <p>Create a <code>CacheMap</code> that can keep up to
28      * <code>nSoftReferences</code> as soft references.</p>
29      *
30      * @param nSoftReferences Maximum number of keys to keep as soft
31      * references. Access times for {@link #get(Object) get} and
32      * {@link #put(Object, Object) put} have a component that scales
33      * linearly with <code>nSoftReferences</code>, so this value
34      * should not be too great.
35      *
36      * @throws IllegalArgumentException if
37      * <code>nSoftReferences</code> is negative.
38      */

39     public CacheMap(int nSoftReferences) {
40     if (nSoftReferences < 0) {
41         throw new IllegalArgumentException JavaDoc("nSoftReferences = " +
42                            nSoftReferences);
43     }
44     this.nSoftReferences = nSoftReferences;
45     }
46
47     public Object JavaDoc put(Object JavaDoc key, Object JavaDoc value) {
48     cache(key);
49     return super.put(key, value);
50     }
51
52     public Object JavaDoc get(Object JavaDoc key) {
53     cache(key);
54     return super.get(key);
55     }
56
57     /* We don't override remove(Object) or try to do something with
58        the map's iterators to detect removal. So we may keep useless
59        entries in the soft reference list for keys that have since
60        been removed. The assumption is that entries are added to the
61        cache but never removed. But the behaviour is not wrong if
62        they are in fact removed -- the caching is just less
63        performant. */

64
65     private void cache(Object JavaDoc key) {
66     Iterator JavaDoc it = cache.iterator();
67     while (it.hasNext()) {
68             SoftReference JavaDoc sref = (SoftReference JavaDoc) it.next();
69             Object JavaDoc key1 = sref.get();
70         if (key1 == null)
71                 it.remove();
72         else if (key.equals(key1)) {
73         // Move this element to the head of the LRU list
74
it.remove();
75         cache.add(0, sref);
76         return;
77         }
78     }
79
80     int size = cache.size();
81     if (size == nSoftReferences) {
82         if (size == 0)
83         return; // degenerate case, equivalent to WeakHashMap
84
it.remove();
85     }
86
87     cache.add(0, new SoftReference JavaDoc(key));
88     }
89
90     /* List of soft references for the most-recently referenced keys.
91        The list is in most-recently-used order, i.e. the first element
92        is the most-recently referenced key. There are never more than
93        nSoftReferences elements of this list.
94     
95        If we didn't care about J2SE 1.3 compatibility, we could use
96        LinkedHashSet in conjunction with a subclass of SoftReference
97        whose equals and hashCode reflect the referent. */

98     private final LinkedList JavaDoc/*<SoftReference>*/ cache = new LinkedList JavaDoc();
99     private final int nSoftReferences;
100 }
101
Popular Tags