]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
2 | // This source code is licensed under both the GPLv2 (found in the | |
3 | // COPYING file in the root directory) and Apache 2.0 License | |
4 | // (found in the LICENSE.Apache file in the root directory). | |
5 | ||
6 | package org.rocksdb; | |
7 | ||
8 | import java.util.List; | |
9 | ||
10 | /** | |
11 | * Database with Transaction support. | |
12 | */ | |
13 | public class OptimisticTransactionDB extends RocksDB | |
14 | implements TransactionalDB<OptimisticTransactionOptions> { | |
15 | ||
16 | /** | |
17 | * Private constructor. | |
18 | * | |
19 | * @param nativeHandle The native handle of the C++ OptimisticTransactionDB | |
20 | * object | |
21 | */ | |
22 | private OptimisticTransactionDB(final long nativeHandle) { | |
23 | super(nativeHandle); | |
24 | } | |
25 | ||
26 | /** | |
27 | * Open an OptimisticTransactionDB similar to | |
28 | * {@link RocksDB#open(Options, String)}. | |
29 | * | |
30 | * @param options {@link org.rocksdb.Options} instance. | |
31 | * @param path the path to the rocksdb. | |
32 | * | |
33 | * @return a {@link OptimisticTransactionDB} instance on success, null if the | |
34 | * specified {@link OptimisticTransactionDB} can not be opened. | |
35 | * | |
36 | * @throws RocksDBException if an error occurs whilst opening the database. | |
37 | */ | |
38 | public static OptimisticTransactionDB open(final Options options, | |
39 | final String path) throws RocksDBException { | |
40 | final OptimisticTransactionDB otdb = new OptimisticTransactionDB(open( | |
41 | options.nativeHandle_, path)); | |
42 | ||
43 | // when non-default Options is used, keeping an Options reference | |
44 | // in RocksDB can prevent Java to GC during the life-time of | |
45 | // the currently-created RocksDB. | |
46 | otdb.storeOptionsInstance(options); | |
47 | ||
48 | return otdb; | |
49 | } | |
50 | ||
51 | /** | |
52 | * Open an OptimisticTransactionDB similar to | |
53 | * {@link RocksDB#open(DBOptions, String, List, List)}. | |
54 | * | |
55 | * @param dbOptions {@link org.rocksdb.DBOptions} instance. | |
56 | * @param path the path to the rocksdb. | |
57 | * @param columnFamilyDescriptors list of column family descriptors | |
58 | * @param columnFamilyHandles will be filled with ColumnFamilyHandle instances | |
59 | * | |
60 | * @return a {@link OptimisticTransactionDB} instance on success, null if the | |
61 | * specified {@link OptimisticTransactionDB} can not be opened. | |
62 | * | |
63 | * @throws RocksDBException if an error occurs whilst opening the database. | |
64 | */ | |
65 | public static OptimisticTransactionDB open(final DBOptions dbOptions, | |
66 | final String path, | |
67 | final List<ColumnFamilyDescriptor> columnFamilyDescriptors, | |
68 | final List<ColumnFamilyHandle> columnFamilyHandles) | |
69 | throws RocksDBException { | |
70 | ||
71 | final byte[][] cfNames = new byte[columnFamilyDescriptors.size()][]; | |
72 | final long[] cfOptionHandles = new long[columnFamilyDescriptors.size()]; | |
73 | for (int i = 0; i < columnFamilyDescriptors.size(); i++) { | |
74 | final ColumnFamilyDescriptor cfDescriptor = columnFamilyDescriptors | |
75 | .get(i); | |
f67539c2 TL |
76 | cfNames[i] = cfDescriptor.getName(); |
77 | cfOptionHandles[i] = cfDescriptor.getOptions().nativeHandle_; | |
11fdf7f2 TL |
78 | } |
79 | ||
80 | final long[] handles = open(dbOptions.nativeHandle_, path, cfNames, | |
81 | cfOptionHandles); | |
82 | final OptimisticTransactionDB otdb = | |
83 | new OptimisticTransactionDB(handles[0]); | |
84 | ||
85 | // when non-default Options is used, keeping an Options reference | |
86 | // in RocksDB can prevent Java to GC during the life-time of | |
87 | // the currently-created RocksDB. | |
88 | otdb.storeOptionsInstance(dbOptions); | |
89 | ||
90 | for (int i = 1; i < handles.length; i++) { | |
91 | columnFamilyHandles.add(new ColumnFamilyHandle(otdb, handles[i])); | |
92 | } | |
93 | ||
94 | return otdb; | |
95 | } | |
96 | ||
494da23a TL |
97 | |
98 | /** | |
99 | * This is similar to {@link #close()} except that it | |
100 | * throws an exception if any error occurs. | |
101 | * | |
102 | * This will not fsync the WAL files. | |
103 | * If syncing is required, the caller must first call {@link #syncWal()} | |
104 | * or {@link #write(WriteOptions, WriteBatch)} using an empty write batch | |
105 | * with {@link WriteOptions#setSync(boolean)} set to true. | |
106 | * | |
107 | * See also {@link #close()}. | |
108 | * | |
109 | * @throws RocksDBException if an error occurs whilst closing. | |
110 | */ | |
111 | public void closeE() throws RocksDBException { | |
112 | if (owningHandle_.compareAndSet(true, false)) { | |
113 | try { | |
114 | closeDatabase(nativeHandle_); | |
115 | } finally { | |
116 | disposeInternal(); | |
117 | } | |
118 | } | |
119 | } | |
120 | ||
121 | /** | |
122 | * This is similar to {@link #closeE()} except that it | |
123 | * silently ignores any errors. | |
124 | * | |
125 | * This will not fsync the WAL files. | |
126 | * If syncing is required, the caller must first call {@link #syncWal()} | |
127 | * or {@link #write(WriteOptions, WriteBatch)} using an empty write batch | |
128 | * with {@link WriteOptions#setSync(boolean)} set to true. | |
129 | * | |
130 | * See also {@link #close()}. | |
131 | */ | |
132 | @Override | |
133 | public void close() { | |
134 | if (owningHandle_.compareAndSet(true, false)) { | |
135 | try { | |
136 | closeDatabase(nativeHandle_); | |
137 | } catch (final RocksDBException e) { | |
138 | // silently ignore the error report | |
139 | } finally { | |
140 | disposeInternal(); | |
141 | } | |
142 | } | |
143 | } | |
144 | ||
11fdf7f2 TL |
145 | @Override |
146 | public Transaction beginTransaction(final WriteOptions writeOptions) { | |
147 | return new Transaction(this, beginTransaction(nativeHandle_, | |
148 | writeOptions.nativeHandle_)); | |
149 | } | |
150 | ||
151 | @Override | |
152 | public Transaction beginTransaction(final WriteOptions writeOptions, | |
153 | final OptimisticTransactionOptions optimisticTransactionOptions) { | |
154 | return new Transaction(this, beginTransaction(nativeHandle_, | |
155 | writeOptions.nativeHandle_, | |
156 | optimisticTransactionOptions.nativeHandle_)); | |
157 | } | |
158 | ||
159 | // TODO(AR) consider having beingTransaction(... oldTransaction) set a | |
160 | // reference count inside Transaction, so that we can always call | |
161 | // Transaction#close but the object is only disposed when there are as many | |
162 | // closes as beginTransaction. Makes the try-with-resources paradigm easier for | |
163 | // java developers | |
164 | ||
165 | @Override | |
166 | public Transaction beginTransaction(final WriteOptions writeOptions, | |
167 | final Transaction oldTransaction) { | |
168 | final long jtxn_handle = beginTransaction_withOld(nativeHandle_, | |
169 | writeOptions.nativeHandle_, oldTransaction.nativeHandle_); | |
170 | ||
171 | // RocksJava relies on the assumption that | |
172 | // we do not allocate a new Transaction object | |
173 | // when providing an old_txn | |
174 | assert(jtxn_handle == oldTransaction.nativeHandle_); | |
175 | ||
176 | return oldTransaction; | |
177 | } | |
178 | ||
179 | @Override | |
180 | public Transaction beginTransaction(final WriteOptions writeOptions, | |
181 | final OptimisticTransactionOptions optimisticTransactionOptions, | |
182 | final Transaction oldTransaction) { | |
183 | final long jtxn_handle = beginTransaction_withOld(nativeHandle_, | |
184 | writeOptions.nativeHandle_, optimisticTransactionOptions.nativeHandle_, | |
185 | oldTransaction.nativeHandle_); | |
186 | ||
187 | // RocksJava relies on the assumption that | |
188 | // we do not allocate a new Transaction object | |
189 | // when providing an old_txn | |
190 | assert(jtxn_handle == oldTransaction.nativeHandle_); | |
191 | ||
192 | return oldTransaction; | |
193 | } | |
194 | ||
195 | /** | |
196 | * Get the underlying database that was opened. | |
197 | * | |
198 | * @return The underlying database that was opened. | |
199 | */ | |
200 | public RocksDB getBaseDB() { | |
201 | final RocksDB db = new RocksDB(getBaseDB(nativeHandle_)); | |
202 | db.disOwnNativeHandle(); | |
203 | return db; | |
204 | } | |
205 | ||
494da23a TL |
206 | @Override protected final native void disposeInternal(final long handle); |
207 | ||
11fdf7f2 TL |
208 | protected static native long open(final long optionsHandle, |
209 | final String path) throws RocksDBException; | |
210 | protected static native long[] open(final long handle, final String path, | |
211 | final byte[][] columnFamilyNames, final long[] columnFamilyOptions); | |
494da23a TL |
212 | private native static void closeDatabase(final long handle) |
213 | throws RocksDBException; | |
11fdf7f2 TL |
214 | private native long beginTransaction(final long handle, |
215 | final long writeOptionsHandle); | |
216 | private native long beginTransaction(final long handle, | |
217 | final long writeOptionsHandle, | |
218 | final long optimisticTransactionOptionsHandle); | |
219 | private native long beginTransaction_withOld(final long handle, | |
220 | final long writeOptionsHandle, final long oldTransactionHandle); | |
221 | private native long beginTransaction_withOld(final long handle, | |
222 | final long writeOptionsHandle, | |
223 | final long optimisticTransactionOptionsHandle, | |
224 | final long oldTransactionHandle); | |
225 | private native long getBaseDB(final long handle); | |
11fdf7f2 | 226 | } |