01: /*
02: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
03: */
04: package com.tc.objectserver.persistence.sleepycat;
05:
06: import EDU.oswego.cs.dl.util.concurrent.SynchronizedBoolean;
07:
08: import com.sleepycat.bind.serial.ClassCatalog;
09: import com.sleepycat.bind.serial.SerialBinding;
10: import com.sleepycat.je.Cursor;
11: import com.sleepycat.je.CursorConfig;
12: import com.sleepycat.je.Database;
13: import com.sleepycat.je.DatabaseEntry;
14: import com.sleepycat.je.LockMode;
15: import com.sleepycat.je.OperationStatus;
16: import com.tc.objectserver.persistence.api.PersistenceTransaction;
17: import com.tc.objectserver.persistence.api.PersistenceTransactionProvider;
18: import com.tc.objectserver.persistence.api.StringIndexPersistor;
19: import com.tc.objectserver.persistence.sleepycat.SleepycatPersistor.SleepycatPersistorBase;
20: import com.tc.util.Conversion;
21:
22: import gnu.trove.TLongObjectHashMap;
23:
24: public final class SleepycatStringIndexPersistor extends
25: SleepycatPersistorBase implements StringIndexPersistor {
26:
27: private final PersistenceTransactionProvider ptp;
28: private final Database stringIndexDatabase;
29: private final CursorConfig stringIndexCursorConfig;
30: private final SerialBinding serialBinding;
31: private final SynchronizedBoolean initialized = new SynchronizedBoolean(
32: false);
33:
34: public SleepycatStringIndexPersistor(
35: PersistenceTransactionProvider ptp,
36: Database stringIndexDatabase,
37: CursorConfig stringIndexCursorConfig,
38: ClassCatalog classCatalog) {
39: this .ptp = ptp;
40: this .stringIndexDatabase = stringIndexDatabase;
41: this .stringIndexCursorConfig = stringIndexCursorConfig;
42: this .serialBinding = new SerialBinding(classCatalog,
43: String.class);
44: }
45:
46: public TLongObjectHashMap loadMappingsInto(TLongObjectHashMap target) {
47: if (initialized.set(true))
48: throw new AssertionError("Attempt to use more than once.");
49: Cursor cursor = null;
50: PersistenceTransaction tx = null;
51: try {
52: tx = ptp.newTransaction();
53: DatabaseEntry key = new DatabaseEntry(), value = new DatabaseEntry();
54: cursor = stringIndexDatabase.openCursor(pt2nt(tx),
55: stringIndexCursorConfig);
56: while (OperationStatus.SUCCESS.equals(cursor.getNext(key,
57: value, LockMode.DEFAULT))) {
58: target.put(Conversion.bytes2Long(key.getData()),
59: bytes2String(value));
60: }
61: cursor.close();
62: tx.commit();
63: } catch (Throwable t) {
64: abortOnError(cursor, tx);
65: throw new DBException(t);
66: }
67: return target;
68: }
69:
70: public void saveMapping(long index, String string) {
71: PersistenceTransaction tx = null;
72: try {
73: tx = ptp.newTransaction();
74: DatabaseEntry key = new DatabaseEntry(), value = new DatabaseEntry();
75: key.setData(Conversion.long2Bytes(index));
76: string2Bytes(string, value);
77: stringIndexDatabase.put(pt2nt(tx), key, value);
78: tx.commit();
79: } catch (Throwable t) {
80: abortOnError(tx);
81: throw new DBException(t);
82: }
83: }
84:
85: private String bytes2String(DatabaseEntry entry) {
86: return (String) serialBinding.entryToObject(entry);
87: }
88:
89: private void string2Bytes(String string, DatabaseEntry entry) {
90: serialBinding.objectToEntry(string, entry);
91: }
92:
93: }
|