1 5 package com.tc.objectserver.persistence.sleepycat; 6 7 import com.sleepycat.je.Cursor; 8 import com.sleepycat.je.CursorConfig; 9 import com.sleepycat.je.Database; 10 import com.sleepycat.je.DatabaseEntry; 11 import com.sleepycat.je.DatabaseException; 12 import com.sleepycat.je.LockMode; 13 import com.sleepycat.je.OperationStatus; 14 import com.sleepycat.je.Transaction; 15 import com.tc.logging.TCLogger; 16 import com.tc.net.protocol.tcm.ChannelID; 17 import com.tc.objectserver.persistence.api.ClientStatePersistor; 18 import com.tc.objectserver.persistence.api.PersistenceTransaction; 19 import com.tc.objectserver.persistence.api.PersistenceTransactionProvider; 20 import com.tc.objectserver.persistence.api.PersistentSequence; 21 import com.tc.objectserver.persistence.impl.ClientNotFoundException; 22 import com.tc.objectserver.persistence.sleepycat.SleepycatPersistor.SleepycatPersistorBase; 23 import com.tc.util.Conversion; 24 25 import java.util.HashSet ; 26 import java.util.Set ; 27 28 class ClientStatePersistorImpl extends SleepycatPersistorBase implements ClientStatePersistor { 29 30 private final Database db; 31 private final CursorConfig cursorConfig; 32 private final DatabaseEntry key; 33 private final DatabaseEntry value; 34 private final PersistenceTransactionProvider ptp; 35 private final TCLogger logger; 36 private final PersistentSequence connectionIDSequence; 37 38 ClientStatePersistorImpl(final TCLogger logger, final PersistenceTransactionProvider ptp, 39 final PersistentSequence connectionIDSequence, final Database db) { 40 this.logger = logger; 41 this.ptp = ptp; 42 this.cursorConfig = new CursorConfig(); 43 this.cursorConfig.setReadCommitted(true); 44 this.db = db; 45 this.key = new DatabaseEntry(); 46 this.value = new DatabaseEntry(); 47 this.connectionIDSequence = connectionIDSequence; 48 } 49 50 public PersistentSequence getConnectionIDSequence() { 51 return this.connectionIDSequence; 52 } 53 54 public synchronized boolean containsClient(ChannelID id) { 55 setKey(id); 56 try { 57 PersistenceTransaction tx = ptp.newTransaction(); 58 OperationStatus status = db.get(pt2nt(tx), key, value, LockMode.DEFAULT); 59 tx.commit(); 60 return OperationStatus.SUCCESS.equals(status); 61 } catch (DatabaseException e) { 62 throw new DBException(e); 63 } 64 } 65 66 public synchronized Set loadClientIDs() { 67 Set set = new HashSet (); 68 Cursor cursor; 69 try { 70 PersistenceTransaction tx = ptp.newTransaction(); 71 cursor = db.openCursor(pt2nt(tx), cursorConfig); 72 while (OperationStatus.SUCCESS.equals(cursor.getNext(key, value, LockMode.DEFAULT))) { 73 set.add(new ChannelID(Conversion.bytes2Long(key.getData()))); 74 } 75 cursor.close(); 76 tx.commit(); 77 } catch (DatabaseException e) { 78 e.printStackTrace(); 79 throw new DBException(e); 80 } 81 return set; 82 } 83 84 public synchronized void saveClientState(ChannelID clientID) { 85 if (containsClient(clientID)) return; 88 basicSave(clientID.toLong()); 89 logger.debug("Saved client state for " + clientID); 90 } 91 92 private void basicSave(long clientID) { 93 94 setKey(clientID); 95 value.setData(Conversion.long2Bytes(0)); 96 try { 97 PersistenceTransaction tx = ptp.newTransaction(); 98 Transaction realTx = pt2nt(tx); 99 OperationStatus status = db.put(realTx, key, value); 100 if (!OperationStatus.SUCCESS.equals(status)) { 101 realTx.abort(); 102 throw new DBException("Unable to save client state: ChannelID " + clientID + "; status: " + status); 103 } 104 tx.commit(); 105 } catch (DatabaseException e) { 106 throw new DBException(e); 107 } 108 } 109 110 public synchronized void deleteClientState(ChannelID id) throws ClientNotFoundException { 111 setKey(id); 112 try { 113 PersistenceTransaction tx = ptp.newTransaction(); 114 Transaction realTx = pt2nt(tx); 115 116 OperationStatus status = db.delete(realTx, key); 117 if (OperationStatus.NOTFOUND.equals(status)) { 118 realTx.abort(); 119 throw new ClientNotFoundException("Client not found: " + id); 120 } 121 if (!OperationStatus.SUCCESS.equals(status)) { 122 realTx.abort(); 123 throw new DBException("Unable to delete client state: " + id + "; status: " + status); 124 } 125 126 tx.commit(); 127 logger.debug("Deleted client state for " + id); 128 } catch (DatabaseException e) { 129 throw new DBException(e); 130 } 131 } 132 133 private void setKey(ChannelID id) { 134 setKey(id.toLong()); 135 } 136 137 private void setKey(long id) { 138 setData(id, key); 139 } 140 141 private void setData(long id, DatabaseEntry entry) { 142 entry.setData(Conversion.long2Bytes(id)); 143 } 144 145 } | Popular Tags |