KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > objectserver > tx > TransactionAccountImpl


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.objectserver.tx;
5
6 import com.tc.net.protocol.tcm.ChannelID;
7 import com.tc.object.tx.TransactionID;
8 import com.tc.util.Assert;
9
10 import java.util.Collections JavaDoc;
11 import java.util.HashMap JavaDoc;
12 import java.util.HashSet JavaDoc;
13 import java.util.Iterator JavaDoc;
14 import java.util.Map JavaDoc;
15 import java.util.Set JavaDoc;
16
17 /**
18  * An account of the state of a given transaction. Keeps track of the initiating client, the state of the transaction
19  * (applied, committed, etc), clients the transaction has been broadcast to, and clients that have ACKed the
20  * transaction.
21  *
22  */

23 public class TransactionAccountImpl implements TransactionAccount {
24   final ChannelID clientID;
25   private final Map JavaDoc waitees = Collections.synchronizedMap(new HashMap JavaDoc());
26
27   public TransactionAccountImpl(ChannelID clientID) {
28     this.clientID = clientID;
29   }
30
31   public String JavaDoc toString() {
32     return "TransactionAccount[" + clientID + ": waitees=" + waitees + "]\n";
33   }
34
35   public ChannelID getClientID() {
36     return clientID;
37   }
38
39   /*
40    * returns true if completed, false if not completed or if the client has sent a duplicate ACK.
41    */

42   public boolean removeWaitee(ChannelID waitee, TransactionID requestID) {
43     TransactionRecord transactionRecord = getRecord(requestID);
44
45     if (transactionRecord == null) return false;
46     synchronized (transactionRecord) {
47       transactionRecord.remove(waitee);
48       return checkCompleted(requestID, transactionRecord);
49     }
50   }
51
52   public void addWaitee(ChannelID waitee, TransactionID requestID) {
53     TransactionRecord record = getOrCreateRecord(requestID);
54     synchronized (record) {
55       boolean added = record.addWaitee(waitee);
56       Assert.eval(added);
57     }
58   }
59
60   private TransactionRecord getOrCreateRecord(TransactionID requestID) {
61     synchronized (waitees) {
62       TransactionRecord transactionRecord = getRecord(requestID);
63       if (transactionRecord == null) {
64         waitees.put(requestID, (transactionRecord = new TransactionRecord()));
65       }
66       return transactionRecord;
67     }
68   }
69
70   private TransactionRecord getRecord(TransactionID requestID) {
71     TransactionRecord transactionRecord = (TransactionRecord) waitees.get(requestID);
72     return transactionRecord;
73   }
74
75   public boolean skipApplyAndCommit(TransactionID requestID) {
76     TransactionRecord transactionRecord = getOrCreateRecord(requestID);
77     synchronized (transactionRecord) {
78       transactionRecord.applyAndCommitSkipped();
79       return checkCompleted(requestID, transactionRecord);
80     }
81   }
82
83   public void applyStarted(TransactionID requestID) {
84     TransactionRecord transactionRecord = getOrCreateRecord(requestID);
85     synchronized (transactionRecord) {
86       transactionRecord.applyStarted();
87     }
88   }
89
90   public boolean applyCommitted(TransactionID requestID) {
91     TransactionRecord transactionRecord = getRecord(requestID);// (TransactionRecord) waitees.get(requestID);
92
if (transactionRecord == null) {
93       // this can happen when a client crashes and there are still some unprocessed apply messages in the
94
// queue. We dont want to try to send acks for such scenario.
95
return false;
96     }
97     synchronized (transactionRecord) {
98       transactionRecord.applyCommitted();
99       return checkCompleted(requestID, transactionRecord);
100     }
101   }
102
103   public boolean broadcastCompleted(TransactionID requestID) {
104     TransactionRecord transactionRecord = getRecord(requestID);// (TransactionRecord) waitees.get(requestID);
105
if (transactionRecord == null) {
106       // this could happen when a client crashes and there are still some unprocessed apply messages in the
107
// queue. We dont want to try to send acks for such scenario.
108
return false;
109     }
110     synchronized (transactionRecord) {
111       transactionRecord.broadcastCompleted();
112       return checkCompleted(requestID, transactionRecord);
113     }
114   }
115
116   public boolean relayTransactionComplete(TransactionID requestID) {
117     TransactionRecord transactionRecord = getOrCreateRecord(requestID);
118     synchronized (transactionRecord) {
119       transactionRecord.relayTransactionComplete();
120       return checkCompleted(requestID, transactionRecord);
121     }
122   }
123
124   public boolean hasWaitees(TransactionID requestID) {
125     TransactionRecord record = getRecord(requestID);
126     if (record == null) return false;
127     synchronized (record) {
128       return !record.isEmpty();
129     }
130   }
131
132   public Set JavaDoc requestersWaitingFor(ChannelID waitee) {
133     Set JavaDoc requesters = new HashSet JavaDoc();
134     synchronized (waitees) {
135       for (Iterator JavaDoc i = new HashSet JavaDoc(waitees.keySet()).iterator(); i.hasNext();) {
136         TransactionID requester = (TransactionID) i.next();
137         // if (((Set) waitees.get(requester)).contains(waitee))
138
if (getRecord(requester).contains(waitee)) {
139           requesters.add(requester);
140         }
141       }
142     }
143     return requesters;
144   }
145
146   private boolean checkCompleted(TransactionID requestID, TransactionRecord record) {
147     if (record.isComplete()) {
148       waitees.remove(requestID);
149       return true;
150     }
151     return false;
152   }
153
154 }
Popular Tags