comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:3dc0c5604566
1 package org.dancres.blitz.txnlock;
2
3 import java.util.HashMap;
4
5 import java.lang.ref.ReferenceQueue;
6 import java.lang.ref.WeakReference;
7
8 import org.dancres.blitz.oid.OID;
9
10 class LockCache {
11 private HashMap theLocks = new HashMap();
12
13 private ReferenceQueue theDeadLocks = new ReferenceQueue();
14
15 LockCache() {
16 }
17
18 TxnLock getOrInsert(OID aOID) {
19 cleanQueue();
20
21 synchronized(this) {
22 TxnLock myLock = get(aOID);
23
24 if (myLock == null) {
25 myLock = new TxnLock();
26 put(aOID, myLock);
27 }
28
29 return myLock;
30 }
31 }
32
33 TxnLock get(OID aOID) {
34 cleanQueue();
35
36 synchronized(this) {
37 LockHolder myHolder = (LockHolder) theLocks.get(aOID);
38
39 return (myHolder == null) ? null : (TxnLock) myHolder.get();
40 }
41 }
42
43 void put(OID aOID, TxnLock aLock) {
44 cleanQueue();
45
46 synchronized(this) {
47 LockHolder myHolder = new LockHolder(aOID, aLock, theDeadLocks);
48
49 theLocks.put(aOID, myHolder);
50 }
51 }
52
53 private void cleanQueue() {
54 LockHolder myRef;
55
56 while ((myRef = (LockHolder) theDeadLocks.poll()) != null) {
57 synchronized(this) {
58 LockHolder myOther = (LockHolder) theLocks.remove(myRef.getOID());
59
60 /*
61 Check that the reference we're releasing is the same as the
62 one we currently have in the table. Otherwise:
63
64 It could be that get(OID) was called above and the holder was
65 recovered but it's reference had been cleared resulting in
66 allocation of a new lock BEFORE we've processed the reference
67 from the queue. Thus we allocate the new lock, the old
68 reference (from get(OID)) is enqueued and we then delete the
69 new lock - oops!
70 */
71 if ((myOther != null) &&(! myOther.equals(myRef))) {
72 theLocks.put(myOther.getOID(), myOther);
73 }
74 }
75 }
76 }
77
78 private class LockHolder extends WeakReference {
79 private OID theOID;
80
81 LockHolder(OID aOID, TxnLock aLock, ReferenceQueue aQueue) {
82 super(aLock, aQueue);
83 theOID = aOID;
84 }
85
86 OID getOID() {
87 return theOID;
88 }
89 }
90 }