KickJava   Java API By Example, From Geeks To Geeks.

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


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, 2006, Oracle. All rights reserved.
22
package oracle.toplink.essentials.internal.identitymaps;
23
24 import java.io.*;
25 import java.util.Vector JavaDoc;
26 import oracle.toplink.essentials.internal.helper.*;
27 import oracle.toplink.essentials.sessions.Record;
28
29 /**
30  * <p><b>Purpose</b>: Container class for storing objects in an IdentityMap.
31  * <p><b>Responsibilities</b>:<ul>
32  * <li> Hold key and object.
33  * <li> Maintain and update the current writeLockValue.
34  * </ul>
35  * @since TOPLink/Java 1.0
36  */

37 public class CacheKey implements Serializable, Cloneable JavaDoc {
38
39     /** The key holds the vector of primary key values for the object. */
40     protected Vector JavaDoc key;
41
42     /** Calculated hash value for CacheKey from primary key values. */
43     protected int hash;
44     protected Object JavaDoc object;
45     
46     //used to store a reference to the map this cachkey is in in cases where the
47
//cache key is to be removed, prevents us from having to track down the owning
48
//map
49
protected IdentityMap mapOwner;
50
51     /** The writeLock value is being held as an object so that it might contain a number or timestamp. */
52     protected Object JavaDoc writeLockValue;
53
54     /** The cached wrapper for the object, used in EJB. */
55     protected Object JavaDoc wrapper;
56
57     /** The cache key hold a reference to the concurrency manager to perform the cache key level locking. */
58     protected ConcurrencyManager mutex;
59
60     /** This is used for Document Preservation to cache the record that this object was built from */
61     protected Record record;
62
63     /** This attribute is the system time in milli seconds that the object was last refreshed on */
64
65     //CR #4365
66
// CR #2698903 - fix for the previous fix. No longer using millis.
67
protected long lastUpdatedQueryId;
68
69     /** Invalidation State can be used to indicate whether this cache key is considered valid */
70     protected int invalidationState = CHECK_INVALIDATION_POLICY;
71
72     /** The following constants are used for the invalidationState variable */
73     public static final int CHECK_INVALIDATION_POLICY = 0;
74     public static final int CACHE_KEY_INVALID = -1;
75
76     /** The read time stores the millisecond value of the last time the object help by
77     this cache key was confirmed as up to date. */

78     protected long readTime = 0;
79
80     public CacheKey(Vector JavaDoc primaryKeys) {
81         this.key = primaryKeys;
82         this.hash = computeHash(primaryKeys);
83     }
84
85     public CacheKey(Vector JavaDoc primaryKey, Object JavaDoc object, Object JavaDoc lockValue) {
86         this(primaryKey);
87         //bug4649617 use setter instead of this.object = object to avoid hard reference on object in subclasses
88
setObject(object);
89         this.writeLockValue = lockValue;
90     }
91
92     public CacheKey(Vector JavaDoc primaryKey, Object JavaDoc object, Object JavaDoc lockValue, long readTime) {
93         this(primaryKey, object, lockValue);
94         this.readTime = readTime;
95     }
96
97     /**
98      * Acquire the lock on the cachek key object.
99      */

100     public void acquire() {
101         getMutex().acquire(false);
102     }
103
104     /**
105      * Acquire the lock on the cachek key object. For the merge process
106      * called with true from the merge process, if true then the refresh will not refresh the object
107      */

108     public void acquire(boolean forMerge) {
109         getMutex().acquire(forMerge);
110     }
111
112     /**
113      * Acquire the lock on the cache key object. But only if the object has no lock on it
114      * Added for CR 2317
115      */

116     public boolean acquireNoWait() {
117         return getMutex().acquireNoWait(false);
118     }
119
120     /**
121      * Acquire the lock on the cache key object. But only if the object has no lock on it
122      * Added for CR 2317
123      * called with true from the merge process, if true then the refresh will not refresh the object
124      */

125     public boolean acquireNoWait(boolean forMerge) {
126         return getMutex().acquireNoWait(forMerge);
127     }
128
129     /**
130      * Acquire the deferred lcok.
131      */

132     public void acquireDeferredLock() {
133         getMutex().acquireDeferredLock();
134     }
135     
136     /**
137      * Check the read lock on the cachek key object.
138      * This can be called to ensure the cache key has a valid built object.
139      * It does not hold a lock, so the object could be refreshed afterwards.
140      */

141     public void checkReadLock() {
142         getMutex().checkReadLock();
143     }
144     
145     /**
146      * Acquire the read lock on the cachek key object.
147      */

148     public void acquireReadLock() {
149         getMutex().acquireReadLock();
150     }
151
152     /**
153      * Acquire the read lock on the cache key object.
154      */

155     public boolean acquireReadLockNoWait() {
156         return getMutex().acquireReadLockNoWait();
157     }
158
159     /**
160      * INTERNAL:
161      * Clones itself.
162      */

163     public Object JavaDoc clone() {
164         Object JavaDoc object = null;
165
166         try {
167             object = super.clone();
168         } catch (Exception JavaDoc exception) {
169             throw new InternalError JavaDoc(exception.toString());
170         }
171
172         return object;
173     }
174
175     /**
176      * Compute a hash value for the CacheKey dependent upon the values of the primary key
177      * instead of the identity of the receiver.
178      * This method is intended for use by constructors only.
179      */

180     protected int computeHash(Vector JavaDoc primaryKey) {
181         int computedHashValue = 0;
182
183         for (int index = 0; index < primaryKey.size(); index++) {
184             Object JavaDoc value = primaryKey.elementAt(index);
185             if (value != null) {
186                 computedHashValue = computedHashValue ^ (value.hashCode());
187             }
188         }
189         return computedHashValue;
190     }
191
192     /**
193      * Determine if the receiver is equal to anObject.
194      * If anObject is a CacheKey, do further comparison, otherwise, return false.
195      * @see CacheKey#equals(CacheKey)
196      */

197     public boolean equals(Object JavaDoc object) {
198         if (object instanceof CacheKey) {
199             return equals((CacheKey)object);
200         }
201
202         return false;
203     }
204
205     /**
206      * Determine if the receiver is equal to key.
207      * Use an index compare, because it is much faster than enumerations.
208      */

209     public boolean equals(CacheKey key) {
210         if (this == key) {
211             return true;
212         }
213         if (getKey().size() == key.getKey().size()) {
214             for (int index = 0; index < getKey().size(); index++) {
215                 Object JavaDoc myValue = getKey().elementAt(index);
216                 Object JavaDoc comparisionValue = key.getKey().elementAt(index);
217
218                 if (myValue == null) {
219                     if (comparisionValue != null) {
220                         return false;
221                     }
222                 } else if (myValue.getClass().isArray()) {
223                     if (((myValue.getClass() == ClassConstants.APBYTE) && (comparisionValue.getClass() == ClassConstants.APBYTE)) && (Helper.compareByteArrays((byte[])myValue, (byte[])comparisionValue))) {
224                         return false;
225                     } else if (((myValue.getClass() == ClassConstants.APCHAR) && (comparisionValue.getClass() == ClassConstants.APCHAR)) && (Helper.compareCharArrays((char[])myValue, (char[])comparisionValue))) {
226                         return false;
227                     } else {
228                         if (Helper.compareArrays((Object JavaDoc[])myValue, (Object JavaDoc[])comparisionValue)) {
229                             return false;
230                         }
231                     }
232                 } else {
233                     if (!(myValue.equals(comparisionValue))) {
234                         return false;
235                     }
236                 }
237             }
238             return true;
239         }
240         return false;
241     }
242
243     /**
244      * INTERNAL:
245      * This method returns the system time in millis seconds at which this object was last refreshed
246      * CR #4365
247      * CR #2698903 ... instead of using millis we will now use id's instead. Method
248      * renamed appropriately.
249      */

250     public long getLastUpdatedQueryId() {
251         return this.lastUpdatedQueryId;
252     }
253
254     public Vector JavaDoc getKey() {
255         return key;
256     }
257
258     /**
259      * Return the concurrency manager.
260      */

261     public synchronized ConcurrencyManager getMutex() {
262         if (mutex == null) {
263             mutex = new ConcurrencyManager(this);
264         }
265         return mutex;
266     }
267
268     public Object JavaDoc getObject() {
269         return object;
270     }
271
272     public IdentityMap getOwningMap(){
273         return this.mapOwner;
274     }
275     
276     /**
277      * INTERNAL:
278      * Return the current value of the Read Time variable
279      */

280     public long getReadTime() {
281         return readTime;
282     }
283
284     public Record getRecord() {
285         return record;
286     }
287
288     public Object JavaDoc getWrapper() {
289         return wrapper;
290     }
291
292     public Object JavaDoc getWriteLockValue() {
293         return writeLockValue;
294     }
295
296     /**
297      * Overrides hashCode() in Object to use the primaryKey's hashCode for storage in data structures.
298      */

299     public int hashCode() {
300         return hash;
301     }
302
303     /**
304      * Return if the lock is acquired
305      */

306     public boolean isAcquired() {
307         return getMutex().isAcquired();
308     }
309
310     /**
311      * INTERNAL:
312      * Return the value of the invalidationState Variable
313      * The return value will be a constant
314      * CHECK_INVALIDATION_POLICY - The Invalidation policy is must be checked for this cache key's sate
315      * CACHE_KEY_INVALID - This cache key has been labeled invalid.
316      */

317     public int getInvalidationState() {
318         return invalidationState;
319     }
320
321     /**
322      * Release the lock on the cachek key object.
323      */

324     public void release() {
325         getMutex().release();
326     }
327
328     /**
329      * Release the deferred lock
330      */

331     public void releaseDeferredLock() {
332         getMutex().releaseDeferredLock();
333     }
334
335     /**
336      * Release the read lock on the cachek key object.
337      */

338     public void releaseReadLock() {
339         getMutex().releaseReadLock();
340     }
341
342     /**
343      * INTERNAL:
344      * Set the value of the invalidationState Variable
345      * The possible values are from an enumeration of constants
346      * CHECK_INVALIDATION_POLICY - The invalidation policy is must be checked for this cache key's sate
347      * CACHE_KEY_INVALID - This cache key has been labeled invalid.
348      */

349     public void setInvalidationState(int invalidationState) {
350         this.invalidationState = invalidationState;
351     }
352
353     /**
354      * INTERNAL:
355      * This method sets the system time in millis seconds at which this object was last refreshed
356      * CR #4365
357      * CR #2698903 ... instead of using millis we will now use ids instead. Method
358      * renamed appropriately.
359      */

360     public void setLastUpdatedQueryId(long id) {
361         this.lastUpdatedQueryId = id;
362     }
363
364     public void setKey(Vector JavaDoc key) {
365         this.key = key;
366         this.hash = computeHash(key);
367     }
368
369     /**
370      * Set the concurrency manager.
371      */

372     public void setMutex(ConcurrencyManager mutex) {
373         this.mutex = mutex;
374     }
375
376     public void setObject(Object JavaDoc object) {
377         this.object = object;
378     }
379
380     public void setOwningMap(IdentityMap map){
381         this.mapOwner = map;
382     }
383     
384     /**
385      * INTERNAL:
386      * Set the read time of this cache key
387      */

388     public void setReadTime(long readTime) {
389         this.readTime = readTime;
390         invalidationState = CHECK_INVALIDATION_POLICY;
391     }
392
393     public void setRecord(Record newRecord) {
394         this.record = newRecord;
395     }
396
397     public void setWrapper(Object JavaDoc wrapper) {
398         this.wrapper = wrapper;
399     }
400
401     public void setWriteLockValue(Object JavaDoc writeLockValue) {
402         this.writeLockValue = writeLockValue;
403     }
404
405     public String JavaDoc toString() {
406         int hashCode = 0;
407         if (getObject() != null) {
408             hashCode = getObject().hashCode();
409         }
410
411         return "[" + getKey() + ": " + hashCode + ": " + getWriteLockValue() + ": " + getReadTime() + ": " + getObject() + "]";
412     }
413
414     /**
415      * Notifies that cache key that it has been accessed.
416      * Allows the LRU sub-cache to be maintained.
417      */

418     public void updateAccess() {
419         // Nothing required by default.
420
}
421 }
422
Popular Tags