Mercurial > hg > blitz_condensed
view src/org/dancres/blitz/txnlock/LockCache.java @ 0:3dc0c5604566
Initial checkin of blitz 2.0 fcs - no installer yet.
author | Dan Creswell <dan.creswell@gmail.com> |
---|---|
date | Sat, 21 Mar 2009 11:00:06 +0000 |
parents | |
children |
line wrap: on
line source
package org.dancres.blitz.txnlock; import java.util.HashMap; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import org.dancres.blitz.oid.OID; class LockCache { private HashMap theLocks = new HashMap(); private ReferenceQueue theDeadLocks = new ReferenceQueue(); LockCache() { } TxnLock getOrInsert(OID aOID) { cleanQueue(); synchronized(this) { TxnLock myLock = get(aOID); if (myLock == null) { myLock = new TxnLock(); put(aOID, myLock); } return myLock; } } TxnLock get(OID aOID) { cleanQueue(); synchronized(this) { LockHolder myHolder = (LockHolder) theLocks.get(aOID); return (myHolder == null) ? null : (TxnLock) myHolder.get(); } } void put(OID aOID, TxnLock aLock) { cleanQueue(); synchronized(this) { LockHolder myHolder = new LockHolder(aOID, aLock, theDeadLocks); theLocks.put(aOID, myHolder); } } private void cleanQueue() { LockHolder myRef; while ((myRef = (LockHolder) theDeadLocks.poll()) != null) { synchronized(this) { LockHolder myOther = (LockHolder) theLocks.remove(myRef.getOID()); /* Check that the reference we're releasing is the same as the one we currently have in the table. Otherwise: It could be that get(OID) was called above and the holder was recovered but it's reference had been cleared resulting in allocation of a new lock BEFORE we've processed the reference from the queue. Thus we allocate the new lock, the old reference (from get(OID)) is enqueued and we then delete the new lock - oops! */ if ((myOther != null) &&(! myOther.equals(myRef))) { theLocks.put(myOther.getOID(), myOther); } } } } private class LockHolder extends WeakReference { private OID theOID; LockHolder(OID aOID, TxnLock aLock, ReferenceQueue aQueue) { super(aLock, aQueue); theOID = aOID; } OID getOID() { return theOID; } } }