KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > object > tx > TransactionBatchAccounting


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.object.tx;
5
6 import gnu.trove.TLinkable;
7 import gnu.trove.TLinkedList;
8
9 import java.util.Collection JavaDoc;
10 import java.util.HashMap JavaDoc;
11 import java.util.HashSet JavaDoc;
12 import java.util.Iterator JavaDoc;
13 import java.util.LinkedList JavaDoc;
14 import java.util.List JavaDoc;
15 import java.util.Map JavaDoc;
16 import java.util.Set JavaDoc;
17
18 public class TransactionBatchAccounting {
19
20   private final Map JavaDoc batchesByTransaction = new HashMap JavaDoc();
21   private final TLinkedList batches = new TLinkedList();
22   private final Set JavaDoc completedTransactionIDs = new HashSet JavaDoc();
23   private boolean stopped = false;
24
25   public Object JavaDoc dump() {
26     return this.toString();
27   }
28
29   public String JavaDoc toString() {
30     return "TransactionBatchAccounting[batchesByTransaction=" + batchesByTransaction
31            + ", completedGlobalTransactionIDs=" + completedTransactionIDs + "]";
32   }
33
34   public synchronized void addBatch(TxnBatchID batchID, Collection JavaDoc transactionIDs) {
35     if (stopped || transactionIDs.size() == 0) return;
36     BatchDescriptor desc = new BatchDescriptor(batchID, transactionIDs);
37     batches.add(desc);
38     for (Iterator JavaDoc i = transactionIDs.iterator(); i.hasNext();) {
39       TransactionID txID = (TransactionID) i.next();
40       Object JavaDoc removed = batchesByTransaction.put(txID, desc);
41       if (removed != null) { throw new AssertionError JavaDoc("TransactionID is already accounted for: " + txID + "=>"
42                                                       + removed); }
43     }
44   }
45
46   public synchronized TxnBatchID getBatchByTransactionID(TransactionID txID) {
47     BatchDescriptor desc = (BatchDescriptor) batchesByTransaction.get(txID);
48     return desc == null ? TxnBatchID.NULL_BATCH_ID : desc.batchID;
49   }
50
51   /**
52    * Adds all incomplete transaction batch ids to the given collection in the order they were added. An incomplete
53    * transaction batch is a batch for which not all its constituent transactions have been ACKed.
54    *
55    * @param c The collection to add all incomplete batch ids to
56    * @return The input collection
57    */

58   public synchronized List addIncompleteBatchIDsTo(List c) {
59     for (Iterator JavaDoc i = batches.iterator(); i.hasNext();) {
60       BatchDescriptor desc = (BatchDescriptor) i.next();
61       c.add(desc.batchID);
62     }
63     return c;
64   }
65
66   public synchronized TxnBatchID getMinIncompleteBatchID() {
67     return batches.isEmpty() ? TxnBatchID.NULL_BATCH_ID : ((BatchDescriptor) batches.getFirst()).batchID;
68   }
69
70   public synchronized TxnBatchID acknowledge(TransactionID txID) {
71     if (stopped) return TxnBatchID.NULL_BATCH_ID;
72     final TxnBatchID completed;
73     final BatchDescriptor desc = (BatchDescriptor) batchesByTransaction.remove(txID);
74     if (desc == null) throw new AssertionError JavaDoc("Batch not found for " + txID);
75     completedTransactionIDs.add(txID);
76     if (desc.acknowledge(txID) == 0) {
77       // completedGlobalTransactionIDs.addAll(desc.globalTransactionIDs);
78
batches.remove(desc);
79       completed = desc.batchID;
80     } else {
81       completed = TxnBatchID.NULL_BATCH_ID;
82     }
83     if (batches.size() == 0 && batchesByTransaction.size() > 0) { throw new AssertionError JavaDoc(
84                                                                                            "Batches list and batchesByTransaction map aren't zero at the same time"); }
85     return completed;
86   }
87
88   public synchronized Collection JavaDoc addCompletedTransactionIDsTo(Collection JavaDoc c) {
89     c.addAll(completedTransactionIDs);
90     return c;
91   }
92
93   public synchronized void clear() {
94     batches.clear();
95     batchesByTransaction.clear();
96     clearCompletedTransactionIds();
97   }
98   
99   public synchronized void clearCompletedTransactionIds() {
100     completedTransactionIDs.clear();
101   }
102
103   private static final class BatchDescriptor implements TLinkable {
104     private final TxnBatchID batchID;
105     private final Set JavaDoc transactionIDs = new HashSet JavaDoc();
106
107     private TLinkable next;
108     private TLinkable previous;
109
110     public BatchDescriptor(TxnBatchID batchID, Collection JavaDoc txIDs) {
111       this.batchID = batchID;
112       transactionIDs.addAll(txIDs);
113     }
114
115     public String JavaDoc toString() {
116       return "BatchDescriptor[" + batchID + ", transactionIDs=" + transactionIDs + "]";
117     }
118
119     public int acknowledge(TransactionID txID) {
120       transactionIDs.remove(txID);
121       return transactionIDs.size();
122     }
123
124     public TLinkable getNext() {
125       return next;
126     }
127
128     public TLinkable getPrevious() {
129       return previous;
130     }
131
132     public void setNext(TLinkable linkable) {
133       next = linkable;
134     }
135
136     public void setPrevious(TLinkable linkable) {
137       previous = linkable;
138     }
139   }
140
141   /**
142    * This is used for testing.
143    */

144   public synchronized List addIncompleteTransactionIDsTo(LinkedList list) {
145     list.addAll(batchesByTransaction.keySet());
146     return list;
147   }
148
149   /**
150    * Ignores all further modifier calls. This is used for testing to stop shutdown hooks from hanging.
151    */

152   public synchronized void stop() {
153     this.stopped = true;
154   }
155
156 }
157
Popular Tags