FileDocCategorySizeDatePackage
IdentityMap.javaAPI DocGlassfish v2 API16512Tue May 22 16:54:34 BST 2007oracle.toplink.essentials.internal.identitymaps

IdentityMap

public abstract class IdentityMap extends Object implements Serializable, Cloneable

Purpose: Caches objects, and allows their retrieval by their primary key.

Responsibilities:

  • Store CacheKeys containing objects and possibly writeLockValues
  • Insert & retrieve objects from the cache
  • Allow retrieval and modification of writeLockValue for a cached object.
see
CacheKey
since
TOPLink/Java 1.0

Fields Summary
protected int
maxSize
The innitial or maximum size of the cache depending upon the concrete implementation
protected CacheKey
searchKey
Used to optimize get through avoiding recreation of the cache key each time.
Constructors Summary
public IdentityMap(int size)
Instantiate an new IdentityMap with it's maximum size.

NOTE: Subclasses may provide different behaviour for maxSize.

param
anInteger is the maximum size to be allocated for the recevier.

        maxSize = size;
        searchKey = new CacheKey(new Vector(1), null, null);
    
Methods Summary
public oracle.toplink.essentials.internal.identitymaps.CacheKeyacquireDeferredLock(java.util.Vector primaryKey)
Acquire the deferred lock

        //check if the key is already in the hashtable
        CacheKey key = null;

        //cache key should not be changed in other threads during the lock acquire operation
        synchronized (this) {
            // bug 3094912 get must be synchronized as well
            key = getCacheKey(primaryKey);
            if (key == null) {
                //create a chachKey and lock the object
                CacheKey cacheKey = createCacheKey(primaryKey, null, null);
                cacheKey.acquireDeferredLock();
                put(cacheKey);
                return cacheKey;
            }
        }

        // code removed as key will never be null here, either one will be found or one created
        key.acquireDeferredLock();

        return key;
    
public oracle.toplink.essentials.internal.identitymaps.CacheKeyacquireLock(java.util.Vector primaryKey, boolean forMerge)
Set an exclusive lock on an object in the IdentityMap. This is provided so that when the object is being read from the database the reader can lock the object while it builds and caches the new object. This will prevent other threads from accessing this objects but will not stop other threads from inserting other objects into this IdentityMap.

        //check if the key is already in the hashtable
        CacheKey key = null;

        //cache key should not be changed in other threads during the lock acquire operation
        synchronized (this) {
            // bug 3094912 get must be synchronized as well
            key = getCacheKey(primaryKey);
            if (key == null) {
                //create a chachKey and lock the object
                CacheKey cacheKey = createCacheKey(primaryKey, null, null);
                cacheKey.acquire(forMerge);
                put(cacheKey);
                return cacheKey;
            }
        }

        // code removed as key will never be null here, either one will be found or one created
        key.acquire();

        return key;
    
public oracle.toplink.essentials.internal.identitymaps.CacheKeyacquireLockNoWait(java.util.Vector primaryKey, boolean forMerge)
Set an exclusive lock on an object in the IdentityMap. This is provided so that when the object is being read from the database the reader can lock the object while it builds and caches the new object. This will prevent other threads from accessing this objects but will not stop other threads from inserting other objects into this IdentityMap.

        //check if the key is already in the hashtable
        CacheKey key = null;

        //cache key should not be changed in other threads during the lock acquire operation
        synchronized (this) {
            key = getCacheKey(primaryKey);
            if (key == null) {
                //create a chachKey and lock the object
                CacheKey cacheKey = createCacheKey(primaryKey, null, null);
                cacheKey.acquire(forMerge);
                put(cacheKey);
                return cacheKey;
            }
        }

        //find the key in the hashtable, lock the object
        if (key != null) {
            //couldn't acquire the key so do not return it
            if (!key.acquireNoWait(forMerge)) {
                key = null;
            }
        }

        return key;
    
public oracle.toplink.essentials.internal.identitymaps.CacheKeyacquireReadLockOnCacheKey(java.util.Vector primaryKey)
INTERNAL: Find the cachekey for the provided primary key and place a readlock on it. This will allow multiple users to read the same object but prevent writes to the object while the read lock is held.

        //check if the key is already in the hashtable
        CacheKey key = null;

        //cache key should not be changed in other threads during the lock acquire operation
        synchronized (this) {
            key = getCacheKey(primaryKey);
            if (key == null) {
                //create a chachKey and lock the object
                CacheKey cacheKey = createCacheKey(primaryKey, null, null);

                //lets create one but not put it in the cache, as we are only reading
                //  should not be writing to the identitymap
                cacheKey.acquireReadLock();
                return cacheKey;
            }
        }

        key.acquireReadLock();

        return key;
    
public oracle.toplink.essentials.internal.identitymaps.CacheKeyacquireReadLockOnCacheKeyNoWait(java.util.Vector primaryKey)
INTERNAL: Find the cachekey for the provided primary key and place a readlock on it. This will allow multiple users to read the same object but prevent writes to the object while the read lock is held. If no readlock can be acquired then do not wait but return null.

        //check if the key is already in the hashtable
        CacheKey key = null;

        //cache key should not be changed in other threads during the lock acquire operation
        synchronized (this) {
            key = getCacheKey(primaryKey);
            if (key == null) {
                //create a chachKey and lock the object
                CacheKey cacheKey = createCacheKey(primaryKey, null, null);
                cacheKey.acquireReadLock();

                //lets create one but not put it in the cache, as we are only reading
                //  should not be writing to the identitymap
                return cacheKey;
            }
        }

        //find the key in the hashtable, lock the object
        if (key != null) {
            //couldn't acquire the key so do not return it
            if (!key.acquireReadLockNoWait()) {
                key = null;
            }
        }

        return key;
    
public java.lang.Objectclone()
INTERNAL: Clones itself.

        Object object = null;

        try {
            object = super.clone();
        } catch (Exception e) {
            ;
        }

        return object;
    
public abstract voidcollectLocks(java.util.HashMap threadList)
INTERNAL: Used to print all the Locks in every identity map in this session. The output of this method will go to log passed in as a parameter.

public booleancontainsKey(java.util.Vector primaryKey)
Return true if an object is indexed in the recevier at the primary key <aVector>

param
aVector is the primary key for the object to search for.

        CacheKey wrapper = getCacheKeyWithReadLock(primaryKey);

        if (wrapper == null) {
            return false;
        } else {
            return true;
        }
    
public oracle.toplink.essentials.internal.identitymaps.CacheKeycreateCacheKey(java.util.Vector primaryKey, java.lang.Object object, java.lang.Object writeLockValue)

        return createCacheKey(primaryKey, object, writeLockValue, 0);
    
public oracle.toplink.essentials.internal.identitymaps.CacheKeycreateCacheKey(java.util.Vector primaryKey, java.lang.Object object, java.lang.Object writeLockValue, long readTime)

        return new CacheKey(primaryKey, object, writeLockValue, readTime);
    
public abstract java.util.Enumerationelements()
Allow for the cache to be iterated on.

public java.lang.Objectget(java.util.Vector primaryKey)
Return the object cached in the identity map or null if it could not be found.

        CacheKey cacheKey = getCacheKeyWithReadLock(primaryKey);

        if (cacheKey == null) {
            return null;
        }
        return cacheKey.getObject();
    
protected oracle.toplink.essentials.internal.identitymaps.CacheKeygetCacheKey(java.util.Vector primaryKey)
Get the cache key (with object) for the primary key. This reuses the same instance of cache key (searchKey) for all of the get to improve performance.

        CacheKey key = null;

        synchronized (this) {
            getSearchKey().setKey(primaryKey);
            key = getCacheKey(getSearchKey());
        }

        return key;
    
protected abstract oracle.toplink.essentials.internal.identitymaps.CacheKeygetCacheKey(oracle.toplink.essentials.internal.identitymaps.CacheKey cacheKey)
Return the cache key (with object) matching the cache key wrapper of the primary key.

protected oracle.toplink.essentials.internal.identitymaps.CacheKeygetCacheKeyWithReadLock(java.util.Vector primaryKey)
Get the cache key (with object) for the primary key with read lock.

        CacheKey key = getCacheKey(primaryKey);

        if (key != null) {
            key.acquireReadLock();
            key.releaseReadLock();
        }

        return key;
    
public static java.lang.ClassgetDefaultIdentityMapClass()
INTERNAL: Returns the class which should be used as an identity map. For JDK1.1.x FullIdentityMap is the default, for JDK1.2 it is SoftCacheWeakIdentityMap.

return
java.lang.Class

        return ClassConstants.SoftCacheWeakIdentityMap_Class;
    
public intgetMaxSize()

return
The maxSize for the IdentityMap (NOTE: some subclasses may use this differently).

        if (maxSize == -1) {
            maxSize = 100;
        }
        return maxSize;
    
protected oracle.toplink.essentials.internal.identitymaps.CacheKeygetSearchKey()

        return searchKey;
    
public abstract intgetSize()
Return the number of objects in the receiver.

public abstract intgetSize(java.lang.Class myClass, boolean recurse)
Return the number of actual objects of type myClass in the IdentityMap. Recurse = true will include subclasses of myClass in the count.

public java.lang.ObjectgetWrapper(java.util.Vector primaryKey)
Get the wrapper object from the cache key associated with the given primary key, this is used for EJB.

        CacheKey cacheKey = getCacheKeyWithReadLock(primaryKey);

        if (cacheKey == null) {
            return null;
        } else {
            return cacheKey.getWrapper();
        }
    
public java.lang.ObjectgetWriteLockValue(java.util.Vector primaryKey)
Get the write lock value from the cache key associated to the primarykey

        CacheKey cacheKey = getCacheKeyWithReadLock(primaryKey);

        if (cacheKey == null) {
            return null;
        } else {
            return cacheKey.getWriteLockValue();
        }
    
public voidinitialize(int size)
Initialize the newly allocated instance of this class. This method must be called in order for the IdentityMap to be functional.

param
anInteger is the maximum size to be allocated for the recevier.

        setMaxSize(size);
    
public abstract java.util.Enumerationkeys()
Allow for the cache keys to be iterated on.

public abstract oracle.toplink.essentials.internal.identitymaps.CacheKeyput(java.util.Vector primaryKey, java.lang.Object object, java.lang.Object writeLockValue, long readTime)
Store the object in the cache at its primary key.

param
primaryKey is the primary key for the object.
param
object is the domain object to cache.
param
writeLockValue is the current write lock value of object, if null the version is ignored.
param
readTime the read time of the object to be stored in the cache

protected abstract voidput(oracle.toplink.essentials.internal.identitymaps.CacheKey cacheKey)
Store the object in the cache with the cache key. Should be overide by the sub-class

public java.lang.Objectremove(java.util.Vector primaryKey)
Remove the primary key from the cache.

        CacheKey key = getCacheKey(primaryKey);
        return remove(key);
    
public abstract java.lang.Objectremove(oracle.toplink.essentials.internal.identitymaps.CacheKey cacheKey)
Remove the cache key from the cache.

protected voidsetMaxSize(int size)
Set the maximum size for the recevier.

param
anInteger is the new maximum size.

        maxSize = size;
    
protected voidsetSearchKey(oracle.toplink.essentials.internal.identitymaps.CacheKey searchKey)

        this.searchKey = searchKey;
    
public voidsetWrapper(java.util.Vector primaryKey, java.lang.Object wrapper)
Update the wrapper object the cache key associated with the given primary key, this is used for EJB.

        CacheKey cacheKey = getCacheKey(primaryKey);

        if (cacheKey != null) {
            cacheKey.setWrapper(wrapper);
        }
    
public voidsetWriteLockValue(java.util.Vector primaryKey, java.lang.Object writeLockValue)
Update the write lock value of the cache key associated with the given primary key,

        CacheKey cacheKey = getCacheKey(primaryKey);

        if (cacheKey != null) {
            //lock/release the cache key during the lock value updating
            cacheKey.acquire();
            cacheKey.setWriteLockValue(writeLockValue);
            cacheKey.release();
        }
    
public java.lang.StringtoString()

        return oracle.toplink.essentials.internal.helper.Helper.getShortClassName(getClass()) + "[" + getSize() + "]";
    
public voidupdateCacheKey(oracle.toplink.essentials.internal.identitymaps.CacheKey cacheKey)
This is used to notify the identity map of a locked keys modification to allow updating of weak refs.

        return;
    
public synchronized voidupdateMaxSize(int maxSize)
INTERNAL: This method will be used to update the max cache size, any objects exceeding the max cache size will be remove from the cache. Please note that this does not remove the object from the identityMap, except in the case of the CacheIdentityMap.

        setMaxSize(maxSize);