001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.objectserver.persistence.impl;
006:
007: import com.tc.exception.ImplementMe;
008: import com.tc.exception.TCRuntimeException;
009: import com.tc.net.groups.NodeID;
010: import com.tc.object.gtx.GlobalTransactionID;
011: import com.tc.object.tx.ServerTransactionID;
012: import com.tc.objectserver.gtx.GlobalTransactionDescriptor;
013: import com.tc.objectserver.gtx.TransactionCommittedError;
014: import com.tc.objectserver.persistence.api.PersistenceTransaction;
015: import com.tc.objectserver.persistence.api.TransactionStore;
016: import com.tc.util.concurrent.NoExceptionLinkedQueue;
017:
018: import java.util.Collection;
019: import java.util.HashMap;
020: import java.util.Iterator;
021: import java.util.Map;
022: import java.util.Set;
023: import java.util.SortedSet;
024: import java.util.TreeSet;
025: import java.util.Map.Entry;
026:
027: public class TestTransactionStore implements TransactionStore {
028:
029: public final NoExceptionLinkedQueue leastContextQueue = new NoExceptionLinkedQueue();
030: public final NoExceptionLinkedQueue commitContextQueue = new NoExceptionLinkedQueue();
031: public final NoExceptionLinkedQueue loadContextQueue = new NoExceptionLinkedQueue();
032: public final NoExceptionLinkedQueue nextTransactionIDContextQueue = new NoExceptionLinkedQueue();
033:
034: private final Map volatileMap = new HashMap();
035: private final SortedSet ids = new TreeSet();
036: private final Map durableMap = new HashMap();
037: public long idSequence = 1;
038:
039: public void restart() throws Exception {
040: volatileMap.clear();
041: ids.clear();
042: volatileMap.putAll(durableMap);
043: for (Iterator i = volatileMap.values().iterator(); i.hasNext();) {
044: GlobalTransactionDescriptor gdesc = (GlobalTransactionDescriptor) i
045: .next();
046: GlobalTransactionID gid = gdesc.getGlobalTransactionID();
047: ids.add(gid);
048: }
049: }
050:
051: public GlobalTransactionDescriptor getOrCreateTransactionDescriptor(
052: ServerTransactionID stxid) {
053: GlobalTransactionDescriptor rv = (GlobalTransactionDescriptor) volatileMap
054: .get(stxid);
055: if (rv == null) {
056: nextTransactionIDContextQueue.put(stxid);
057: rv = new GlobalTransactionDescriptor(stxid,
058: new GlobalTransactionID(idSequence++));
059: basicPut(volatileMap, rv);
060: }
061: return rv;
062: }
063:
064: private void basicPut(Map map, GlobalTransactionDescriptor txID) {
065: map.put(txID.getServerTransactionID(), txID);
066: }
067:
068: public void commitTransactionDescriptor(
069: PersistenceTransaction transaction,
070: ServerTransactionID stxID) {
071: GlobalTransactionDescriptor txID = getTransactionDescriptor(stxID);
072: if (txID.isCommitted()) {
073: throw new TransactionCommittedError("Already committed : "
074: + txID);
075: }
076: try {
077: commitContextQueue.put(new Object[] { transaction, txID });
078: if (!volatileMap.containsValue(txID))
079: throw new AssertionError();
080: basicPut(durableMap, txID);
081: txID.commitComplete();
082: } catch (Exception e) {
083: throw new TCRuntimeException(e);
084: }
085: }
086:
087: public GlobalTransactionDescriptor getTransactionDescriptor(
088: ServerTransactionID stxid) {
089: try {
090: loadContextQueue.put(stxid);
091: return (GlobalTransactionDescriptor) volatileMap.get(stxid);
092: } catch (Exception e) {
093: throw new TCRuntimeException(e);
094: }
095: }
096:
097: public GlobalTransactionID getLeastGlobalTransactionID() {
098: leastContextQueue.put(new Object());
099: return (GlobalTransactionID) ids.first();
100: }
101:
102: public void clearCommitedTransactionsBelowLowWaterMark(
103: PersistenceTransaction tx, ServerTransactionID lowWaterMark) {
104: for (Iterator iter = volatileMap.entrySet().iterator(); iter
105: .hasNext();) {
106: Entry e = (Entry) iter.next();
107: ServerTransactionID sid = (ServerTransactionID) e.getKey();
108: if (sid.getSourceID().equals(lowWaterMark.getSourceID())) {
109: GlobalTransactionDescriptor gdesc = (GlobalTransactionDescriptor) e
110: .getValue();
111: if (gdesc.getClientTransactionID().toLong() < lowWaterMark
112: .getClientTransactionID().toLong()) {
113: ids.remove(gdesc.getGlobalTransactionID());
114: durableMap.remove(sid);
115: }
116: }
117: }
118: }
119:
120: public void shutdownNode(PersistenceTransaction transaction,
121: NodeID nid) {
122: throw new ImplementMe();
123: }
124:
125: public void createGlobalTransactionDescIfNeeded(
126: ServerTransactionID stxnID,
127: GlobalTransactionID globalTransactionID) {
128: GlobalTransactionDescriptor rv = new GlobalTransactionDescriptor(
129: stxnID, globalTransactionID);
130: basicPut(volatileMap, rv);
131: }
132:
133: public void shutdownAllClientsExcept(PersistenceTransaction tx,
134: Set cids) {
135: throw new ImplementMe();
136: }
137:
138: public void commitAllTransactionDescriptor(
139: PersistenceTransaction persistenceTransaction,
140: Collection stxIDs) {
141: for (Iterator i = stxIDs.iterator(); i.hasNext();) {
142: ServerTransactionID sid = (ServerTransactionID) i.next();
143: commitTransactionDescriptor(persistenceTransaction, sid);
144: }
145: }
146:
147: public void clearCommitedTransactionsBelowLowWaterMark(
148: PersistenceTransaction tx, GlobalTransactionID lowWaterMark) {
149: throw new ImplementMe();
150: }
151:
152: }
|