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.DatabaseException;
010: import com.sleepycat.je.Transaction;
011: import com.tc.io.serializer.api.StringIndex;
012: import com.tc.logging.TCLogger;
013: import com.tc.logging.TCLogging;
014: import com.tc.objectserver.persistence.api.ClassPersistor;
015: import com.tc.objectserver.persistence.api.ClientStatePersistor;
016: import com.tc.objectserver.persistence.api.ManagedObjectPersistor;
017: import com.tc.objectserver.persistence.api.PersistenceTransaction;
018: import com.tc.objectserver.persistence.api.PersistenceTransactionProvider;
019: import com.tc.objectserver.persistence.api.PersistentCollectionFactory;
020: import com.tc.objectserver.persistence.api.PersistentMapStore;
021: import com.tc.objectserver.persistence.api.Persistor;
022: import com.tc.objectserver.persistence.api.StringIndexPersistor;
023: import com.tc.objectserver.persistence.api.TransactionPersistor;
024: import com.tc.objectserver.persistence.impl.StringIndexImpl;
025: import com.tc.util.sequence.MutableSequence;
026:
027: import java.io.IOException;
028:
029: public class SleepycatPersistor implements Persistor {
030: private static final int DEFAULT_CAPACITY = 50000;
031:
032: private final StringIndexPersistor stringIndexPersistor;
033: private final StringIndex stringIndex;
034: private final ManagedObjectPersistorImpl managedObjectPersistor;
035: private final ClientStatePersistor clientStatePersistor;
036: private final TransactionPersistor transactionPerisistor;
037: private final MutableSequence globalTransactionIDSequence;
038: private final ClassPersistor classPersistor;
039: private final PersistenceTransactionProvider persistenceTransactionProvider;
040: private final DBEnvironment env;
041: private final SleepycatCollectionFactory sleepycatCollectionFactory;
042: private final PersistentMapStore clusterStateStore;
043:
044: private SleepycatCollectionsPersistor sleepycatCollectionsPersistor;
045:
046: public SleepycatPersistor(TCLogger logger, DBEnvironment env,
047: SerializationAdapterFactory serializationAdapterFactory)
048: throws TCDatabaseException {
049: DatabaseOpenResult result = env.open();
050: if (!result.isClean()) {
051: //
052: throw new DatabaseDirtyException(
053: "Attempt to open a dirty database. "
054: + "This may be because a previous instance of the server didn't exit cleanly."
055: + " Since the integrity of the data cannot be assured, "
056: + "the server is refusing to start."
057: + " Please remove the database files in the following directory and restart "
058: + "the server: " + env.getEnvironmentHome());
059: }
060:
061: CursorConfig dbCursorConfig = new CursorConfig();
062: dbCursorConfig.setReadCommitted(true);
063: CursorConfig rootDBCursorConfig = new CursorConfig();
064: rootDBCursorConfig.setReadCommitted(true);
065: CursorConfig stringIndexCursorConfig = new CursorConfig();
066: stringIndexCursorConfig.setReadCommitted(true);
067: this .env = env;
068: this .persistenceTransactionProvider = new SleepycatPersistenceTransactionProvider(
069: env.getEnvironment());
070: this .stringIndexPersistor = new SleepycatStringIndexPersistor(
071: persistenceTransactionProvider, env
072: .getStringIndexDatabase(),
073: stringIndexCursorConfig, env.getClassCatalogWrapper()
074: .getClassCatalog());
075: this .stringIndex = new StringIndexImpl(
076: this .stringIndexPersistor, DEFAULT_CAPACITY);
077: this .sleepycatCollectionFactory = new SleepycatCollectionFactory();
078: this .sleepycatCollectionsPersistor = new SleepycatCollectionsPersistor(
079: logger, env.getMapsDatabase(),
080: sleepycatCollectionFactory);
081: this .managedObjectPersistor = new ManagedObjectPersistorImpl(
082: logger, env.getClassCatalogWrapper().getClassCatalog(),
083: serializationAdapterFactory, env.getObjectDatabase(),
084: env.getOidDatabase(), dbCursorConfig,
085: new SleepycatSequence(
086: this .persistenceTransactionProvider, logger, 1,
087: 1000, env.getObjectIDDB()), env
088: .getRootDatabase(), rootDBCursorConfig,
089: this .persistenceTransactionProvider,
090: this .sleepycatCollectionsPersistor, env
091: .isParanoidMode());
092: this .clientStatePersistor = new ClientStatePersistorImpl(
093: logger, this .persistenceTransactionProvider,
094: new SleepycatSequence(
095: this .persistenceTransactionProvider, logger, 1,
096: 0, env.getClientIDDatabase()), env
097: .getClientStateDatabase());
098: this .transactionPerisistor = new TransactionPersistorImpl(env
099: .getTransactionDatabase(),
100: this .persistenceTransactionProvider);
101: this .globalTransactionIDSequence = new SleepycatSequence(
102: this .persistenceTransactionProvider, logger, 1, 1, env
103: .getTransactionSequenceDatabase());
104: this .classPersistor = new ClassPersistorImpl(
105: this .persistenceTransactionProvider, logger, env
106: .getClassDatabase());
107: this .clusterStateStore = new SleepycatMapStore(
108: this .persistenceTransactionProvider, logger, env
109: .getClusterStateStoreDatabase());
110: }
111:
112: public StringIndex getStringIndex() {
113: return this .stringIndex;
114: }
115:
116: public PersistenceTransactionProvider getPersistenceTransactionProvider() {
117: return this .persistenceTransactionProvider;
118: }
119:
120: public MutableSequence getGlobalTransactionIDSequence() {
121: return this .globalTransactionIDSequence;
122: }
123:
124: public TransactionPersistor getTransactionPersistor() {
125: return this .transactionPerisistor;
126: }
127:
128: public ManagedObjectPersistor getManagedObjectPersistor() {
129: return this .managedObjectPersistor;
130: }
131:
132: public ClientStatePersistor getClientStatePersistor() {
133: return this .clientStatePersistor;
134: }
135:
136: public ClassPersistor getClassPersistor() {
137: return this .classPersistor;
138: }
139:
140: public PersistentCollectionFactory getPersistentCollectionFactory() {
141: return this .sleepycatCollectionFactory;
142: }
143:
144: public PersistentMapStore getClusterStateStore() {
145: return clusterStateStore;
146: }
147:
148: public void close() {
149: try {
150: env.close();
151: } catch (TCDatabaseException e) {
152: throw new DBException(e);
153: }
154: }
155:
156: public boolean isOpen() {
157: return env.isOpen();
158: }
159:
160: static class SleepycatPersistorBase {
161:
162: private static final TCLogger logger = TCLogging
163: .getLogger(SleepycatPersistorBase.class);
164:
165: protected Transaction pt2nt(PersistenceTransaction tx) {
166: // XXX: Yuck.
167: return (tx instanceof TransactionWrapper) ? ((TransactionWrapper) tx)
168: .getTransaction()
169: : null;
170: }
171:
172: protected void abortOnError(PersistenceTransaction ptx) {
173: abortOnError(pt2nt(ptx));
174: }
175:
176: protected void abortOnError(Transaction tx) {
177: try {
178: if (tx != null)
179: tx.abort();
180: } catch (DatabaseException e) {
181: // This doesnt throw an exception as we dont want to create a Red herring.
182: logger.error("Error on abortOnError", e);
183: }
184:
185: }
186:
187: protected void abortOnError(Cursor cursor,
188: PersistenceTransaction ptx) {
189: abortOnError(cursor, pt2nt(ptx));
190: }
191:
192: protected void abortOnError(Cursor cursor, Transaction tx) {
193: if (cursor != null) {
194: try {
195: cursor.close();
196: } catch (DatabaseException e) {
197: // This doesnt throw an exception as we dont want to create a Red herring.
198: logger.error("Error on abortOnError", e);
199: }
200: }
201: abortOnError(tx);
202: }
203:
204: }
205:
206: /**
207: * This is only exposed for tests.
208: */
209: public SerializationAdapter getSerializationAdapter()
210: throws IOException {
211: return this .managedObjectPersistor.getSerializationAdapter();
212: }
213:
214: /**
215: * This is only exposed for tests.
216: */
217: public SleepycatCollectionsPersistor getCollectionsPersistor() {
218: return sleepycatCollectionsPersistor;
219: }
220:
221: }
|