KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * Copyright (c) 2003-2006 Terracotta, Inc. All rights reserved.
3  */

4 package com.tc.objectserver.tx;
5
6 import com.tc.logging.TCLogger;
7 import com.tc.logging.TCLogging;
8 import com.tc.util.Assert;
9
10 import java.util.Arrays JavaDoc;
11 import java.util.Collection JavaDoc;
12 import java.util.HashSet JavaDoc;
13 import java.util.Iterator JavaDoc;
14 import java.util.LinkedList JavaDoc;
15 import java.util.List JavaDoc;
16 import java.util.Set JavaDoc;
17
18 public class TransactionSequencer {
19
20   private static final TCLogger logger = TCLogging.getLogger(TransactionSequencer.class);
21
22   private final Set JavaDoc pendingTxns = new HashSet JavaDoc();
23
24   private final LinkedList JavaDoc txnQ = new LinkedList JavaDoc();
25   private final LinkedList JavaDoc blockedQ = new LinkedList JavaDoc();
26
27   private final BlockedSet locks = new BlockedSet();
28   private final BlockedSet objects = new BlockedSet();
29
30   private int txnsCount;
31   private boolean reconcile = false;
32
33   public synchronized void addTransactions(List JavaDoc txns) {
34     if (false) log_incoming(txns);
35     txnQ.addAll(txns);
36     txnsCount += txns.size();
37   }
38
39   private void log_incoming(List JavaDoc txns) {
40     for (Iterator JavaDoc i = txns.iterator(); i.hasNext();) {
41       ServerTransaction txn = (ServerTransaction) i.next();
42       logger.info("Incoming : " + txn);
43     }
44   }
45
46   public synchronized ServerTransaction getNextTxnToProcess() {
47     reconcileIfNeeded();
48     while (!txnQ.isEmpty()) {
49
50       ServerTransaction txn = (ServerTransaction) txnQ.removeFirst();
51       if (isBlocked(txn)) {
52         addBlocked(txn);
53       } else {
54         if (false) log_outgoing(txn);
55         txnsCount--;
56         return txn;
57       }
58     }
59     if (false) log_no_txns_to_process();
60     return null;
61   }
62
63   private void reconcileIfNeeded() {
64     if (reconcile) {
65       // Add to begining
66
txnQ.addAll(0, blockedQ);
67       blockedQ.clear();
68       locks.clearBlocked();
69       objects.clearBlocked();
70       reconcile = false;
71     }
72   }
73
74   private void addBlocked(ServerTransaction txn) {
75     locks.addBlocked(Arrays.asList(txn.getLockIDs()));
76     objects.addBlocked(txn.getObjectIDs());
77     blockedQ.add(txn);
78   }
79
80   private void log_no_txns_to_process() {
81     if (txnsCount != 0) {
82       int psize = pendingTxns.size();
83       logger.info("No More Txns that can be processed : txnCount = " + txnsCount + " and pending txns = " + psize);
84     }
85   }
86
87   private void log_outgoing(ServerTransaction txn) {
88     logger.info("Outgoing : " + txn);
89   }
90
91   private boolean isBlocked(ServerTransaction txn) {
92     return locks.isBlocked(Arrays.asList(txn.getLockIDs())) || objects.isBlocked(txn.getObjectIDs());
93   }
94
95   public synchronized void makePending(ServerTransaction txn) {
96     locks.makePending(Arrays.asList(txn.getLockIDs()));
97     objects.makePending(txn.getObjectIDs());
98     Assert.assertTrue(pendingTxns.add(txn.getServerTransactionID()));
99     if (false) logger.info("Make Pending : " + txn);
100   }
101
102   public synchronized void makeUnpending(ServerTransaction txn) {
103     Assert.assertTrue(pendingTxns.remove(txn.getServerTransactionID()));
104     locks.makeUnpending(Arrays.asList(txn.getLockIDs()));
105     objects.makeUnpending(txn.getObjectIDs());
106     reconcile = true;
107     if (false) logger.info("Processed Pending : " + txn);
108   }
109
110   /*
111    * Used for testing
112    */

113   boolean isPending(List JavaDoc txns) {
114     for (Iterator JavaDoc i = txns.iterator(); i.hasNext();) {
115       ServerTransaction st = (ServerTransaction) i.next();
116       if (pendingTxns.contains(st.getServerTransactionID())) return true;
117     }
118     return false;
119   }
120
121   private static final class BlockedSet {
122
123     Set JavaDoc cause = new HashSet JavaDoc();
124     Set JavaDoc effect = new HashSet JavaDoc();
125
126     public boolean isBlocked(Collection JavaDoc keys) {
127       for (Iterator JavaDoc i = keys.iterator(); i.hasNext();) {
128         Object JavaDoc o = i.next();
129         if (cause.contains(o) || effect.contains(o)) { return true; }
130       }
131       return false;
132     }
133
134     public void makePending(Collection JavaDoc keys) {
135       cause.addAll(keys);
136     }
137
138     public void makeUnpending(Collection JavaDoc keys) {
139       cause.removeAll(keys);
140     }
141
142     public void addBlocked(Collection JavaDoc keys) {
143       effect.addAll(keys);
144     }
145
146     public void clearBlocked() {
147       effect.clear();
148     }
149   }
150 }
151
Popular Tags