KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > internal > identitymaps > HardCacheWeakIdentityMap


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21 // Copyright (c) 1998, 2005, Oracle. All rights reserved.
22
package oracle.toplink.essentials.internal.identitymaps;
23
24 import java.util.*;
25 import oracle.toplink.essentials.internal.helper.linkedlist.*;
26
27 /**
28  * <p><b>Purpose</b>: A weak cache is identical to the weak identity map, however the weak
29  * can be a performance problem for some types of apps because it can cause too much garbage collection
30  * of objects read causing them to be re-read and re-built (this defeats the purpose of the cache).
31  * The weak cache solves this through also holding a fixed number of objects is memory to improve caching.
32  * This makes used of an exposed node linked list to maintain the objects by storing the link nodes in the cache key.
33  * <p><b>Responsibilities</b>:<ul>
34  * <li> Guarantees identity
35  * <li> Allows garbage collection
36  * <li> Increases performance through maintaining a fixed size cache of MRU objects when memory is available
37  * <li> The default size of the reference cache is half the max size
38  * </ul>
39  * @since TOPLink/Java 1.2
40  */

41 public class HardCacheWeakIdentityMap extends WeakIdentityMap {
42     protected ExposedNodeLinkedList referenceCache;
43
44     public HardCacheWeakIdentityMap(int size) {
45         super(size);
46         this.referenceCache = new ExposedNodeLinkedList();
47     }
48
49     /**
50      * Use a ReferenceCacheKey that also stores the linked list node to manage
51      * the LRU sub-cache of references.
52      */

53     public CacheKey createCacheKey(Vector primaryKey, Object JavaDoc object, Object JavaDoc writeLockValue, long readTime) {
54         return new ReferenceCacheKey(primaryKey, object, writeLockValue, readTime);
55     }
56
57     /**
58      * Return the linked reference cache.
59      */

60     public ExposedNodeLinkedList getReferenceCache() {
61         return referenceCache;
62     }
63
64     /**
65      * Creates a Soft reference if Required
66      * @param object is the domain object to cache.
67      */

68     public Object JavaDoc buildReference(Object JavaDoc object) {
69         return object;
70     }
71
72     /**
73      * Checks if the object is null, or reference's object is null.
74      * @param the object for hard or the reference for soft.
75      */

76     public boolean hasReference(Object JavaDoc reference) {
77         return reference != null;
78     }
79
80     /**
81      * Store the object in the cache with the cache key.
82      * Also store the linked list node in the cache key.
83      */

84     protected void put(CacheKey cacheKey) {
85         ReferenceCacheKey referenceCacheKey = (ReferenceCacheKey)cacheKey;
86         LinkedNode node = getReferenceCache().addFirst(buildReference(referenceCacheKey.getObject()));
87         referenceCacheKey.setReferenceCacheNode(node);
88         super.put(cacheKey);
89     }
90
91     /**
92      * Remove the cache key from the map and the sub-cache list.
93      */

94     public Object JavaDoc remove(CacheKey cacheKey) {
95         if (cacheKey == null) {
96             return null;
97         }
98         ReferenceCacheKey referenceCacheKey = (ReferenceCacheKey)cacheKey;
99         synchronized (this){
100             getReferenceCache().remove(referenceCacheKey.getReferenceCacheNode());
101         }
102         return super.remove(cacheKey);
103     }
104
105     /**
106      * This method will be used to update the max cache size.
107      */

108     public synchronized void updateMaxSize(int maxSize) {
109         setMaxSize(maxSize);
110         // Remove the LRU items if max size exceeded.
111
while (getReferenceCache().size() > getMaxSize()) {
112             getReferenceCache().removeLast();
113         }
114     }
115
116     /**
117      * Inner class to define the specialized weak cache key.
118      * Keeps track of the linked list node to allow quick repositioning.
119      */

120     public class ReferenceCacheKey extends WeakCacheKey {
121         protected LinkedNode referenceNode;
122
123         public ReferenceCacheKey(Vector primaryKey, Object JavaDoc object, Object JavaDoc writeLockValue, long readTime) {
124             super(primaryKey, object, writeLockValue, readTime);
125         }
126
127         public LinkedNode getReferenceCacheNode() {
128             return referenceNode;
129         }
130
131         public void setReferenceCacheNode(LinkedNode referenceNode) {
132             this.referenceNode = referenceNode;
133         }
134
135         public ExposedNodeLinkedList getReferenceCache() {
136             return referenceCache;
137         }
138
139         /**
140          * Notifies that cache key that it has been accessed.
141          * Allows the LRU sub-cache to be maintained,
142          * the cache node must be moved to the front of the list.
143          */

144         public void updateAccess() {
145             // CR#3573797 must be synchronized on the map, not the cache key.
146
synchronized (HardCacheWeakIdentityMap.this) {
147                 // Check if the node's contents is null (was removed),
148
// also the object is null on initial put of acquired cache key,
149
// or ref value may have garbage collected so reset it.
150
if (!hasReference(getReferenceCacheNode().getContents())) {
151                     getReferenceCacheNode().setContents(buildReference(getObject()));
152                 }
153
154                 // This is a fast constant time operations because of the linked list usage.
155
getReferenceCache().moveFirst(getReferenceCacheNode());
156                 // Remove the old LRU items if max size exceeded (if was removed).
157
while (getReferenceCache().size() > getMaxSize()) {
158                     getReferenceCache().removeLast();
159                 }
160             }
161         }
162     }
163 }
164
Popular Tags