KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > objectserver > persistence > sleepycat > ClientStatePersistorImpl


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
3  * notice. All rights reserved.
4  */

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 JavaDoc;
26 import java.util.Set JavaDoc;
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 JavaDoc loadClientIDs() {
67     Set JavaDoc set = new HashSet JavaDoc();
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     // someday, maybe we'll need to save more state, but for now, this stops
86
// from overwriting the sequence.
87
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