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.sleepycat;
006:
007: import com.sleepycat.je.Cursor;
008: import com.sleepycat.je.CursorConfig;
009: import com.sleepycat.je.Database;
010: import com.sleepycat.je.DatabaseEntry;
011: import com.sleepycat.je.DatabaseException;
012: import com.sleepycat.je.LockMode;
013: import com.sleepycat.je.OperationStatus;
014: import com.tc.object.gtx.GlobalTransactionID;
015: import com.tc.object.tx.ServerTransactionID;
016: import com.tc.objectserver.gtx.GlobalTransactionDescriptor;
017: import com.tc.objectserver.persistence.api.PersistenceTransaction;
018: import com.tc.objectserver.persistence.api.PersistenceTransactionProvider;
019: import com.tc.objectserver.persistence.api.TransactionPersistor;
020: import com.tc.objectserver.persistence.sleepycat.SleepycatPersistor.SleepycatPersistorBase;
021: import com.tc.util.Conversion;
022:
023: import java.util.Collection;
024: import java.util.HashSet;
025: import java.util.Iterator;
026:
027: class TransactionPersistorImpl extends SleepycatPersistorBase implements
028: TransactionPersistor {
029:
030: private final Database db;
031: private final CursorConfig cursorConfig;
032: private final PersistenceTransactionProvider ptp;
033:
034: public TransactionPersistorImpl(Database db,
035: PersistenceTransactionProvider ptp) {
036: this .db = db;
037: this .ptp = ptp;
038: this .cursorConfig = new CursorConfig();
039: this .cursorConfig.setReadCommitted(true);
040: }
041:
042: public Collection loadAllGlobalTransactionDescriptors() {
043: Cursor cursor = null;
044: PersistenceTransaction tx = null;
045: try {
046: Collection rv = new HashSet();
047: tx = ptp.newTransaction();
048: cursor = this .db.openCursor(pt2nt(tx), cursorConfig);
049: DatabaseEntry key = new DatabaseEntry();
050: DatabaseEntry value = new DatabaseEntry();
051: while (OperationStatus.SUCCESS.equals(cursor.getNext(key,
052: value, LockMode.DEFAULT))) {
053: rv.add(new GlobalTransactionDescriptor(
054: bytes2ServerTxnID(key.getData()),
055: bytes2GlobalTxnID(value.getData())));
056: }
057: cursor.close();
058: tx.commit();
059: return rv;
060: } catch (DatabaseException e) {
061: abortOnError(cursor, tx);
062: throw new DBException(e);
063: }
064: }
065:
066: public void saveGlobalTransactionDescriptor(
067: PersistenceTransaction tx, GlobalTransactionDescriptor gtx) {
068: DatabaseEntry key = new DatabaseEntry();
069: DatabaseEntry value = new DatabaseEntry();
070: key.setData(serverTxnID2Bytes(gtx.getServerTransactionID()));
071: value.setData(globalTxnID2Bytes(gtx.getGlobalTransactionID()));
072: try {
073: this .db.put(pt2nt(tx), key, value);
074: } catch (DatabaseException e) {
075: throw new DBException(e);
076: }
077: }
078:
079: private GlobalTransactionID bytes2GlobalTxnID(byte[] data) {
080: return new GlobalTransactionID(Conversion.bytes2Long(data));
081: }
082:
083: private byte[] globalTxnID2Bytes(
084: GlobalTransactionID globalTransactionID) {
085: return Conversion.long2Bytes(globalTransactionID.toLong());
086: }
087:
088: private byte[] serverTxnID2Bytes(
089: ServerTransactionID serverTransactionID) {
090: return serverTransactionID.getBytes();
091: }
092:
093: private ServerTransactionID bytes2ServerTxnID(byte[] data) {
094: return ServerTransactionID.createFrom(data);
095: }
096:
097: public void deleteAllGlobalTransactionDescriptors(
098: PersistenceTransaction tx, Collection toDelete) {
099: DatabaseEntry key = new DatabaseEntry();
100: for (Iterator i = toDelete.iterator(); i.hasNext();) {
101: ServerTransactionID stxID = ((GlobalTransactionDescriptor) i
102: .next()).getServerTransactionID();
103: key.setData(serverTxnID2Bytes(stxID));
104: try {
105: db.delete(pt2nt(tx), key);
106: } catch (DatabaseException e) {
107: throw new DBException(e);
108: }
109: }
110: }
111: }
|