1 5 package com.tc.objectserver.tx; 6 7 import com.tc.object.tx.ServerTransactionID; 8 import com.tc.properties.TCPropertiesImpl; 9 import com.tc.text.PrettyPrintable; 10 import com.tc.text.PrettyPrinter; 11 import com.tc.util.Assert; 12 import com.tc.util.State; 13 14 import java.util.Collection ; 15 import java.util.Collections ; 16 import java.util.ConcurrentModificationException ; 17 import java.util.HashMap ; 18 import java.util.Iterator ; 19 import java.util.Map ; 20 import java.util.NoSuchElementException ; 21 import java.util.Map.Entry; 22 23 public final class TxnObjectGrouping implements PrettyPrintable { 24 private static final int MAX_OBJECTS = TCPropertiesImpl.getProperties() 25 .getInt("l2.objectmanager.maxObjectsInTxnObjGrouping"); 26 private static final int MAX_TXNS = TCPropertiesImpl.getProperties() 27 .getInt("l2.objectmanager.maxTxnsInTxnObjectGrouping"); 28 29 private static final State APPLY_PENDING = new State("APPLY_PENDING"); 30 private static final State COMMIT_PENDING = new State("COMMIT_PENDING"); 31 32 private final ServerTransactionID txID; 33 private Map txns; 34 private Map objects; 35 private final Map newRootsMap; 36 private int pendingApplys; 37 private boolean isActive = true; 38 39 public TxnObjectGrouping(ServerTransactionID sTxID, Map newRootsMap) { 40 this.txID = sTxID; 41 this.newRootsMap = newRootsMap; 42 this.txns = new HashMap (); 43 this.txns.put(sTxID, APPLY_PENDING); 44 this.pendingApplys = 1; 45 this.objects = Collections.EMPTY_MAP; 46 } 47 48 public TxnObjectGrouping(Map lookedupObjects) { 49 this.txID = ServerTransactionID.NULL_ID; 50 this.newRootsMap = Collections.EMPTY_MAP; 51 this.txns = Collections.EMPTY_MAP; 52 objects = lookedupObjects; 53 this.pendingApplys = 0; 54 } 55 56 public boolean applyComplete(ServerTransactionID txnId) { 57 Object o = txns.put(txnId, COMMIT_PENDING); 58 Assert.assertTrue(o == APPLY_PENDING); 59 --pendingApplys; 60 return (pendingApplys == 0); 61 } 62 63 public ServerTransactionID getServerTransactionID() { 64 return txID; 65 } 66 67 public Map getObjects() { 68 return objects; 69 } 70 71 public Map getNewRoots() { 72 return newRootsMap; 73 } 74 75 79 public void merge(TxnObjectGrouping oldGrouping) { 80 Assert.assertTrue(this.txID != ServerTransactionID.NULL_ID && oldGrouping.isActive()); 81 if (txns.size() >= oldGrouping.txns.size()) { 82 txns.putAll(oldGrouping.txns); 83 } else { 84 Map temp = txns; 85 txns = oldGrouping.txns; 86 txns.putAll(temp); 87 } 88 if (objects.size() >= oldGrouping.objects.size()) { 89 objects.putAll(oldGrouping.objects); 90 } else { 91 Map temp = objects; 92 objects = oldGrouping.objects; 93 objects.putAll(temp); 94 } 95 newRootsMap.putAll(oldGrouping.newRootsMap); 96 pendingApplys += oldGrouping.pendingApplys; 97 98 oldGrouping.txns = null; 100 oldGrouping.objects = null; 101 oldGrouping.isActive = false; 102 } 103 104 public boolean isActive() { 105 return isActive; 106 } 107 108 public boolean limitReached() { 109 return txns.size() > MAX_TXNS || objects.size() > MAX_OBJECTS; 110 } 111 112 public int hashCode() { 113 return txID.hashCode(); 114 } 115 116 public boolean equals(Object o) { 117 if (o instanceof TxnObjectGrouping) { 118 TxnObjectGrouping other = (TxnObjectGrouping) o; 119 return (txID.equals(other.txID)); 120 } 121 return false; 122 } 123 124 public Iterator getApplyPendingTxnsIterator() { 125 return new ApplyPendingTxnsIterator(); 126 } 127 128 public Collection getTxnIDs() { 129 return txns.keySet(); 130 } 131 132 public PrettyPrinter prettyPrint(PrettyPrinter out) { 133 out.println("TransactionGrouping@" + System.identityHashCode(this)); 134 out.indent().println("txnID: ").visit(txID).println(); 135 out.indent().println("txns: ").visit(txns).println(); 136 out.indent().println("objects: ").visit(objects.keySet()).println(); 137 out.indent().println("pendingApplys: " + pendingApplys).println(); 138 out.indent().println("newRootsMap: ").visit(newRootsMap).println(); 139 return out; 140 } 141 142 public String toString() { 143 StringBuffer out = new StringBuffer (); 144 out.append("TransactionGrouping@" + System.identityHashCode(this)).append("\n"); 145 out.append("\t").append("txnID: ").append(txID).append("\n"); 146 out.append("\t").append("txns: ").append(txns).append("\n"); 147 out.append("\t").append("objects: ").append(objects.keySet()).append("\n"); 148 out.append("\t").append("pendingApplys: ").append(pendingApplys).append("\n"); 149 out.append("\t").append("newRootsMap: ").append(newRootsMap).append("\n"); 150 return out.toString(); 151 } 152 153 public String shortDescription() { 154 return "TxnGrouping[txns = " + txns.size() + ", objects = " + objects.size() + ", pendingApplys = " + pendingApplys 155 + ", roots = " + newRootsMap.size() + "]"; 156 } 157 158 private final class ApplyPendingTxnsIterator implements Iterator { 159 160 int remaining = pendingApplys; 161 int save = pendingApplys; 162 Iterator pointer = txns.entrySet().iterator(); 163 164 public boolean hasNext() { 165 return (remaining > 0); 166 } 167 168 public Object next() { 169 if (remaining <= 0) { throw new NoSuchElementException (); } 170 if (save != pendingApplys) { throw new ConcurrentModificationException (); } 171 remaining--; 172 while (pointer.hasNext()) { 173 Map.Entry e = (Entry) pointer.next(); 174 if (e.getValue() == APPLY_PENDING) { return e.getKey(); } 175 } 176 throw new AssertionError ("Shouldnt reach here"); 177 } 178 179 public void remove() { 180 throw new UnsupportedOperationException (); 181 } 182 183 } 184 } | Popular Tags |