]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/java/src/main/java/org/rocksdb/RocksDB.java
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / rocksdb / java / src / main / java / org / rocksdb / RocksDB.java
CommitLineData
7c673cae 1// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
11fdf7f2
TL
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).
7c673cae
FG
5
6package org.rocksdb;
7
1e59de90
TL
8import static java.nio.charset.StandardCharsets.UTF_8;
9
7c673cae 10import java.io.IOException;
f67539c2
TL
11import java.nio.ByteBuffer;
12import java.util.ArrayList;
13import java.util.Arrays;
f67539c2
TL
14import java.util.List;
15import java.util.Map;
7c673cae 16import java.util.concurrent.atomic.AtomicReference;
7c673cae
FG
17import org.rocksdb.util.Environment;
18
19/**
20 * A RocksDB is a persistent ordered map from keys to values. It is safe for
21 * concurrent access from multiple threads without any external synchronization.
22 * All methods of this class could potentially throw RocksDBException, which
23 * indicates sth wrong at the RocksDB library side and the call failed.
24 */
25public class RocksDB extends RocksObject {
1e59de90 26 public static final byte[] DEFAULT_COLUMN_FAMILY = "default".getBytes(UTF_8);
7c673cae
FG
27 public static final int NOT_FOUND = -1;
28
29 private enum LibraryState {
30 NOT_LOADED,
31 LOADING,
32 LOADED
33 }
34
1e59de90
TL
35 private static final AtomicReference<LibraryState> libraryLoaded =
36 new AtomicReference<>(LibraryState.NOT_LOADED);
7c673cae
FG
37
38 static {
39 RocksDB.loadLibrary();
40 }
41
1e59de90 42 private final List<ColumnFamilyHandle> ownedColumnFamilyHandles = new ArrayList<>();
20effc67 43
7c673cae
FG
44 /**
45 * Loads the necessary library files.
46 * Calling this method twice will have no effect.
47 * By default the method extracts the shared library for loading at
48 * java.io.tmpdir, however, you can override this temporary location by
49 * setting the environment variable ROCKSDB_SHAREDLIB_DIR.
50 */
51 public static void loadLibrary() {
52 if (libraryLoaded.get() == LibraryState.LOADED) {
53 return;
54 }
55
56 if (libraryLoaded.compareAndSet(LibraryState.NOT_LOADED,
57 LibraryState.LOADING)) {
58 final String tmpDir = System.getenv("ROCKSDB_SHAREDLIB_DIR");
59 // loading possibly necessary libraries.
60 for (final CompressionType compressionType : CompressionType.values()) {
61 try {
62 if (compressionType.getLibraryName() != null) {
63 System.loadLibrary(compressionType.getLibraryName());
64 }
20effc67 65 } catch (final UnsatisfiedLinkError e) {
7c673cae
FG
66 // since it may be optional, we ignore its loading failure here.
67 }
68 }
69 try {
70 NativeLibraryLoader.getInstance().loadLibrary(tmpDir);
20effc67 71 } catch (final IOException e) {
7c673cae 72 libraryLoaded.set(LibraryState.NOT_LOADED);
494da23a
TL
73 throw new RuntimeException("Unable to load the RocksDB shared library",
74 e);
7c673cae
FG
75 }
76
20effc67
TL
77 final int encodedVersion = version();
78 version = Version.fromEncodedVersion(encodedVersion);
79
7c673cae
FG
80 libraryLoaded.set(LibraryState.LOADED);
81 return;
82 }
83
84 while (libraryLoaded.get() == LibraryState.LOADING) {
85 try {
86 Thread.sleep(10);
87 } catch(final InterruptedException e) {
88 //ignore
89 }
90 }
91 }
92
93 /**
94 * Tries to load the necessary library files from the given list of
95 * directories.
96 *
97 * @param paths a list of strings where each describes a directory
98 * of a library.
99 */
100 public static void loadLibrary(final List<String> paths) {
101 if (libraryLoaded.get() == LibraryState.LOADED) {
102 return;
103 }
104
105 if (libraryLoaded.compareAndSet(LibraryState.NOT_LOADED,
106 LibraryState.LOADING)) {
107 for (final CompressionType compressionType : CompressionType.values()) {
108 if (compressionType.equals(CompressionType.NO_COMPRESSION)) {
109 continue;
110 }
111 for (final String path : paths) {
112 try {
113 System.load(path + "/" + Environment.getSharedLibraryFileName(
114 compressionType.getLibraryName()));
115 break;
20effc67 116 } catch (final UnsatisfiedLinkError e) {
7c673cae
FG
117 // since they are optional, we ignore loading fails.
118 }
119 }
120 }
121 boolean success = false;
122 UnsatisfiedLinkError err = null;
123 for (final String path : paths) {
124 try {
125 System.load(path + "/" +
126 Environment.getJniLibraryFileName("rocksdbjni"));
127 success = true;
128 break;
20effc67 129 } catch (final UnsatisfiedLinkError e) {
7c673cae
FG
130 err = e;
131 }
132 }
133 if (!success) {
134 libraryLoaded.set(LibraryState.NOT_LOADED);
135 throw err;
136 }
137
20effc67
TL
138 final int encodedVersion = version();
139 version = Version.fromEncodedVersion(encodedVersion);
140
7c673cae
FG
141 libraryLoaded.set(LibraryState.LOADED);
142 return;
143 }
144
145 while (libraryLoaded.get() == LibraryState.LOADING) {
146 try {
147 Thread.sleep(10);
148 } catch(final InterruptedException e) {
149 //ignore
150 }
151 }
152 }
153
20effc67
TL
154 public static Version rocksdbVersion() {
155 return version;
156 }
157
494da23a
TL
158 /**
159 * Private constructor.
160 *
161 * @param nativeHandle The native handle of the C++ RocksDB object
162 */
163 protected RocksDB(final long nativeHandle) {
164 super(nativeHandle);
165 }
166
7c673cae
FG
167 /**
168 * The factory constructor of RocksDB that opens a RocksDB instance given
169 * the path to the database using the default options w/ createIfMissing
170 * set to true.
171 *
172 * @param path the path to the rocksdb.
173 * @return a {@link RocksDB} instance on success, null if the specified
174 * {@link RocksDB} can not be opened.
175 *
176 * @throws RocksDBException thrown if error happens in underlying
177 * native library.
178 * @see Options#setCreateIfMissing(boolean)
179 */
180 public static RocksDB open(final String path) throws RocksDBException {
494da23a 181 final Options options = new Options();
7c673cae
FG
182 options.setCreateIfMissing(true);
183 return open(options, path);
184 }
185
186 /**
187 * The factory constructor of RocksDB that opens a RocksDB instance given
188 * the path to the database using the specified options and db path and a list
189 * of column family names.
190 * <p>
191 * If opened in read write mode every existing column family name must be
192 * passed within the list to this method.</p>
193 * <p>
194 * If opened in read-only mode only a subset of existing column families must
195 * be passed to this method.</p>
196 * <p>
197 * Options instance *should* not be disposed before all DBs using this options
198 * instance have been closed. If user doesn't call options dispose explicitly,
199 * then this options instance will be GC'd automatically</p>
200 * <p>
201 * ColumnFamily handles are disposed when the RocksDB instance is disposed.
202 * </p>
203 *
204 * @param path the path to the rocksdb.
205 * @param columnFamilyDescriptors list of column family descriptors
206 * @param columnFamilyHandles will be filled with ColumnFamilyHandle instances
207 * on open.
208 * @return a {@link RocksDB} instance on success, null if the specified
209 * {@link RocksDB} can not be opened.
210 *
211 * @throws RocksDBException thrown if error happens in underlying
212 * native library.
213 * @see DBOptions#setCreateIfMissing(boolean)
214 */
215 public static RocksDB open(final String path,
216 final List<ColumnFamilyDescriptor> columnFamilyDescriptors,
217 final List<ColumnFamilyHandle> columnFamilyHandles)
218 throws RocksDBException {
494da23a 219 final DBOptions options = new DBOptions();
7c673cae
FG
220 return open(options, path, columnFamilyDescriptors, columnFamilyHandles);
221 }
222
223 /**
224 * The factory constructor of RocksDB that opens a RocksDB instance given
225 * the path to the database using the specified options and db path.
226 *
227 * <p>
228 * Options instance *should* not be disposed before all DBs using this options
229 * instance have been closed. If user doesn't call options dispose explicitly,
230 * then this options instance will be GC'd automatically.</p>
231 * <p>
232 * Options instance can be re-used to open multiple DBs if DB statistics is
233 * not used. If DB statistics are required, then its recommended to open DB
234 * with new Options instance as underlying native statistics instance does not
235 * use any locks to prevent concurrent updates.</p>
236 *
237 * @param options {@link org.rocksdb.Options} instance.
238 * @param path the path to the rocksdb.
239 * @return a {@link RocksDB} instance on success, null if the specified
240 * {@link RocksDB} can not be opened.
241 *
242 * @throws RocksDBException thrown if error happens in underlying
243 * native library.
244 *
245 * @see Options#setCreateIfMissing(boolean)
246 */
247 public static RocksDB open(final Options options, final String path)
248 throws RocksDBException {
249 // when non-default Options is used, keeping an Options reference
250 // in RocksDB can prevent Java to GC during the life-time of
251 // the currently-created RocksDB.
252 final RocksDB db = new RocksDB(open(options.nativeHandle_, path));
253 db.storeOptionsInstance(options);
254 return db;
255 }
256
257 /**
258 * The factory constructor of RocksDB that opens a RocksDB instance given
259 * the path to the database using the specified options and db path and a list
260 * of column family names.
261 * <p>
262 * If opened in read write mode every existing column family name must be
263 * passed within the list to this method.</p>
264 * <p>
265 * If opened in read-only mode only a subset of existing column families must
266 * be passed to this method.</p>
267 * <p>
268 * Options instance *should* not be disposed before all DBs using this options
269 * instance have been closed. If user doesn't call options dispose explicitly,
270 * then this options instance will be GC'd automatically.</p>
271 * <p>
272 * Options instance can be re-used to open multiple DBs if DB statistics is
273 * not used. If DB statistics are required, then its recommended to open DB
274 * with new Options instance as underlying native statistics instance does not
275 * use any locks to prevent concurrent updates.</p>
276 * <p>
277 * ColumnFamily handles are disposed when the RocksDB instance is disposed.
278 * </p>
279 *
280 * @param options {@link org.rocksdb.DBOptions} instance.
281 * @param path the path to the rocksdb.
282 * @param columnFamilyDescriptors list of column family descriptors
283 * @param columnFamilyHandles will be filled with ColumnFamilyHandle instances
284 * on open.
285 * @return a {@link RocksDB} instance on success, null if the specified
286 * {@link RocksDB} can not be opened.
287 *
288 * @throws RocksDBException thrown if error happens in underlying
289 * native library.
290 *
291 * @see DBOptions#setCreateIfMissing(boolean)
292 */
293 public static RocksDB open(final DBOptions options, final String path,
294 final List<ColumnFamilyDescriptor> columnFamilyDescriptors,
295 final List<ColumnFamilyHandle> columnFamilyHandles)
296 throws RocksDBException {
297
298 final byte[][] cfNames = new byte[columnFamilyDescriptors.size()][];
299 final long[] cfOptionHandles = new long[columnFamilyDescriptors.size()];
300 for (int i = 0; i < columnFamilyDescriptors.size(); i++) {
301 final ColumnFamilyDescriptor cfDescriptor = columnFamilyDescriptors
302 .get(i);
f67539c2
TL
303 cfNames[i] = cfDescriptor.getName();
304 cfOptionHandles[i] = cfDescriptor.getOptions().nativeHandle_;
7c673cae
FG
305 }
306
307 final long[] handles = open(options.nativeHandle_, path, cfNames,
308 cfOptionHandles);
309 final RocksDB db = new RocksDB(handles[0]);
310 db.storeOptionsInstance(options);
311
312 for (int i = 1; i < handles.length; i++) {
20effc67
TL
313 final ColumnFamilyHandle columnFamilyHandle = new ColumnFamilyHandle(db, handles[i]);
314 columnFamilyHandles.add(columnFamilyHandle);
7c673cae
FG
315 }
316
20effc67
TL
317 db.ownedColumnFamilyHandles.addAll(columnFamilyHandles);
318
7c673cae
FG
319 return db;
320 }
321
322 /**
323 * The factory constructor of RocksDB that opens a RocksDB instance in
324 * Read-Only mode given the path to the database using the default
325 * options.
326 *
327 * @param path the path to the RocksDB.
328 * @return a {@link RocksDB} instance on success, null if the specified
329 * {@link RocksDB} can not be opened.
330 *
331 * @throws RocksDBException thrown if error happens in underlying
332 * native library.
333 */
334 public static RocksDB openReadOnly(final String path)
335 throws RocksDBException {
336 // This allows to use the rocksjni default Options instead of
337 // the c++ one.
20effc67 338 final Options options = new Options();
7c673cae
FG
339 return openReadOnly(options, path);
340 }
341
20effc67
TL
342 /**
343 * The factory constructor of RocksDB that opens a RocksDB instance in
344 * Read-Only mode given the path to the database using the specified
345 * options and db path.
346 *
347 * Options instance *should* not be disposed before all DBs using this options
348 * instance have been closed. If user doesn't call options dispose explicitly,
349 * then this options instance will be GC'd automatically.
350 *
351 * @param options {@link Options} instance.
352 * @param path the path to the RocksDB.
353 * @return a {@link RocksDB} instance on success, null if the specified
354 * {@link RocksDB} can not be opened.
355 *
356 * @throws RocksDBException thrown if error happens in underlying
357 * native library.
358 */
359 public static RocksDB openReadOnly(final Options options, final String path)
360 throws RocksDBException {
361 return openReadOnly(options, path, false);
362 }
363
364 /**
365 * The factory constructor of RocksDB that opens a RocksDB instance in
366 * Read-Only mode given the path to the database using the specified
367 * options and db path.
368 *
369 * Options instance *should* not be disposed before all DBs using this options
370 * instance have been closed. If user doesn't call options dispose explicitly,
371 * then this options instance will be GC'd automatically.
372 *
373 * @param options {@link Options} instance.
374 * @param path the path to the RocksDB.
375 * @param errorIfWalFileExists true to raise an error when opening the db
376 * if a Write Ahead Log file exists, false otherwise.
377 * @return a {@link RocksDB} instance on success, null if the specified
378 * {@link RocksDB} can not be opened.
379 *
380 * @throws RocksDBException thrown if error happens in underlying
381 * native library.
382 */
383 public static RocksDB openReadOnly(final Options options, final String path,
384 final boolean errorIfWalFileExists) throws RocksDBException {
385 // when non-default Options is used, keeping an Options reference
386 // in RocksDB can prevent Java to GC during the life-time of
387 // the currently-created RocksDB.
388 final RocksDB db = new RocksDB(openROnly(options.nativeHandle_, path, errorIfWalFileExists));
389 db.storeOptionsInstance(options);
390 return db;
391 }
392
7c673cae
FG
393 /**
394 * The factory constructor of RocksDB that opens a RocksDB instance in
395 * Read-Only mode given the path to the database using the default
396 * options.
397 *
398 * @param path the path to the RocksDB.
399 * @param columnFamilyDescriptors list of column family descriptors
400 * @param columnFamilyHandles will be filled with ColumnFamilyHandle instances
401 * on open.
402 * @return a {@link RocksDB} instance on success, null if the specified
403 * {@link RocksDB} can not be opened.
404 *
405 * @throws RocksDBException thrown if error happens in underlying
406 * native library.
407 */
408 public static RocksDB openReadOnly(final String path,
409 final List<ColumnFamilyDescriptor> columnFamilyDescriptors,
410 final List<ColumnFamilyHandle> columnFamilyHandles)
411 throws RocksDBException {
412 // This allows to use the rocksjni default Options instead of
413 // the c++ one.
414 final DBOptions options = new DBOptions();
20effc67 415 return openReadOnly(options, path, columnFamilyDescriptors, columnFamilyHandles, false);
7c673cae
FG
416 }
417
418 /**
419 * The factory constructor of RocksDB that opens a RocksDB instance in
420 * Read-Only mode given the path to the database using the specified
421 * options and db path.
422 *
20effc67
TL
423 * <p>This open method allows to open RocksDB using a subset of available
424 * column families</p>
425 * <p>Options instance *should* not be disposed before all DBs using this
426 * options instance have been closed. If user doesn't call options dispose
427 * explicitly,then this options instance will be GC'd automatically.</p>
7c673cae 428 *
20effc67 429 * @param options {@link DBOptions} instance.
7c673cae 430 * @param path the path to the RocksDB.
20effc67
TL
431 * @param columnFamilyDescriptors list of column family descriptors
432 * @param columnFamilyHandles will be filled with ColumnFamilyHandle instances
433 * on open.
7c673cae
FG
434 * @return a {@link RocksDB} instance on success, null if the specified
435 * {@link RocksDB} can not be opened.
436 *
437 * @throws RocksDBException thrown if error happens in underlying
438 * native library.
439 */
20effc67
TL
440 public static RocksDB openReadOnly(final DBOptions options, final String path,
441 final List<ColumnFamilyDescriptor> columnFamilyDescriptors,
442 final List<ColumnFamilyHandle> columnFamilyHandles) throws RocksDBException {
443 return openReadOnly(options, path, columnFamilyDescriptors, columnFamilyHandles, false);
7c673cae
FG
444 }
445
446 /**
447 * The factory constructor of RocksDB that opens a RocksDB instance in
448 * Read-Only mode given the path to the database using the specified
449 * options and db path.
450 *
451 * <p>This open method allows to open RocksDB using a subset of available
452 * column families</p>
453 * <p>Options instance *should* not be disposed before all DBs using this
454 * options instance have been closed. If user doesn't call options dispose
455 * explicitly,then this options instance will be GC'd automatically.</p>
456 *
457 * @param options {@link DBOptions} instance.
458 * @param path the path to the RocksDB.
459 * @param columnFamilyDescriptors list of column family descriptors
460 * @param columnFamilyHandles will be filled with ColumnFamilyHandle instances
461 * on open.
20effc67
TL
462 * @param errorIfWalFileExists true to raise an error when opening the db
463 * if a Write Ahead Log file exists, false otherwise.
7c673cae
FG
464 * @return a {@link RocksDB} instance on success, null if the specified
465 * {@link RocksDB} can not be opened.
466 *
467 * @throws RocksDBException thrown if error happens in underlying
468 * native library.
469 */
470 public static RocksDB openReadOnly(final DBOptions options, final String path,
471 final List<ColumnFamilyDescriptor> columnFamilyDescriptors,
20effc67 472 final List<ColumnFamilyHandle> columnFamilyHandles, final boolean errorIfWalFileExists)
7c673cae
FG
473 throws RocksDBException {
474 // when non-default Options is used, keeping an Options reference
475 // in RocksDB can prevent Java to GC during the life-time of
476 // the currently-created RocksDB.
477
478 final byte[][] cfNames = new byte[columnFamilyDescriptors.size()][];
479 final long[] cfOptionHandles = new long[columnFamilyDescriptors.size()];
480 for (int i = 0; i < columnFamilyDescriptors.size(); i++) {
481 final ColumnFamilyDescriptor cfDescriptor = columnFamilyDescriptors
482 .get(i);
f67539c2
TL
483 cfNames[i] = cfDescriptor.getName();
484 cfOptionHandles[i] = cfDescriptor.getOptions().nativeHandle_;
7c673cae
FG
485 }
486
20effc67
TL
487 final long[] handles =
488 openROnly(options.nativeHandle_, path, cfNames, cfOptionHandles, errorIfWalFileExists);
489 final RocksDB db = new RocksDB(handles[0]);
490 db.storeOptionsInstance(options);
491
492 for (int i = 1; i < handles.length; i++) {
493 final ColumnFamilyHandle columnFamilyHandle = new ColumnFamilyHandle(db, handles[i]);
494 columnFamilyHandles.add(columnFamilyHandle);
495 }
496
497 db.ownedColumnFamilyHandles.addAll(columnFamilyHandles);
498
499 return db;
500 }
501
502 /**
503 * Open DB as secondary instance with only the default column family.
504 *
505 * The secondary instance can dynamically tail the MANIFEST of
506 * a primary that must have already been created. User can call
507 * {@link #tryCatchUpWithPrimary()} to make the secondary instance catch up
508 * with primary (WAL tailing is NOT supported now) whenever the user feels
509 * necessary. Column families created by the primary after the secondary
510 * instance starts are currently ignored by the secondary instance.
511 * Column families opened by secondary and dropped by the primary will be
512 * dropped by secondary as well. However the user of the secondary instance
513 * can still access the data of such dropped column family as long as they
514 * do not destroy the corresponding column family handle.
515 * WAL tailing is not supported at present, but will arrive soon.
516 *
517 * @param options the options to open the secondary instance.
518 * @param path the path to the primary RocksDB instance.
519 * @param secondaryPath points to a directory where the secondary instance
520 * stores its info log
521 *
522 * @return a {@link RocksDB} instance on success, null if the specified
523 * {@link RocksDB} can not be opened.
524 *
525 * @throws RocksDBException thrown if error happens in underlying
526 * native library.
527 */
528 public static RocksDB openAsSecondary(final Options options, final String path,
529 final String secondaryPath) throws RocksDBException {
530 // when non-default Options is used, keeping an Options reference
531 // in RocksDB can prevent Java to GC during the life-time of
532 // the currently-created RocksDB.
533 final RocksDB db = new RocksDB(openAsSecondary(options.nativeHandle_, path, secondaryPath));
534 db.storeOptionsInstance(options);
535 return db;
536 }
537
538 /**
539 * Open DB as secondary instance with column families.
540 * You can open a subset of column families in secondary mode.
541 *
542 * The secondary instance can dynamically tail the MANIFEST of
543 * a primary that must have already been created. User can call
544 * {@link #tryCatchUpWithPrimary()} to make the secondary instance catch up
545 * with primary (WAL tailing is NOT supported now) whenever the user feels
546 * necessary. Column families created by the primary after the secondary
547 * instance starts are currently ignored by the secondary instance.
548 * Column families opened by secondary and dropped by the primary will be
549 * dropped by secondary as well. However the user of the secondary instance
550 * can still access the data of such dropped column family as long as they
551 * do not destroy the corresponding column family handle.
552 * WAL tailing is not supported at present, but will arrive soon.
553 *
554 * @param options the options to open the secondary instance.
555 * @param path the path to the primary RocksDB instance.
556 * @param secondaryPath points to a directory where the secondary instance
557 * stores its info log.
558 * @param columnFamilyDescriptors list of column family descriptors
559 * @param columnFamilyHandles will be filled with ColumnFamilyHandle instances
560 * on open.
561 *
562 * @return a {@link RocksDB} instance on success, null if the specified
563 * {@link RocksDB} can not be opened.
564 *
565 * @throws RocksDBException thrown if error happens in underlying
566 * native library.
567 */
568 public static RocksDB openAsSecondary(final DBOptions options, final String path,
569 final String secondaryPath, final List<ColumnFamilyDescriptor> columnFamilyDescriptors,
570 final List<ColumnFamilyHandle> columnFamilyHandles) throws RocksDBException {
571 // when non-default Options is used, keeping an Options reference
572 // in RocksDB can prevent Java to GC during the life-time of
573 // the currently-created RocksDB.
574
575 final byte[][] cfNames = new byte[columnFamilyDescriptors.size()][];
576 final long[] cfOptionHandles = new long[columnFamilyDescriptors.size()];
577 for (int i = 0; i < columnFamilyDescriptors.size(); i++) {
578 final ColumnFamilyDescriptor cfDescriptor = columnFamilyDescriptors.get(i);
579 cfNames[i] = cfDescriptor.getName();
580 cfOptionHandles[i] = cfDescriptor.getOptions().nativeHandle_;
581 }
582
583 final long[] handles =
584 openAsSecondary(options.nativeHandle_, path, secondaryPath, cfNames, cfOptionHandles);
7c673cae
FG
585 final RocksDB db = new RocksDB(handles[0]);
586 db.storeOptionsInstance(options);
587
588 for (int i = 1; i < handles.length; i++) {
20effc67
TL
589 final ColumnFamilyHandle columnFamilyHandle = new ColumnFamilyHandle(db, handles[i]);
590 columnFamilyHandles.add(columnFamilyHandle);
7c673cae
FG
591 }
592
20effc67
TL
593 db.ownedColumnFamilyHandles.addAll(columnFamilyHandles);
594
7c673cae
FG
595 return db;
596 }
494da23a
TL
597
598 /**
599 * This is similar to {@link #close()} except that it
600 * throws an exception if any error occurs.
601 *
602 * This will not fsync the WAL files.
603 * If syncing is required, the caller must first call {@link #syncWal()}
604 * or {@link #write(WriteOptions, WriteBatch)} using an empty write batch
605 * with {@link WriteOptions#setSync(boolean)} set to true.
606 *
607 * See also {@link #close()}.
608 *
609 * @throws RocksDBException if an error occurs whilst closing.
610 */
611 public void closeE() throws RocksDBException {
20effc67
TL
612 for (final ColumnFamilyHandle columnFamilyHandle : ownedColumnFamilyHandles) {
613 columnFamilyHandle.close();
614 }
615 ownedColumnFamilyHandles.clear();
616
494da23a
TL
617 if (owningHandle_.compareAndSet(true, false)) {
618 try {
619 closeDatabase(nativeHandle_);
620 } finally {
621 disposeInternal();
622 }
623 }
624 }
625
626 /**
627 * This is similar to {@link #closeE()} except that it
628 * silently ignores any errors.
629 *
630 * This will not fsync the WAL files.
631 * If syncing is required, the caller must first call {@link #syncWal()}
632 * or {@link #write(WriteOptions, WriteBatch)} using an empty write batch
633 * with {@link WriteOptions#setSync(boolean)} set to true.
634 *
635 * See also {@link #close()}.
636 */
637 @Override
638 public void close() {
20effc67
TL
639 for (final ColumnFamilyHandle columnFamilyHandle : ownedColumnFamilyHandles) {
640 columnFamilyHandle.close();
641 }
642 ownedColumnFamilyHandles.clear();
643
494da23a
TL
644 if (owningHandle_.compareAndSet(true, false)) {
645 try {
646 closeDatabase(nativeHandle_);
647 } catch (final RocksDBException e) {
648 // silently ignore the error report
649 } finally {
650 disposeInternal();
651 }
652 }
653 }
654
7c673cae
FG
655 /**
656 * Static method to determine all available column families for a
657 * rocksdb database identified by path
658 *
659 * @param options Options for opening the database
660 * @param path Absolute path to rocksdb database
661 * @return List&lt;byte[]&gt; List containing the column family names
662 *
663 * @throws RocksDBException thrown if error happens in underlying
664 * native library.
665 */
666 public static List<byte[]> listColumnFamilies(final Options options,
667 final String path) throws RocksDBException {
668 return Arrays.asList(RocksDB.listColumnFamilies(options.nativeHandle_,
669 path));
670 }
671
494da23a
TL
672 /**
673 * Creates a new column family with the name columnFamilyName and
674 * allocates a ColumnFamilyHandle within an internal structure.
675 * The ColumnFamilyHandle is automatically disposed with DB disposal.
676 *
677 * @param columnFamilyDescriptor column family to be created.
678 * @return {@link org.rocksdb.ColumnFamilyHandle} instance.
679 *
680 * @throws RocksDBException thrown if error happens in underlying
681 * native library.
682 */
683 public ColumnFamilyHandle createColumnFamily(
684 final ColumnFamilyDescriptor columnFamilyDescriptor)
685 throws RocksDBException {
20effc67
TL
686 final ColumnFamilyHandle columnFamilyHandle = new ColumnFamilyHandle(this,
687 createColumnFamily(nativeHandle_, columnFamilyDescriptor.getName(),
688 columnFamilyDescriptor.getName().length,
689 columnFamilyDescriptor.getOptions().nativeHandle_));
690 ownedColumnFamilyHandles.add(columnFamilyHandle);
691 return columnFamilyHandle;
494da23a
TL
692 }
693
694 /**
695 * Bulk create column families with the same column family options.
696 *
697 * @param columnFamilyOptions the options for the column families.
698 * @param columnFamilyNames the names of the column families.
699 *
700 * @return the handles to the newly created column families.
f67539c2
TL
701 *
702 * @throws RocksDBException if an error occurs whilst creating
703 * the column families
494da23a
TL
704 */
705 public List<ColumnFamilyHandle> createColumnFamilies(
706 final ColumnFamilyOptions columnFamilyOptions,
707 final List<byte[]> columnFamilyNames) throws RocksDBException {
708 final byte[][] cfNames = columnFamilyNames.toArray(
709 new byte[0][]);
710 final long[] cfHandles = createColumnFamilies(nativeHandle_,
711 columnFamilyOptions.nativeHandle_, cfNames);
712 final List<ColumnFamilyHandle> columnFamilyHandles =
713 new ArrayList<>(cfHandles.length);
714 for (int i = 0; i < cfHandles.length; i++) {
20effc67
TL
715 final ColumnFamilyHandle columnFamilyHandle = new ColumnFamilyHandle(this, cfHandles[i]);
716 columnFamilyHandles.add(columnFamilyHandle);
494da23a 717 }
20effc67 718 ownedColumnFamilyHandles.addAll(columnFamilyHandles);
494da23a
TL
719 return columnFamilyHandles;
720 }
721
722 /**
723 * Bulk create column families with the same column family options.
724 *
725 * @param columnFamilyDescriptors the descriptions of the column families.
726 *
727 * @return the handles to the newly created column families.
f67539c2
TL
728 *
729 * @throws RocksDBException if an error occurs whilst creating
730 * the column families
494da23a
TL
731 */
732 public List<ColumnFamilyHandle> createColumnFamilies(
733 final List<ColumnFamilyDescriptor> columnFamilyDescriptors)
734 throws RocksDBException {
735 final long[] cfOptsHandles = new long[columnFamilyDescriptors.size()];
736 final byte[][] cfNames = new byte[columnFamilyDescriptors.size()][];
737 for (int i = 0; i < columnFamilyDescriptors.size(); i++) {
738 final ColumnFamilyDescriptor columnFamilyDescriptor
739 = columnFamilyDescriptors.get(i);
740 cfOptsHandles[i] = columnFamilyDescriptor.getOptions().nativeHandle_;
741 cfNames[i] = columnFamilyDescriptor.getName();
742 }
743 final long[] cfHandles = createColumnFamilies(nativeHandle_,
744 cfOptsHandles, cfNames);
745 final List<ColumnFamilyHandle> columnFamilyHandles =
746 new ArrayList<>(cfHandles.length);
747 for (int i = 0; i < cfHandles.length; i++) {
20effc67
TL
748 final ColumnFamilyHandle columnFamilyHandle = new ColumnFamilyHandle(this, cfHandles[i]);
749 columnFamilyHandles.add(columnFamilyHandle);
494da23a 750 }
20effc67 751 ownedColumnFamilyHandles.addAll(columnFamilyHandles);
494da23a
TL
752 return columnFamilyHandles;
753 }
754
755 /**
756 * Drops the column family specified by {@code columnFamilyHandle}. This call
757 * only records a drop record in the manifest and prevents the column
758 * family from flushing and compacting.
759 *
760 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
761 * instance
762 *
763 * @throws RocksDBException thrown if error happens in underlying
764 * native library.
765 */
766 public void dropColumnFamily(final ColumnFamilyHandle columnFamilyHandle)
767 throws RocksDBException {
768 dropColumnFamily(nativeHandle_, columnFamilyHandle.nativeHandle_);
769 }
770
771 // Bulk drop column families. This call only records drop records in the
772 // manifest and prevents the column families from flushing and compacting.
773 // In case of error, the request may succeed partially. User may call
774 // ListColumnFamilies to check the result.
775 public void dropColumnFamilies(
776 final List<ColumnFamilyHandle> columnFamilies) throws RocksDBException {
777 final long[] cfHandles = new long[columnFamilies.size()];
778 for (int i = 0; i < columnFamilies.size(); i++) {
779 cfHandles[i] = columnFamilies.get(i).nativeHandle_;
780 }
781 dropColumnFamilies(nativeHandle_, cfHandles);
7c673cae
FG
782 }
783
20effc67
TL
784 /**
785 * Deletes native column family handle of given {@link ColumnFamilyHandle} Java object
786 * and removes reference from {@link RocksDB#ownedColumnFamilyHandles}.
787 *
788 * @param columnFamilyHandle column family handle object.
789 */
790 public void destroyColumnFamilyHandle(final ColumnFamilyHandle columnFamilyHandle) {
791 for (int i = 0; i < ownedColumnFamilyHandles.size(); ++i) {
792 final ColumnFamilyHandle ownedHandle = ownedColumnFamilyHandles.get(i);
793 if (ownedHandle.equals(columnFamilyHandle)) {
794 columnFamilyHandle.close();
795 ownedColumnFamilyHandles.remove(i);
796 return;
797 }
798 }
799 }
494da23a 800
7c673cae
FG
801 /**
802 * Set the database entry for "key" to "value".
803 *
804 * @param key the specified key to be inserted.
805 * @param value the value associated with the specified key.
806 *
807 * @throws RocksDBException thrown if error happens in underlying
808 * native library.
809 */
810 public void put(final byte[] key, final byte[] value)
811 throws RocksDBException {
812 put(nativeHandle_, key, 0, key.length, value, 0, value.length);
813 }
814
494da23a
TL
815 /**
816 * Set the database entry for "key" to "value".
817 *
818 * @param key The specified key to be inserted
819 * @param offset the offset of the "key" array to be used, must be
820 * non-negative and no larger than "key".length
821 * @param len the length of the "key" array to be used, must be non-negative
822 * and no larger than ("key".length - offset)
823 * @param value the value associated with the specified key
824 * @param vOffset the offset of the "value" array to be used, must be
825 * non-negative and no longer than "key".length
826 * @param vLen the length of the "value" array to be used, must be
827 * non-negative and no larger than ("value".length - offset)
828 *
829 * @throws RocksDBException thrown if errors happens in underlying native
830 * library.
831 * @throws IndexOutOfBoundsException if an offset or length is out of bounds
832 */
833 public void put(final byte[] key, final int offset, final int len,
834 final byte[] value, final int vOffset, final int vLen)
835 throws RocksDBException {
836 checkBounds(offset, len, key.length);
837 checkBounds(vOffset, vLen, value.length);
838 put(nativeHandle_, key, offset, len, value, vOffset, vLen);
839 }
840
7c673cae
FG
841 /**
842 * Set the database entry for "key" to "value" in the specified
843 * column family.
844 *
845 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
846 * instance
847 * @param key the specified key to be inserted.
848 * @param value the value associated with the specified key.
849 *
850 * throws IllegalArgumentException if column family is not present
851 *
852 * @throws RocksDBException thrown if error happens in underlying
853 * native library.
854 */
855 public void put(final ColumnFamilyHandle columnFamilyHandle,
856 final byte[] key, final byte[] value) throws RocksDBException {
857 put(nativeHandle_, key, 0, key.length, value, 0, value.length,
858 columnFamilyHandle.nativeHandle_);
859 }
860
494da23a
TL
861 /**
862 * Set the database entry for "key" to "value" in the specified
863 * column family.
864 *
865 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
866 * instance
867 * @param key The specified key to be inserted
868 * @param offset the offset of the "key" array to be used, must
869 * be non-negative and no larger than "key".length
870 * @param len the length of the "key" array to be used, must be non-negative
871 * and no larger than ("key".length - offset)
872 * @param value the value associated with the specified key
873 * @param vOffset the offset of the "value" array to be used, must be
874 * non-negative and no longer than "key".length
875 * @param vLen the length of the "value" array to be used, must be
876 * non-negative and no larger than ("value".length - offset)
877 *
878 * @throws RocksDBException thrown if errors happens in underlying native
879 * library.
880 * @throws IndexOutOfBoundsException if an offset or length is out of bounds
881 */
882 public void put(final ColumnFamilyHandle columnFamilyHandle,
883 final byte[] key, final int offset, final int len,
884 final byte[] value, final int vOffset, final int vLen)
885 throws RocksDBException {
886 checkBounds(offset, len, key.length);
887 checkBounds(vOffset, vLen, value.length);
888 put(nativeHandle_, key, offset, len, value, vOffset, vLen,
889 columnFamilyHandle.nativeHandle_);
890 }
891
7c673cae
FG
892 /**
893 * Set the database entry for "key" to "value".
894 *
895 * @param writeOpts {@link org.rocksdb.WriteOptions} instance.
896 * @param key the specified key to be inserted.
897 * @param value the value associated with the specified key.
898 *
899 * @throws RocksDBException thrown if error happens in underlying
900 * native library.
901 */
902 public void put(final WriteOptions writeOpts, final byte[] key,
903 final byte[] value) throws RocksDBException {
904 put(nativeHandle_, writeOpts.nativeHandle_,
905 key, 0, key.length, value, 0, value.length);
906 }
907
494da23a
TL
908 /**
909 * Set the database entry for "key" to "value".
910 *
911 * @param writeOpts {@link org.rocksdb.WriteOptions} instance.
912 * @param key The specified key to be inserted
913 * @param offset the offset of the "key" array to be used, must be
914 * non-negative and no larger than "key".length
915 * @param len the length of the "key" array to be used, must be non-negative
916 * and no larger than ("key".length - offset)
917 * @param value the value associated with the specified key
918 * @param vOffset the offset of the "value" array to be used, must be
919 * non-negative and no longer than "key".length
920 * @param vLen the length of the "value" array to be used, must be
921 * non-negative and no larger than ("value".length - offset)
922 *
923 * @throws RocksDBException thrown if error happens in underlying
924 * native library.
925 * @throws IndexOutOfBoundsException if an offset or length is out of bounds
926 */
927 public void put(final WriteOptions writeOpts,
928 final byte[] key, final int offset, final int len,
929 final byte[] value, final int vOffset, final int vLen)
930 throws RocksDBException {
931 checkBounds(offset, len, key.length);
932 checkBounds(vOffset, vLen, value.length);
933 put(nativeHandle_, writeOpts.nativeHandle_,
934 key, offset, len, value, vOffset, vLen);
935 }
936
7c673cae
FG
937 /**
938 * Set the database entry for "key" to "value" for the specified
939 * column family.
940 *
941 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
942 * instance
943 * @param writeOpts {@link org.rocksdb.WriteOptions} instance.
944 * @param key the specified key to be inserted.
945 * @param value the value associated with the specified key.
946 *
947 * throws IllegalArgumentException if column family is not present
948 *
949 * @throws RocksDBException thrown if error happens in underlying
950 * native library.
951 * @see IllegalArgumentException
952 */
953 public void put(final ColumnFamilyHandle columnFamilyHandle,
954 final WriteOptions writeOpts, final byte[] key,
955 final byte[] value) throws RocksDBException {
956 put(nativeHandle_, writeOpts.nativeHandle_, key, 0, key.length, value,
957 0, value.length, columnFamilyHandle.nativeHandle_);
958 }
959
f67539c2
TL
960 /**
961 * Set the database entry for "key" to "value" for the specified
962 * column family.
963 *
964 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
965 * instance
966 * @param writeOpts {@link org.rocksdb.WriteOptions} instance.
967 * @param key the specified key to be inserted. Position and limit is used.
968 * Supports direct buffer only.
969 * @param value the value associated with the specified key. Position and limit is used.
970 * Supports direct buffer only.
971 *
972 * throws IllegalArgumentException if column family is not present
973 *
974 * @throws RocksDBException thrown if error happens in underlying
975 * native library.
976 * @see IllegalArgumentException
977 */
978 public void put(final ColumnFamilyHandle columnFamilyHandle, final WriteOptions writeOpts,
979 final ByteBuffer key, final ByteBuffer value) throws RocksDBException {
980 assert key.isDirect() && value.isDirect();
981 putDirect(nativeHandle_, writeOpts.nativeHandle_, key, key.position(), key.remaining(), value,
982 value.position(), value.remaining(), columnFamilyHandle.nativeHandle_);
983 key.position(key.limit());
984 value.position(value.limit());
985 }
986
987 /**
988 * Set the database entry for "key" to "value".
989 *
990 * @param writeOpts {@link org.rocksdb.WriteOptions} instance.
991 * @param key the specified key to be inserted. Position and limit is used.
992 * Supports direct buffer only.
993 * @param value the value associated with the specified key. Position and limit is used.
994 * Supports direct buffer only.
995 *
996 * throws IllegalArgumentException if column family is not present
997 *
998 * @throws RocksDBException thrown if error happens in underlying
999 * native library.
1000 * @see IllegalArgumentException
1001 */
1002 public void put(final WriteOptions writeOpts, final ByteBuffer key, final ByteBuffer value)
1003 throws RocksDBException {
1004 assert key.isDirect() && value.isDirect();
1005 putDirect(nativeHandle_, writeOpts.nativeHandle_, key, key.position(), key.remaining(), value,
1006 value.position(), value.remaining(), 0);
1007 key.position(key.limit());
1008 value.position(value.limit());
1009 }
1010
7c673cae 1011 /**
494da23a
TL
1012 * Set the database entry for "key" to "value" for the specified
1013 * column family.
7c673cae 1014 *
494da23a
TL
1015 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
1016 * instance
1017 * @param writeOpts {@link org.rocksdb.WriteOptions} instance.
1018 * @param key The specified key to be inserted
1019 * @param offset the offset of the "key" array to be used, must be
1020 * non-negative and no larger than "key".length
1021 * @param len the length of the "key" array to be used, must be non-negative
1022 * and no larger than ("key".length - offset)
1023 * @param value the value associated with the specified key
1024 * @param vOffset the offset of the "value" array to be used, must be
1025 * non-negative and no longer than "key".length
1026 * @param vLen the length of the "value" array to be used, must be
1027 * non-negative and no larger than ("value".length - offset)
7c673cae 1028 *
494da23a
TL
1029 * @throws RocksDBException thrown if error happens in underlying
1030 * native library.
1031 * @throws IndexOutOfBoundsException if an offset or length is out of bounds
7c673cae 1032 */
494da23a
TL
1033 public void put(final ColumnFamilyHandle columnFamilyHandle,
1034 final WriteOptions writeOpts,
1035 final byte[] key, final int offset, final int len,
1036 final byte[] value, final int vOffset, final int vLen)
1037 throws RocksDBException {
1038 checkBounds(offset, len, key.length);
1039 checkBounds(vOffset, vLen, value.length);
1040 put(nativeHandle_, writeOpts.nativeHandle_, key, offset, len, value,
1041 vOffset, vLen, columnFamilyHandle.nativeHandle_);
7c673cae
FG
1042 }
1043
7c673cae 1044 /**
494da23a
TL
1045 * Delete the database entry (if any) for "key". Returns OK on
1046 * success, and a non-OK status on error. It is not an error if "key"
1047 * did not exist in the database.
7c673cae 1048 *
494da23a 1049 * @param key Key to delete within database
7c673cae 1050 *
494da23a
TL
1051 * @throws RocksDBException thrown if error happens in underlying
1052 * native library.
7c673cae 1053 */
494da23a
TL
1054 public void delete(final byte[] key) throws RocksDBException {
1055 delete(nativeHandle_, key, 0, key.length);
7c673cae
FG
1056 }
1057
1058 /**
494da23a
TL
1059 * Delete the database entry (if any) for "key". Returns OK on
1060 * success, and a non-OK status on error. It is not an error if "key"
1061 * did not exist in the database.
7c673cae 1062 *
494da23a
TL
1063 * @param key Key to delete within database
1064 * @param offset the offset of the "key" array to be used, must be
1065 * non-negative and no larger than "key".length
1066 * @param len the length of the "key" array to be used, must be
1067 * non-negative and no larger than ("key".length - offset)
7c673cae 1068 *
494da23a
TL
1069 * @throws RocksDBException thrown if error happens in underlying
1070 * native library.
7c673cae 1071 */
494da23a
TL
1072 public void delete(final byte[] key, final int offset, final int len)
1073 throws RocksDBException {
1074 delete(nativeHandle_, key, offset, len);
7c673cae
FG
1075 }
1076
7c673cae 1077 /**
494da23a
TL
1078 * Delete the database entry (if any) for "key". Returns OK on
1079 * success, and a non-OK status on error. It is not an error if "key"
1080 * did not exist in the database.
7c673cae 1081 *
494da23a
TL
1082 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
1083 * instance
1084 * @param key Key to delete within database
7c673cae
FG
1085 *
1086 * @throws RocksDBException thrown if error happens in underlying
1087 * native library.
1088 */
494da23a
TL
1089 public void delete(final ColumnFamilyHandle columnFamilyHandle,
1090 final byte[] key) throws RocksDBException {
1091 delete(nativeHandle_, key, 0, key.length, columnFamilyHandle.nativeHandle_);
7c673cae
FG
1092 }
1093
1094 /**
494da23a
TL
1095 * Delete the database entry (if any) for "key". Returns OK on
1096 * success, and a non-OK status on error. It is not an error if "key"
1097 * did not exist in the database.
7c673cae 1098 *
494da23a
TL
1099 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
1100 * instance
1101 * @param key Key to delete within database
1102 * @param offset the offset of the "key" array to be used,
1103 * must be non-negative and no larger than "key".length
1104 * @param len the length of the "key" array to be used, must be non-negative
1105 * and no larger than ("value".length - offset)
7c673cae
FG
1106 *
1107 * @throws RocksDBException thrown if error happens in underlying
1108 * native library.
1109 */
494da23a
TL
1110 public void delete(final ColumnFamilyHandle columnFamilyHandle,
1111 final byte[] key, final int offset, final int len)
7c673cae 1112 throws RocksDBException {
494da23a 1113 delete(nativeHandle_, key, offset, len, columnFamilyHandle.nativeHandle_);
7c673cae
FG
1114 }
1115
7c673cae 1116 /**
494da23a
TL
1117 * Delete the database entry (if any) for "key". Returns OK on
1118 * success, and a non-OK status on error. It is not an error if "key"
1119 * did not exist in the database.
7c673cae 1120 *
494da23a
TL
1121 * @param writeOpt WriteOptions to be used with delete operation
1122 * @param key Key to delete within database
7c673cae
FG
1123 *
1124 * @throws RocksDBException thrown if error happens in underlying
1125 * native library.
1126 */
494da23a
TL
1127 public void delete(final WriteOptions writeOpt, final byte[] key)
1128 throws RocksDBException {
1129 delete(nativeHandle_, writeOpt.nativeHandle_, key, 0, key.length);
7c673cae
FG
1130 }
1131
1132 /**
494da23a
TL
1133 * Delete the database entry (if any) for "key". Returns OK on
1134 * success, and a non-OK status on error. It is not an error if "key"
1135 * did not exist in the database.
7c673cae 1136 *
494da23a
TL
1137 * @param writeOpt WriteOptions to be used with delete operation
1138 * @param key Key to delete within database
1139 * @param offset the offset of the "key" array to be used, must be
1140 * non-negative and no larger than "key".length
1141 * @param len the length of the "key" array to be used, must be
1142 * non-negative and no larger than ("key".length - offset)
7c673cae
FG
1143 *
1144 * @throws RocksDBException thrown if error happens in underlying
1145 * native library.
1146 */
494da23a
TL
1147 public void delete(final WriteOptions writeOpt, final byte[] key,
1148 final int offset, final int len) throws RocksDBException {
1149 delete(nativeHandle_, writeOpt.nativeHandle_, key, offset, len);
7c673cae
FG
1150 }
1151
7c673cae 1152 /**
494da23a
TL
1153 * Delete the database entry (if any) for "key". Returns OK on
1154 * success, and a non-OK status on error. It is not an error if "key"
1155 * did not exist in the database.
7c673cae
FG
1156 *
1157 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
1158 * instance
494da23a
TL
1159 * @param writeOpt WriteOptions to be used with delete operation
1160 * @param key Key to delete within database
7c673cae
FG
1161 *
1162 * @throws RocksDBException thrown if error happens in underlying
1163 * native library.
1164 */
494da23a
TL
1165 public void delete(final ColumnFamilyHandle columnFamilyHandle,
1166 final WriteOptions writeOpt, final byte[] key)
1167 throws RocksDBException {
1168 delete(nativeHandle_, writeOpt.nativeHandle_, key, 0, key.length,
7c673cae
FG
1169 columnFamilyHandle.nativeHandle_);
1170 }
1171
1172 /**
494da23a
TL
1173 * Delete the database entry (if any) for "key". Returns OK on
1174 * success, and a non-OK status on error. It is not an error if "key"
1175 * did not exist in the database.
7c673cae
FG
1176 *
1177 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
1178 * instance
494da23a
TL
1179 * @param writeOpt WriteOptions to be used with delete operation
1180 * @param key Key to delete within database
1181 * @param offset the offset of the "key" array to be used, must be
1182 * non-negative and no larger than "key".length
1183 * @param len the length of the "key" array to be used, must be
1184 * non-negative and no larger than ("key".length - offset)
7c673cae
FG
1185 *
1186 * @throws RocksDBException thrown if error happens in underlying
1187 * native library.
1188 */
494da23a
TL
1189 public void delete(final ColumnFamilyHandle columnFamilyHandle,
1190 final WriteOptions writeOpt, final byte[] key, final int offset,
1191 final int len) throws RocksDBException {
1192 delete(nativeHandle_, writeOpt.nativeHandle_, key, offset, len,
1193 columnFamilyHandle.nativeHandle_);
7c673cae
FG
1194 }
1195
f67539c2
TL
1196 /**
1197 * Get the value associated with the specified key within column family.
1198 *
1199 * @param opt {@link org.rocksdb.ReadOptions} instance.
1200 * @param key the key to retrieve the value. It is using position and limit.
1201 * Supports direct buffer only.
1202 * @param value the out-value to receive the retrieved value.
1203 * It is using position and limit. Limit is set according to value size.
1204 * Supports direct buffer only.
1205 * @return The size of the actual value that matches the specified
1206 * {@code key} in byte. If the return value is greater than the
1207 * length of {@code value}, then it indicates that the size of the
1208 * input buffer {@code value} is insufficient and partial result will
1209 * be returned. RocksDB.NOT_FOUND will be returned if the value not
1210 * found.
1211 *
1212 * @throws RocksDBException thrown if error happens in underlying
1213 * native library.
1214 */
1215 public int get(final ReadOptions opt, final ByteBuffer key, final ByteBuffer value)
1216 throws RocksDBException {
1217 assert key.isDirect() && value.isDirect();
1218 int result = getDirect(nativeHandle_, opt.nativeHandle_, key, key.position(), key.remaining(),
1219 value, value.position(), value.remaining(), 0);
1220 if (result != NOT_FOUND) {
1221 value.limit(Math.min(value.limit(), value.position() + result));
1222 }
1223 key.position(key.limit());
1224 return result;
1225 }
1226
1227 /**
1228 * Get the value associated with the specified key within column family.
1229 *
1230 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
1231 * instance
1232 * @param opt {@link org.rocksdb.ReadOptions} instance.
1233 * @param key the key to retrieve the value. It is using position and limit.
1234 * Supports direct buffer only.
1235 * @param value the out-value to receive the retrieved value.
1236 * It is using position and limit. Limit is set according to value size.
1237 * Supports direct buffer only.
1238 * @return The size of the actual value that matches the specified
1239 * {@code key} in byte. If the return value is greater than the
1240 * length of {@code value}, then it indicates that the size of the
1241 * input buffer {@code value} is insufficient and partial result will
1242 * be returned. RocksDB.NOT_FOUND will be returned if the value not
1243 * found.
1244 *
1245 * @throws RocksDBException thrown if error happens in underlying
1246 * native library.
1247 */
1248 public int get(final ColumnFamilyHandle columnFamilyHandle, final ReadOptions opt,
1249 final ByteBuffer key, final ByteBuffer value) throws RocksDBException {
1250 assert key.isDirect() && value.isDirect();
1251 int result = getDirect(nativeHandle_, opt.nativeHandle_, key, key.position(), key.remaining(),
1252 value, value.position(), value.remaining(), columnFamilyHandle.nativeHandle_);
1253 if (result != NOT_FOUND) {
1254 value.limit(Math.min(value.limit(), value.position() + result));
1255 }
1256 key.position(key.limit());
1257 return result;
1258 }
1259
7c673cae 1260 /**
494da23a
TL
1261 * Remove the database entry for {@code key}. Requires that the key exists
1262 * and was not overwritten. It is not an error if the key did not exist
1263 * in the database.
7c673cae 1264 *
494da23a
TL
1265 * If a key is overwritten (by calling {@link #put(byte[], byte[])} multiple
1266 * times), then the result of calling SingleDelete() on this key is undefined.
1267 * SingleDelete() only behaves correctly if there has been only one Put()
1268 * for this key since the previous call to SingleDelete() for this key.
1269 *
1270 * This feature is currently an experimental performance optimization
1271 * for a very specific workload. It is up to the caller to ensure that
1272 * SingleDelete is only used for a key that is not deleted using Delete() or
1273 * written using Merge(). Mixing SingleDelete operations with Deletes and
1274 * Merges can result in undefined behavior.
1275 *
1276 * @param key Key to delete within database
7c673cae
FG
1277 *
1278 * @throws RocksDBException thrown if error happens in underlying
494da23a 1279 * native library.
7c673cae 1280 */
494da23a
TL
1281 @Experimental("Performance optimization for a very specific workload")
1282 public void singleDelete(final byte[] key) throws RocksDBException {
1283 singleDelete(nativeHandle_, key, key.length);
7c673cae
FG
1284 }
1285
1286 /**
494da23a
TL
1287 * Remove the database entry for {@code key}. Requires that the key exists
1288 * and was not overwritten. It is not an error if the key did not exist
1289 * in the database.
7c673cae 1290 *
494da23a
TL
1291 * If a key is overwritten (by calling {@link #put(byte[], byte[])} multiple
1292 * times), then the result of calling SingleDelete() on this key is undefined.
1293 * SingleDelete() only behaves correctly if there has been only one Put()
1294 * for this key since the previous call to SingleDelete() for this key.
1295 *
1296 * This feature is currently an experimental performance optimization
1297 * for a very specific workload. It is up to the caller to ensure that
1298 * SingleDelete is only used for a key that is not deleted using Delete() or
1299 * written using Merge(). Mixing SingleDelete operations with Deletes and
1300 * Merges can result in undefined behavior.
1301 *
1302 * @param columnFamilyHandle The column family to delete the key from
1303 * @param key Key to delete within database
7c673cae
FG
1304 *
1305 * @throws RocksDBException thrown if error happens in underlying
494da23a 1306 * native library.
7c673cae 1307 */
494da23a
TL
1308 @Experimental("Performance optimization for a very specific workload")
1309 public void singleDelete(final ColumnFamilyHandle columnFamilyHandle,
7c673cae 1310 final byte[] key) throws RocksDBException {
494da23a 1311 singleDelete(nativeHandle_, key, key.length,
7c673cae
FG
1312 columnFamilyHandle.nativeHandle_);
1313 }
1314
1315 /**
494da23a
TL
1316 * Remove the database entry for {@code key}. Requires that the key exists
1317 * and was not overwritten. It is not an error if the key did not exist
1318 * in the database.
7c673cae 1319 *
494da23a
TL
1320 * If a key is overwritten (by calling {@link #put(byte[], byte[])} multiple
1321 * times), then the result of calling SingleDelete() on this key is undefined.
1322 * SingleDelete() only behaves correctly if there has been only one Put()
1323 * for this key since the previous call to SingleDelete() for this key.
7c673cae 1324 *
494da23a
TL
1325 * This feature is currently an experimental performance optimization
1326 * for a very specific workload. It is up to the caller to ensure that
1327 * SingleDelete is only used for a key that is not deleted using Delete() or
1328 * written using Merge(). Mixing SingleDelete operations with Deletes and
1329 * Merges can result in undefined behavior.
7c673cae 1330 *
494da23a
TL
1331 * Note: consider setting {@link WriteOptions#setSync(boolean)} true.
1332 *
1333 * @param writeOpt Write options for the delete
1334 * @param key Key to delete within database
7c673cae
FG
1335 *
1336 * @throws RocksDBException thrown if error happens in underlying
494da23a 1337 * native library.
7c673cae 1338 */
494da23a
TL
1339 @Experimental("Performance optimization for a very specific workload")
1340 public void singleDelete(final WriteOptions writeOpt, final byte[] key)
1341 throws RocksDBException {
1342 singleDelete(nativeHandle_, writeOpt.nativeHandle_, key, key.length);
7c673cae
FG
1343 }
1344
1345 /**
494da23a
TL
1346 * Remove the database entry for {@code key}. Requires that the key exists
1347 * and was not overwritten. It is not an error if the key did not exist
1348 * in the database.
7c673cae 1349 *
494da23a
TL
1350 * If a key is overwritten (by calling {@link #put(byte[], byte[])} multiple
1351 * times), then the result of calling SingleDelete() on this key is undefined.
1352 * SingleDelete() only behaves correctly if there has been only one Put()
1353 * for this key since the previous call to SingleDelete() for this key.
1354 *
1355 * This feature is currently an experimental performance optimization
1356 * for a very specific workload. It is up to the caller to ensure that
1357 * SingleDelete is only used for a key that is not deleted using Delete() or
1358 * written using Merge(). Mixing SingleDelete operations with Deletes and
1359 * Merges can result in undefined behavior.
1360 *
1361 * Note: consider setting {@link WriteOptions#setSync(boolean)} true.
1362 *
1363 * @param columnFamilyHandle The column family to delete the key from
1364 * @param writeOpt Write options for the delete
1365 * @param key Key to delete within database
7c673cae
FG
1366 *
1367 * @throws RocksDBException thrown if error happens in underlying
494da23a 1368 * native library.
7c673cae 1369 */
494da23a
TL
1370 @Experimental("Performance optimization for a very specific workload")
1371 public void singleDelete(final ColumnFamilyHandle columnFamilyHandle,
1372 final WriteOptions writeOpt, final byte[] key) throws RocksDBException {
1373 singleDelete(nativeHandle_, writeOpt.nativeHandle_, key, key.length,
1374 columnFamilyHandle.nativeHandle_);
7c673cae
FG
1375 }
1376
7c673cae
FG
1377
1378 /**
494da23a
TL
1379 * Removes the database entries in the range ["beginKey", "endKey"), i.e.,
1380 * including "beginKey" and excluding "endKey". a non-OK status on error. It
1381 * is not an error if no keys exist in the range ["beginKey", "endKey").
7c673cae 1382 *
494da23a
TL
1383 * Delete the database entry (if any) for "key". Returns OK on success, and a
1384 * non-OK status on error. It is not an error if "key" did not exist in the
1385 * database.
7c673cae 1386 *
494da23a
TL
1387 * @param beginKey First key to delete within database (inclusive)
1388 * @param endKey Last key to delete within database (exclusive)
1389 *
1390 * @throws RocksDBException thrown if error happens in underlying native
1391 * library.
7c673cae 1392 */
494da23a
TL
1393 public void deleteRange(final byte[] beginKey, final byte[] endKey)
1394 throws RocksDBException {
1395 deleteRange(nativeHandle_, beginKey, 0, beginKey.length, endKey, 0,
1396 endKey.length);
7c673cae
FG
1397 }
1398
1399 /**
494da23a
TL
1400 * Removes the database entries in the range ["beginKey", "endKey"), i.e.,
1401 * including "beginKey" and excluding "endKey". a non-OK status on error. It
1402 * is not an error if no keys exist in the range ["beginKey", "endKey").
7c673cae 1403 *
494da23a
TL
1404 * Delete the database entry (if any) for "key". Returns OK on success, and a
1405 * non-OK status on error. It is not an error if "key" did not exist in the
1406 * database.
7c673cae 1407 *
494da23a
TL
1408 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle} instance
1409 * @param beginKey First key to delete within database (inclusive)
1410 * @param endKey Last key to delete within database (exclusive)
1411 *
1412 * @throws RocksDBException thrown if error happens in underlying native
1413 * library.
7c673cae 1414 */
494da23a
TL
1415 public void deleteRange(final ColumnFamilyHandle columnFamilyHandle,
1416 final byte[] beginKey, final byte[] endKey) throws RocksDBException {
1417 deleteRange(nativeHandle_, beginKey, 0, beginKey.length, endKey, 0,
1418 endKey.length, columnFamilyHandle.nativeHandle_);
7c673cae
FG
1419 }
1420
1421 /**
494da23a
TL
1422 * Removes the database entries in the range ["beginKey", "endKey"), i.e.,
1423 * including "beginKey" and excluding "endKey". a non-OK status on error. It
1424 * is not an error if no keys exist in the range ["beginKey", "endKey").
7c673cae 1425 *
494da23a
TL
1426 * Delete the database entry (if any) for "key". Returns OK on success, and a
1427 * non-OK status on error. It is not an error if "key" did not exist in the
1428 * database.
1429 *
1430 * @param writeOpt WriteOptions to be used with delete operation
1431 * @param beginKey First key to delete within database (inclusive)
1432 * @param endKey Last key to delete within database (exclusive)
7c673cae
FG
1433 *
1434 * @throws RocksDBException thrown if error happens in underlying
494da23a 1435 * native library.
7c673cae 1436 */
494da23a
TL
1437 public void deleteRange(final WriteOptions writeOpt, final byte[] beginKey,
1438 final byte[] endKey) throws RocksDBException {
1439 deleteRange(nativeHandle_, writeOpt.nativeHandle_, beginKey, 0,
1440 beginKey.length, endKey, 0, endKey.length);
7c673cae
FG
1441 }
1442
1443 /**
494da23a
TL
1444 * Removes the database entries in the range ["beginKey", "endKey"), i.e.,
1445 * including "beginKey" and excluding "endKey". a non-OK status on error. It
1446 * is not an error if no keys exist in the range ["beginKey", "endKey").
7c673cae 1447 *
494da23a
TL
1448 * Delete the database entry (if any) for "key". Returns OK on success, and a
1449 * non-OK status on error. It is not an error if "key" did not exist in the
1450 * database.
7c673cae 1451 *
494da23a
TL
1452 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle} instance
1453 * @param writeOpt WriteOptions to be used with delete operation
1454 * @param beginKey First key to delete within database (included)
1455 * @param endKey Last key to delete within database (excluded)
7c673cae 1456 *
494da23a
TL
1457 * @throws RocksDBException thrown if error happens in underlying native
1458 * library.
7c673cae 1459 */
494da23a
TL
1460 public void deleteRange(final ColumnFamilyHandle columnFamilyHandle,
1461 final WriteOptions writeOpt, final byte[] beginKey, final byte[] endKey)
1462 throws RocksDBException {
1463 deleteRange(nativeHandle_, writeOpt.nativeHandle_, beginKey, 0,
1464 beginKey.length, endKey, 0, endKey.length,
1465 columnFamilyHandle.nativeHandle_);
7c673cae
FG
1466 }
1467
494da23a 1468
7c673cae 1469 /**
494da23a 1470 * Add merge operand for key/value pair.
7c673cae 1471 *
494da23a
TL
1472 * @param key the specified key to be merged.
1473 * @param value the value to be merged with the current value for the
1474 * specified key.
7c673cae
FG
1475 *
1476 * @throws RocksDBException thrown if error happens in underlying
1477 * native library.
1478 */
494da23a
TL
1479 public void merge(final byte[] key, final byte[] value)
1480 throws RocksDBException {
1481 merge(nativeHandle_, key, 0, key.length, value, 0, value.length);
7c673cae
FG
1482 }
1483
1484 /**
494da23a 1485 * Add merge operand for key/value pair.
7c673cae 1486 *
494da23a
TL
1487 * @param key the specified key to be merged.
1488 * @param offset the offset of the "key" array to be used, must be
1489 * non-negative and no larger than "key".length
1490 * @param len the length of the "key" array to be used, must be non-negative
1491 * and no larger than ("key".length - offset)
1492 * @param value the value to be merged with the current value for the
1493 * specified key.
1494 * @param vOffset the offset of the "value" array to be used, must be
1495 * non-negative and no longer than "key".length
1496 * @param vLen the length of the "value" array to be used, must be
1497 * non-negative and must be non-negative and no larger than
1498 * ("value".length - offset)
7c673cae
FG
1499 *
1500 * @throws RocksDBException thrown if error happens in underlying
1501 * native library.
494da23a 1502 * @throws IndexOutOfBoundsException if an offset or length is out of bounds
7c673cae 1503 */
494da23a
TL
1504 public void merge(final byte[] key, int offset, int len, final byte[] value,
1505 final int vOffset, final int vLen) throws RocksDBException {
1506 checkBounds(offset, len, key.length);
1507 checkBounds(vOffset, vLen, value.length);
1508 merge(nativeHandle_, key, offset, len, value, vOffset, vLen);
7c673cae
FG
1509 }
1510
1511 /**
494da23a 1512 * Add merge operand for key/value pair in a ColumnFamily.
7c673cae 1513 *
494da23a
TL
1514 * @param columnFamilyHandle {@link ColumnFamilyHandle} instance
1515 * @param key the specified key to be merged.
1516 * @param value the value to be merged with the current value for
1517 * the specified key.
7c673cae
FG
1518 *
1519 * @throws RocksDBException thrown if error happens in underlying
1520 * native library.
1521 */
494da23a
TL
1522 public void merge(final ColumnFamilyHandle columnFamilyHandle,
1523 final byte[] key, final byte[] value) throws RocksDBException {
1524 merge(nativeHandle_, key, 0, key.length, value, 0, value.length,
1525 columnFamilyHandle.nativeHandle_);
7c673cae
FG
1526 }
1527
1528 /**
494da23a 1529 * Add merge operand for key/value pair in a ColumnFamily.
7c673cae 1530 *
494da23a
TL
1531 * @param columnFamilyHandle {@link ColumnFamilyHandle} instance
1532 * @param key the specified key to be merged.
1533 * @param offset the offset of the "key" array to be used, must be
1534 * non-negative and no larger than "key".length
1535 * @param len the length of the "key" array to be used, must be non-negative
1536 * and no larger than ("key".length - offset)
1537 * @param value the value to be merged with the current value for
1538 * the specified key.
1539 * @param vOffset the offset of the "value" array to be used, must be
1540 * non-negative and no longer than "key".length
1541 * @param vLen the length of the "value" array to be used, must be
1542 * must be non-negative and no larger than ("value".length - offset)
7c673cae
FG
1543 *
1544 * @throws RocksDBException thrown if error happens in underlying
1545 * native library.
494da23a
TL
1546 * @throws IndexOutOfBoundsException if an offset or length is out of bounds
1547 */
1548 public void merge(final ColumnFamilyHandle columnFamilyHandle,
1549 final byte[] key, final int offset, final int len, final byte[] value,
1550 final int vOffset, final int vLen) throws RocksDBException {
1551 checkBounds(offset, len, key.length);
1552 checkBounds(vOffset, vLen, value.length);
1553 merge(nativeHandle_, key, offset, len, value, vOffset, vLen,
1554 columnFamilyHandle.nativeHandle_);
1555 }
1556
1557 /**
1558 * Add merge operand for key/value pair.
7c673cae 1559 *
494da23a
TL
1560 * @param writeOpts {@link WriteOptions} for this write.
1561 * @param key the specified key to be merged.
1562 * @param value the value to be merged with the current value for
1563 * the specified key.
1564 *
1565 * @throws RocksDBException thrown if error happens in underlying
1566 * native library.
7c673cae 1567 */
494da23a
TL
1568 public void merge(final WriteOptions writeOpts, final byte[] key,
1569 final byte[] value) throws RocksDBException {
1570 merge(nativeHandle_, writeOpts.nativeHandle_,
1571 key, 0, key.length, value, 0, value.length);
7c673cae
FG
1572 }
1573
1574 /**
494da23a 1575 * Add merge operand for key/value pair.
7c673cae 1576 *
494da23a
TL
1577 * @param writeOpts {@link WriteOptions} for this write.
1578 * @param key the specified key to be merged.
1579 * @param offset the offset of the "key" array to be used, must be
1580 * non-negative and no larger than "key".length
1581 * @param len the length of the "key" array to be used, must be non-negative
1582 * and no larger than ("value".length - offset)
1583 * @param value the value to be merged with the current value for
1584 * the specified key.
1585 * @param vOffset the offset of the "value" array to be used, must be
1586 * non-negative and no longer than "key".length
1587 * @param vLen the length of the "value" array to be used, must be
1588 * non-negative and no larger than ("value".length - offset)
7c673cae
FG
1589 *
1590 * @throws RocksDBException thrown if error happens in underlying
1591 * native library.
494da23a 1592 * @throws IndexOutOfBoundsException if an offset or length is out of bounds
7c673cae 1593 */
494da23a
TL
1594 public void merge(final WriteOptions writeOpts,
1595 final byte[] key, final int offset, final int len,
1596 final byte[] value, final int vOffset, final int vLen)
7c673cae 1597 throws RocksDBException {
494da23a
TL
1598 checkBounds(offset, len, key.length);
1599 checkBounds(vOffset, vLen, value.length);
1600 merge(nativeHandle_, writeOpts.nativeHandle_,
1601 key, offset, len, value, vOffset, vLen);
7c673cae
FG
1602 }
1603
f67539c2
TL
1604 /**
1605 * Delete the database entry (if any) for "key". Returns OK on
1606 * success, and a non-OK status on error. It is not an error if "key"
1607 * did not exist in the database.
1608 *
1609 * @param writeOpt WriteOptions to be used with delete operation
1610 * @param key Key to delete within database. It is using position and limit.
1611 * Supports direct buffer only.
1612 *
1613 * @throws RocksDBException thrown if error happens in underlying
1614 * native library.
1615 */
1616 public void delete(final WriteOptions writeOpt, final ByteBuffer key) throws RocksDBException {
1617 assert key.isDirect();
1618 deleteDirect(nativeHandle_, writeOpt.nativeHandle_, key, key.position(), key.remaining(), 0);
1619 key.position(key.limit());
1620 }
1621
1622 /**
1623 * Delete the database entry (if any) for "key". Returns OK on
1624 * success, and a non-OK status on error. It is not an error if "key"
1625 * did not exist in the database.
1626 *
1627 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
1628 * instance
1629 * @param writeOpt WriteOptions to be used with delete operation
1630 * @param key Key to delete within database. It is using position and limit.
1631 * Supports direct buffer only.
1632 *
1633 * @throws RocksDBException thrown if error happens in underlying
1634 * native library.
1635 */
1636 public void delete(final ColumnFamilyHandle columnFamilyHandle, final WriteOptions writeOpt,
1637 final ByteBuffer key) throws RocksDBException {
1638 assert key.isDirect();
1639 deleteDirect(nativeHandle_, writeOpt.nativeHandle_, key, key.position(), key.remaining(),
1640 columnFamilyHandle.nativeHandle_);
1641 key.position(key.limit());
1642 }
1643
7c673cae 1644 /**
494da23a 1645 * Add merge operand for key/value pair.
7c673cae 1646 *
494da23a
TL
1647 * @param columnFamilyHandle {@link ColumnFamilyHandle} instance
1648 * @param writeOpts {@link WriteOptions} for this write.
1649 * @param key the specified key to be merged.
1650 * @param value the value to be merged with the current value for the
1651 * specified key.
7c673cae
FG
1652 *
1653 * @throws RocksDBException thrown if error happens in underlying
1654 * native library.
7c673cae 1655 */
494da23a
TL
1656 public void merge(final ColumnFamilyHandle columnFamilyHandle,
1657 final WriteOptions writeOpts, final byte[] key, final byte[] value)
7c673cae 1658 throws RocksDBException {
494da23a
TL
1659 merge(nativeHandle_, writeOpts.nativeHandle_,
1660 key, 0, key.length, value, 0, value.length,
1661 columnFamilyHandle.nativeHandle_);
7c673cae
FG
1662 }
1663
1664 /**
494da23a 1665 * Add merge operand for key/value pair.
7c673cae 1666 *
494da23a
TL
1667 * @param columnFamilyHandle {@link ColumnFamilyHandle} instance
1668 * @param writeOpts {@link WriteOptions} for this write.
1669 * @param key the specified key to be merged.
1670 * @param offset the offset of the "key" array to be used, must be
1671 * non-negative and no larger than "key".length
1672 * @param len the length of the "key" array to be used, must be non-negative
1673 * and no larger than ("key".length - offset)
1674 * @param value the value to be merged with the current value for
1675 * the specified key.
1676 * @param vOffset the offset of the "value" array to be used, must be
1677 * non-negative and no longer than "key".length
1678 * @param vLen the length of the "value" array to be used, must be
1679 * non-negative and no larger than ("value".length - offset)
7c673cae
FG
1680 *
1681 * @throws RocksDBException thrown if error happens in underlying
1682 * native library.
494da23a 1683 * @throws IndexOutOfBoundsException if an offset or length is out of bounds
7c673cae 1684 */
494da23a
TL
1685 public void merge(
1686 final ColumnFamilyHandle columnFamilyHandle, final WriteOptions writeOpts,
1687 final byte[] key, final int offset, final int len,
1688 final byte[] value, final int vOffset, final int vLen)
7c673cae 1689 throws RocksDBException {
494da23a
TL
1690 checkBounds(offset, len, key.length);
1691 checkBounds(vOffset, vLen, value.length);
1692 merge(nativeHandle_, writeOpts.nativeHandle_,
1693 key, offset, len, value, vOffset, vLen,
7c673cae
FG
1694 columnFamilyHandle.nativeHandle_);
1695 }
1696
1697 /**
494da23a 1698 * Apply the specified updates to the database.
7c673cae 1699 *
494da23a
TL
1700 * @param writeOpts WriteOptions instance
1701 * @param updates WriteBatch instance
7c673cae 1702 *
494da23a
TL
1703 * @throws RocksDBException thrown if error happens in underlying
1704 * native library.
1705 */
1706 public void write(final WriteOptions writeOpts, final WriteBatch updates)
1707 throws RocksDBException {
1708 write0(nativeHandle_, writeOpts.nativeHandle_, updates.nativeHandle_);
1709 }
1710
1711 /**
1712 * Apply the specified updates to the database.
7c673cae 1713 *
494da23a
TL
1714 * @param writeOpts WriteOptions instance
1715 * @param updates WriteBatchWithIndex instance
7c673cae
FG
1716 *
1717 * @throws RocksDBException thrown if error happens in underlying
494da23a 1718 * native library.
7c673cae 1719 */
494da23a
TL
1720 public void write(final WriteOptions writeOpts,
1721 final WriteBatchWithIndex updates) throws RocksDBException {
1722 write1(nativeHandle_, writeOpts.nativeHandle_, updates.nativeHandle_);
7c673cae
FG
1723 }
1724
494da23a
TL
1725 // TODO(AR) we should improve the #get() API, returning -1 (RocksDB.NOT_FOUND) is not very nice
1726 // when we could communicate better status into, also the C++ code show that -2 could be returned
1727
7c673cae 1728 /**
494da23a 1729 * Get the value associated with the specified key within column family*
7c673cae 1730 *
494da23a
TL
1731 * @param key the key to retrieve the value.
1732 * @param value the out-value to receive the retrieved value.
7c673cae 1733 *
494da23a
TL
1734 * @return The size of the actual value that matches the specified
1735 * {@code key} in byte. If the return value is greater than the
1736 * length of {@code value}, then it indicates that the size of the
1737 * input buffer {@code value} is insufficient and partial result will
1738 * be returned. RocksDB.NOT_FOUND will be returned if the value not
1739 * found.
7c673cae
FG
1740 *
1741 * @throws RocksDBException thrown if error happens in underlying
494da23a 1742 * native library.
7c673cae 1743 */
494da23a
TL
1744 public int get(final byte[] key, final byte[] value) throws RocksDBException {
1745 return get(nativeHandle_, key, 0, key.length, value, 0, value.length);
7c673cae
FG
1746 }
1747
1748 /**
494da23a 1749 * Get the value associated with the specified key within column family*
7c673cae 1750 *
494da23a
TL
1751 * @param key the key to retrieve the value.
1752 * @param offset the offset of the "key" array to be used, must be
1753 * non-negative and no larger than "key".length
1754 * @param len the length of the "key" array to be used, must be non-negative
1755 * and no larger than ("key".length - offset)
1756 * @param value the out-value to receive the retrieved value.
1757 * @param vOffset the offset of the "value" array to be used, must be
1758 * non-negative and no longer than "value".length
1759 * @param vLen the length of the "value" array to be used, must be
1760 * non-negative and and no larger than ("value".length - offset)
7c673cae 1761 *
494da23a
TL
1762 * @return The size of the actual value that matches the specified
1763 * {@code key} in byte. If the return value is greater than the
1764 * length of {@code value}, then it indicates that the size of the
1765 * input buffer {@code value} is insufficient and partial result will
1766 * be returned. RocksDB.NOT_FOUND will be returned if the value not
1767 * found.
7c673cae
FG
1768 *
1769 * @throws RocksDBException thrown if error happens in underlying
494da23a 1770 * native library.
7c673cae 1771 */
494da23a
TL
1772 public int get(final byte[] key, final int offset, final int len,
1773 final byte[] value, final int vOffset, final int vLen)
7c673cae 1774 throws RocksDBException {
494da23a
TL
1775 checkBounds(offset, len, key.length);
1776 checkBounds(vOffset, vLen, value.length);
1777 return get(nativeHandle_, key, offset, len, value, vOffset, vLen);
7c673cae
FG
1778 }
1779
1780 /**
494da23a 1781 * Get the value associated with the specified key within column family.
7c673cae 1782 *
494da23a
TL
1783 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
1784 * instance
1785 * @param key the key to retrieve the value.
1786 * @param value the out-value to receive the retrieved value.
1787 * @return The size of the actual value that matches the specified
1788 * {@code key} in byte. If the return value is greater than the
1789 * length of {@code value}, then it indicates that the size of the
1790 * input buffer {@code value} is insufficient and partial result will
1791 * be returned. RocksDB.NOT_FOUND will be returned if the value not
1792 * found.
7c673cae
FG
1793 *
1794 * @throws RocksDBException thrown if error happens in underlying
494da23a 1795 * native library.
7c673cae 1796 */
494da23a
TL
1797 public int get(final ColumnFamilyHandle columnFamilyHandle, final byte[] key,
1798 final byte[] value) throws RocksDBException, IllegalArgumentException {
1799 return get(nativeHandle_, key, 0, key.length, value, 0, value.length,
7c673cae
FG
1800 columnFamilyHandle.nativeHandle_);
1801 }
1802
1803 /**
494da23a 1804 * Get the value associated with the specified key within column family.
7c673cae 1805 *
494da23a
TL
1806 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
1807 * instance
1808 * @param key the key to retrieve the value.
1809 * @param offset the offset of the "key" array to be used, must be
1810 * non-negative and no larger than "key".length
1811 * @param len the length of the "key" array to be used, must be non-negative
1812 * an no larger than ("key".length - offset)
1813 * @param value the out-value to receive the retrieved value.
1814 * @param vOffset the offset of the "value" array to be used, must be
1815 * non-negative and no longer than "key".length
1816 * @param vLen the length of the "value" array to be used, must be
1817 * non-negative and no larger than ("value".length - offset)
7c673cae 1818 *
494da23a
TL
1819 * @return The size of the actual value that matches the specified
1820 * {@code key} in byte. If the return value is greater than the
1821 * length of {@code value}, then it indicates that the size of the
1822 * input buffer {@code value} is insufficient and partial result will
1823 * be returned. RocksDB.NOT_FOUND will be returned if the value not
1824 * found.
1825 *
1826 * @throws RocksDBException thrown if error happens in underlying
1827 * native library.
1828 */
1829 public int get(final ColumnFamilyHandle columnFamilyHandle, final byte[] key,
1830 final int offset, final int len, final byte[] value, final int vOffset,
1831 final int vLen) throws RocksDBException, IllegalArgumentException {
1832 checkBounds(offset, len, key.length);
1833 checkBounds(vOffset, vLen, value.length);
1834 return get(nativeHandle_, key, offset, len, value, vOffset, vLen,
1835 columnFamilyHandle.nativeHandle_);
1836 }
1837
1838 /**
1839 * Get the value associated with the specified key.
1840 *
1841 * @param opt {@link org.rocksdb.ReadOptions} instance.
1842 * @param key the key to retrieve the value.
1843 * @param value the out-value to receive the retrieved value.
1844 * @return The size of the actual value that matches the specified
1845 * {@code key} in byte. If the return value is greater than the
1846 * length of {@code value}, then it indicates that the size of the
1847 * input buffer {@code value} is insufficient and partial result will
1848 * be returned. RocksDB.NOT_FOUND will be returned if the value not
1849 * found.
1850 *
1851 * @throws RocksDBException thrown if error happens in underlying
1852 * native library.
1853 */
1854 public int get(final ReadOptions opt, final byte[] key,
1855 final byte[] value) throws RocksDBException {
1856 return get(nativeHandle_, opt.nativeHandle_,
1857 key, 0, key.length, value, 0, value.length);
1858 }
1859
1860 /**
1861 * Get the value associated with the specified key.
1862 *
1863 * @param opt {@link org.rocksdb.ReadOptions} instance.
1864 * @param key the key to retrieve the value.
1865 * @param offset the offset of the "key" array to be used, must be
1866 * non-negative and no larger than "key".length
1867 * @param len the length of the "key" array to be used, must be non-negative
1868 * and no larger than ("key".length - offset)
1869 * @param value the out-value to receive the retrieved value.
1870 * @param vOffset the offset of the "value" array to be used, must be
1871 * non-negative and no longer than "key".length
1872 * @param vLen the length of the "value" array to be used, must be
1873 * non-negative and no larger than ("value".length - offset)
1874 * @return The size of the actual value that matches the specified
1875 * {@code key} in byte. If the return value is greater than the
1876 * length of {@code value}, then it indicates that the size of the
1877 * input buffer {@code value} is insufficient and partial result will
1878 * be returned. RocksDB.NOT_FOUND will be returned if the value not
1879 * found.
1880 *
1881 * @throws RocksDBException thrown if error happens in underlying
1882 * native library.
1883 */
1884 public int get(final ReadOptions opt, final byte[] key, final int offset,
1885 final int len, final byte[] value, final int vOffset, final int vLen)
1886 throws RocksDBException {
1887 checkBounds(offset, len, key.length);
1888 checkBounds(vOffset, vLen, value.length);
1889 return get(nativeHandle_, opt.nativeHandle_,
1890 key, offset, len, value, vOffset, vLen);
1891 }
1892
1893 /**
1894 * Get the value associated with the specified key within column family.
7c673cae
FG
1895 *
1896 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
1897 * instance
494da23a
TL
1898 * @param opt {@link org.rocksdb.ReadOptions} instance.
1899 * @param key the key to retrieve the value.
1900 * @param value the out-value to receive the retrieved value.
1901 * @return The size of the actual value that matches the specified
1902 * {@code key} in byte. If the return value is greater than the
1903 * length of {@code value}, then it indicates that the size of the
1904 * input buffer {@code value} is insufficient and partial result will
1905 * be returned. RocksDB.NOT_FOUND will be returned if the value not
1906 * found.
1907 *
1908 * @throws RocksDBException thrown if error happens in underlying
1909 * native library.
1910 */
1911 public int get(final ColumnFamilyHandle columnFamilyHandle,
1912 final ReadOptions opt, final byte[] key, final byte[] value)
1913 throws RocksDBException {
1914 return get(nativeHandle_, opt.nativeHandle_, key, 0, key.length, value,
1915 0, value.length, columnFamilyHandle.nativeHandle_);
1916 }
1917
1918 /**
1919 * Get the value associated with the specified key within column family.
1920 *
1921 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
1922 * instance
1923 * @param opt {@link org.rocksdb.ReadOptions} instance.
1924 * @param key the key to retrieve the value.
1925 * @param offset the offset of the "key" array to be used, must be
1926 * non-negative and no larger than "key".length
1927 * @param len the length of the "key" array to be used, must be
1928 * non-negative and and no larger than ("key".length - offset)
1929 * @param value the out-value to receive the retrieved value.
1930 * @param vOffset the offset of the "value" array to be used, must be
1931 * non-negative and no longer than "key".length
1932 * @param vLen the length of the "value" array to be used, and must be
1933 * non-negative and no larger than ("value".length - offset)
1934 * @return The size of the actual value that matches the specified
1935 * {@code key} in byte. If the return value is greater than the
1936 * length of {@code value}, then it indicates that the size of the
1937 * input buffer {@code value} is insufficient and partial result will
1938 * be returned. RocksDB.NOT_FOUND will be returned if the value not
1939 * found.
1940 *
1941 * @throws RocksDBException thrown if error happens in underlying
1942 * native library.
1943 */
1944 public int get(final ColumnFamilyHandle columnFamilyHandle,
1945 final ReadOptions opt, final byte[] key, final int offset, final int len,
1946 final byte[] value, final int vOffset, final int vLen)
1947 throws RocksDBException {
1948 checkBounds(offset, len, key.length);
1949 checkBounds(vOffset, vLen, value.length);
1950 return get(nativeHandle_, opt.nativeHandle_, key, offset, len, value,
1951 vOffset, vLen, columnFamilyHandle.nativeHandle_);
1952 }
1953
1954 /**
1955 * The simplified version of get which returns a new byte array storing
1956 * the value associated with the specified input key if any. null will be
1957 * returned if the specified key is not found.
1958 *
1959 * @param key the key retrieve the value.
1960 * @return a byte array storing the value associated with the input key if
1961 * any. null if it does not find the specified key.
1962 *
1963 * @throws RocksDBException thrown if error happens in underlying
1964 * native library.
1965 */
1966 public byte[] get(final byte[] key) throws RocksDBException {
1967 return get(nativeHandle_, key, 0, key.length);
1968 }
1969
1970 /**
1971 * The simplified version of get which returns a new byte array storing
1972 * the value associated with the specified input key if any. null will be
1973 * returned if the specified key is not found.
1974 *
1975 * @param key the key retrieve the value.
1976 * @param offset the offset of the "key" array to be used, must be
1977 * non-negative and no larger than "key".length
1978 * @param len the length of the "key" array to be used, must be non-negative
1979 * and no larger than ("key".length - offset)
1980 * @return a byte array storing the value associated with the input key if
1981 * any. null if it does not find the specified key.
1982 *
1983 * @throws RocksDBException thrown if error happens in underlying
1984 * native library.
1985 */
1986 public byte[] get(final byte[] key, final int offset,
1987 final int len) throws RocksDBException {
1988 checkBounds(offset, len, key.length);
1989 return get(nativeHandle_, key, offset, len);
1990 }
1991
1992 /**
1993 * The simplified version of get which returns a new byte array storing
1994 * the value associated with the specified input key if any. null will be
1995 * returned if the specified key is not found.
1996 *
1997 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
1998 * instance
1999 * @param key the key retrieve the value.
2000 * @return a byte array storing the value associated with the input key if
2001 * any. null if it does not find the specified key.
2002 *
2003 * @throws RocksDBException thrown if error happens in underlying
2004 * native library.
2005 */
2006 public byte[] get(final ColumnFamilyHandle columnFamilyHandle,
2007 final byte[] key) throws RocksDBException {
2008 return get(nativeHandle_, key, 0, key.length,
2009 columnFamilyHandle.nativeHandle_);
2010 }
2011
2012 /**
2013 * The simplified version of get which returns a new byte array storing
2014 * the value associated with the specified input key if any. null will be
2015 * returned if the specified key is not found.
2016 *
2017 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
2018 * instance
2019 * @param key the key retrieve the value.
2020 * @param offset the offset of the "key" array to be used, must be
2021 * non-negative and no larger than "key".length
2022 * @param len the length of the "key" array to be used, must be non-negative
2023 * and no larger than ("key".length - offset)
2024 * @return a byte array storing the value associated with the input key if
2025 * any. null if it does not find the specified key.
2026 *
2027 * @throws RocksDBException thrown if error happens in underlying
2028 * native library.
2029 */
2030 public byte[] get(final ColumnFamilyHandle columnFamilyHandle,
2031 final byte[] key, final int offset, final int len)
2032 throws RocksDBException {
2033 checkBounds(offset, len, key.length);
2034 return get(nativeHandle_, key, offset, len,
2035 columnFamilyHandle.nativeHandle_);
2036 }
2037
2038 /**
2039 * The simplified version of get which returns a new byte array storing
2040 * the value associated with the specified input key if any. null will be
2041 * returned if the specified key is not found.
2042 *
2043 * @param key the key retrieve the value.
2044 * @param opt Read options.
2045 * @return a byte array storing the value associated with the input key if
2046 * any. null if it does not find the specified key.
2047 *
2048 * @throws RocksDBException thrown if error happens in underlying
2049 * native library.
2050 */
2051 public byte[] get(final ReadOptions opt, final byte[] key)
2052 throws RocksDBException {
2053 return get(nativeHandle_, opt.nativeHandle_, key, 0, key.length);
2054 }
2055
2056 /**
2057 * The simplified version of get which returns a new byte array storing
2058 * the value associated with the specified input key if any. null will be
2059 * returned if the specified key is not found.
2060 *
2061 * @param key the key retrieve the value.
2062 * @param offset the offset of the "key" array to be used, must be
2063 * non-negative and no larger than "key".length
2064 * @param len the length of the "key" array to be used, must be non-negative
2065 * and no larger than ("key".length - offset)
2066 * @param opt Read options.
2067 * @return a byte array storing the value associated with the input key if
2068 * any. null if it does not find the specified key.
2069 *
2070 * @throws RocksDBException thrown if error happens in underlying
2071 * native library.
2072 */
2073 public byte[] get(final ReadOptions opt, final byte[] key, final int offset,
2074 final int len) throws RocksDBException {
2075 checkBounds(offset, len, key.length);
2076 return get(nativeHandle_, opt.nativeHandle_, key, offset, len);
2077 }
2078
2079 /**
2080 * The simplified version of get which returns a new byte array storing
2081 * the value associated with the specified input key if any. null will be
2082 * returned if the specified key is not found.
2083 *
2084 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
2085 * instance
2086 * @param key the key retrieve the value.
2087 * @param opt Read options.
2088 * @return a byte array storing the value associated with the input key if
2089 * any. null if it does not find the specified key.
2090 *
2091 * @throws RocksDBException thrown if error happens in underlying
2092 * native library.
2093 */
2094 public byte[] get(final ColumnFamilyHandle columnFamilyHandle,
2095 final ReadOptions opt, final byte[] key) throws RocksDBException {
2096 return get(nativeHandle_, opt.nativeHandle_, key, 0, key.length,
2097 columnFamilyHandle.nativeHandle_);
2098 }
2099
2100 /**
2101 * The simplified version of get which returns a new byte array storing
2102 * the value associated with the specified input key if any. null will be
2103 * returned if the specified key is not found.
2104 *
2105 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
2106 * instance
2107 * @param key the key retrieve the value.
2108 * @param offset the offset of the "key" array to be used, must be
2109 * non-negative and no larger than "key".length
2110 * @param len the length of the "key" array to be used, must be non-negative
2111 * and no larger than ("key".length - offset)
2112 * @param opt Read options.
2113 * @return a byte array storing the value associated with the input key if
2114 * any. null if it does not find the specified key.
2115 *
2116 * @throws RocksDBException thrown if error happens in underlying
2117 * native library.
2118 */
2119 public byte[] get(final ColumnFamilyHandle columnFamilyHandle,
2120 final ReadOptions opt, final byte[] key, final int offset, final int len)
2121 throws RocksDBException {
2122 checkBounds(offset, len, key.length);
2123 return get(nativeHandle_, opt.nativeHandle_, key, offset, len,
2124 columnFamilyHandle.nativeHandle_);
2125 }
2126
494da23a
TL
2127 /**
2128 * Takes a list of keys, and returns a list of values for the given list of
2129 * keys. List will contain null for keys which could not be found.
2130 *
2131 * @param keys List of keys for which values need to be retrieved.
2132 * @return List of values for the given list of keys. List will contain
2133 * null for keys which could not be found.
2134 *
2135 * @throws RocksDBException thrown if error happens in underlying
2136 * native library.
2137 */
2138 public List<byte[]> multiGetAsList(final List<byte[]> keys)
2139 throws RocksDBException {
2140 assert(keys.size() != 0);
2141
2142 final byte[][] keysArray = keys.toArray(new byte[keys.size()][]);
1e59de90
TL
2143 final int[] keyOffsets = new int[keysArray.length];
2144 final int[] keyLengths = new int[keysArray.length];
494da23a
TL
2145 for(int i = 0; i < keyLengths.length; i++) {
2146 keyLengths[i] = keysArray[i].length;
2147 }
2148
2149 return Arrays.asList(multiGet(nativeHandle_, keysArray, keyOffsets,
2150 keyLengths));
2151 }
2152
2153 /**
2154 * Returns a list of values for the given list of keys. List will contain
2155 * null for keys which could not be found.
2156 * <p>
2157 * Note: Every key needs to have a related column family name in
2158 * {@code columnFamilyHandleList}.
2159 * </p>
2160 *
2161 * @param columnFamilyHandleList {@link java.util.List} containing
2162 * {@link org.rocksdb.ColumnFamilyHandle} instances.
2163 * @param keys List of keys for which values need to be retrieved.
2164 * @return List of values for the given list of keys. List will contain
2165 * null for keys which could not be found.
2166 *
2167 * @throws RocksDBException thrown if error happens in underlying
2168 * native library.
2169 * @throws IllegalArgumentException thrown if the size of passed keys is not
2170 * equal to the amount of passed column family handles.
2171 */
2172 public List<byte[]> multiGetAsList(
2173 final List<ColumnFamilyHandle> columnFamilyHandleList,
2174 final List<byte[]> keys) throws RocksDBException,
2175 IllegalArgumentException {
2176 assert(keys.size() != 0);
2177 // Check if key size equals cfList size. If not a exception must be
2178 // thrown. If not a Segmentation fault happens.
2179 if (keys.size() != columnFamilyHandleList.size()) {
2180 throw new IllegalArgumentException(
2181 "For each key there must be a ColumnFamilyHandle.");
2182 }
2183 final long[] cfHandles = new long[columnFamilyHandleList.size()];
2184 for (int i = 0; i < columnFamilyHandleList.size(); i++) {
2185 cfHandles[i] = columnFamilyHandleList.get(i).nativeHandle_;
2186 }
2187
2188 final byte[][] keysArray = keys.toArray(new byte[keys.size()][]);
1e59de90
TL
2189 final int[] keyOffsets = new int[keysArray.length];
2190 final int[] keyLengths = new int[keysArray.length];
494da23a
TL
2191 for(int i = 0; i < keyLengths.length; i++) {
2192 keyLengths[i] = keysArray[i].length;
2193 }
2194
2195 return Arrays.asList(multiGet(nativeHandle_, keysArray, keyOffsets,
2196 keyLengths, cfHandles));
2197 }
2198
2199 /**
2200 * Returns a list of values for the given list of keys. List will contain
2201 * null for keys which could not be found.
2202 *
2203 * @param opt Read options.
2204 * @param keys of keys for which values need to be retrieved.
2205 * @return List of values for the given list of keys. List will contain
2206 * null for keys which could not be found.
7c673cae
FG
2207 *
2208 * @throws RocksDBException thrown if error happens in underlying
2209 * native library.
2210 */
494da23a
TL
2211 public List<byte[]> multiGetAsList(final ReadOptions opt,
2212 final List<byte[]> keys) throws RocksDBException {
2213 assert(keys.size() != 0);
2214
2215 final byte[][] keysArray = keys.toArray(new byte[keys.size()][]);
1e59de90
TL
2216 final int[] keyOffsets = new int[keysArray.length];
2217 final int[] keyLengths = new int[keysArray.length];
494da23a
TL
2218 for(int i = 0; i < keyLengths.length; i++) {
2219 keyLengths[i] = keysArray[i].length;
2220 }
2221
2222 return Arrays.asList(multiGet(nativeHandle_, opt.nativeHandle_,
2223 keysArray, keyOffsets, keyLengths));
7c673cae
FG
2224 }
2225
2226 /**
494da23a
TL
2227 * Returns a list of values for the given list of keys. List will contain
2228 * null for keys which could not be found.
2229 * <p>
2230 * Note: Every key needs to have a related column family name in
2231 * {@code columnFamilyHandleList}.
2232 * </p>
7c673cae 2233 *
494da23a
TL
2234 * @param opt Read options.
2235 * @param columnFamilyHandleList {@link java.util.List} containing
2236 * {@link org.rocksdb.ColumnFamilyHandle} instances.
2237 * @param keys of keys for which values need to be retrieved.
2238 * @return List of values for the given list of keys. List will contain
2239 * null for keys which could not be found.
7c673cae 2240 *
494da23a
TL
2241 * @throws RocksDBException thrown if error happens in underlying
2242 * native library.
2243 * @throws IllegalArgumentException thrown if the size of passed keys is not
2244 * equal to the amount of passed column family handles.
7c673cae 2245 */
494da23a
TL
2246 public List<byte[]> multiGetAsList(final ReadOptions opt,
2247 final List<ColumnFamilyHandle> columnFamilyHandleList,
2248 final List<byte[]> keys) throws RocksDBException {
2249 assert(keys.size() != 0);
2250 // Check if key size equals cfList size. If not a exception must be
2251 // thrown. If not a Segmentation fault happens.
2252 if (keys.size()!=columnFamilyHandleList.size()){
2253 throw new IllegalArgumentException(
2254 "For each key there must be a ColumnFamilyHandle.");
2255 }
2256 final long[] cfHandles = new long[columnFamilyHandleList.size()];
2257 for (int i = 0; i < columnFamilyHandleList.size(); i++) {
2258 cfHandles[i] = columnFamilyHandleList.get(i).nativeHandle_;
2259 }
2260
2261 final byte[][] keysArray = keys.toArray(new byte[keys.size()][]);
1e59de90
TL
2262 final int[] keyOffsets = new int[keysArray.length];
2263 final int[] keyLengths = new int[keysArray.length];
494da23a
TL
2264 for(int i = 0; i < keyLengths.length; i++) {
2265 keyLengths[i] = keysArray[i].length;
2266 }
2267
2268 return Arrays.asList(multiGet(nativeHandle_, opt.nativeHandle_,
2269 keysArray, keyOffsets, keyLengths, cfHandles));
7c673cae
FG
2270 }
2271
1e59de90
TL
2272 /**
2273 * Fetches a list of values for the given list of keys, all from the default column family.
2274 *
2275 * @param keys list of keys for which values need to be retrieved.
2276 * @param values list of buffers to return retrieved values in
2277 * @return list of number of bytes in DB for each requested key
2278 * this can be more than the size of the corresponding buffer; then the buffer will be filled
2279 * with the appropriate truncation of the database value.
2280 * @throws RocksDBException if error happens in underlying native library.
2281 * @throws IllegalArgumentException thrown if the number of passed keys and passed values
2282 * do not match.
2283 */
2284 public List<ByteBufferGetStatus> multiGetByteBuffers(
2285 final List<ByteBuffer> keys, final List<ByteBuffer> values) throws RocksDBException {
2286 final ReadOptions readOptions = new ReadOptions();
2287 final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>(1);
2288 columnFamilyHandleList.add(getDefaultColumnFamily());
2289 return multiGetByteBuffers(readOptions, columnFamilyHandleList, keys, values);
2290 }
2291
2292 /**
2293 * Fetches a list of values for the given list of keys, all from the default column family.
2294 *
2295 * @param readOptions Read options
2296 * @param keys list of keys for which values need to be retrieved.
2297 * @param values list of buffers to return retrieved values in
2298 * @throws RocksDBException if error happens in underlying native library.
2299 * @throws IllegalArgumentException thrown if the number of passed keys and passed values
2300 * do not match.
2301 * @return the list of values for the given list of keys
2302 */
2303 public List<ByteBufferGetStatus> multiGetByteBuffers(final ReadOptions readOptions,
2304 final List<ByteBuffer> keys, final List<ByteBuffer> values) throws RocksDBException {
2305 final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>(1);
2306 columnFamilyHandleList.add(getDefaultColumnFamily());
2307 return multiGetByteBuffers(readOptions, columnFamilyHandleList, keys, values);
2308 }
2309
2310 /**
2311 * Fetches a list of values for the given list of keys.
2312 * <p>
2313 * Note: Every key needs to have a related column family name in
2314 * {@code columnFamilyHandleList}.
2315 * </p>
2316 *
2317 * @param columnFamilyHandleList {@link java.util.List} containing
2318 * {@link org.rocksdb.ColumnFamilyHandle} instances.
2319 * @param keys list of keys for which values need to be retrieved.
2320 * @param values list of buffers to return retrieved values in
2321 * @throws RocksDBException if error happens in underlying native library.
2322 * @throws IllegalArgumentException thrown if the number of passed keys, passed values and
2323 * passed column family handles do not match.
2324 * @return the list of values for the given list of keys
2325 */
2326 public List<ByteBufferGetStatus> multiGetByteBuffers(
2327 final List<ColumnFamilyHandle> columnFamilyHandleList, final List<ByteBuffer> keys,
2328 final List<ByteBuffer> values) throws RocksDBException {
2329 final ReadOptions readOptions = new ReadOptions();
2330 return multiGetByteBuffers(readOptions, columnFamilyHandleList, keys, values);
2331 }
2332
2333 /**
2334 * Fetches a list of values for the given list of keys.
2335 * <p>
2336 * Note: Every key needs to have a related column family name in
2337 * {@code columnFamilyHandleList}.
2338 * </p>
2339 *
2340 * @param readOptions Read options
2341 * @param columnFamilyHandleList {@link java.util.List} containing
2342 * {@link org.rocksdb.ColumnFamilyHandle} instances.
2343 * @param keys list of keys for which values need to be retrieved.
2344 * @param values list of buffers to return retrieved values in
2345 * @throws RocksDBException if error happens in underlying native library.
2346 * @throws IllegalArgumentException thrown if the number of passed keys, passed values and
2347 * passed column family handles do not match.
2348 * @return the list of values for the given list of keys
2349 */
2350 public List<ByteBufferGetStatus> multiGetByteBuffers(final ReadOptions readOptions,
2351 final List<ColumnFamilyHandle> columnFamilyHandleList, final List<ByteBuffer> keys,
2352 final List<ByteBuffer> values) throws RocksDBException {
2353 assert (keys.size() != 0);
2354
2355 // Check if key size equals cfList size. If not a exception must be
2356 // thrown. If not a Segmentation fault happens.
2357 if (keys.size() != columnFamilyHandleList.size() && columnFamilyHandleList.size() > 1) {
2358 throw new IllegalArgumentException(
2359 "Wrong number of ColumnFamilyHandle(s) supplied. Provide 0, 1, or as many as there are key/value(s)");
2360 }
2361
2362 // Check if key size equals cfList size. If not a exception must be
2363 // thrown. If not a Segmentation fault happens.
2364 if (values.size() != keys.size()) {
2365 throw new IllegalArgumentException("For each key there must be a corresponding value.");
2366 }
2367
2368 // TODO (AP) support indirect buffers
2369 for (final ByteBuffer key : keys) {
2370 if (!key.isDirect()) {
2371 throw new IllegalArgumentException("All key buffers must be direct byte buffers");
2372 }
2373 }
2374
2375 // TODO (AP) support indirect buffers, though probably via a less efficient code path
2376 for (final ByteBuffer value : values) {
2377 if (!value.isDirect()) {
2378 throw new IllegalArgumentException("All value buffers must be direct byte buffers");
2379 }
2380 }
2381
2382 final int numCFHandles = columnFamilyHandleList.size();
2383 final long[] cfHandles = new long[numCFHandles];
2384 for (int i = 0; i < numCFHandles; i++) {
2385 cfHandles[i] = columnFamilyHandleList.get(i).nativeHandle_;
2386 }
2387
2388 final int numValues = keys.size();
2389
2390 final ByteBuffer[] keysArray = keys.toArray(new ByteBuffer[0]);
2391 final int[] keyOffsets = new int[numValues];
2392 final int[] keyLengths = new int[numValues];
2393 for (int i = 0; i < numValues; i++) {
2394 // TODO (AP) add keysArray[i].arrayOffset() if the buffer is indirect
2395 // TODO (AP) because in that case we have to pass the array directly,
2396 // so that the JNI C++ code will not know to compensate for the array offset
2397 keyOffsets[i] = keysArray[i].position();
2398 keyLengths[i] = keysArray[i].limit();
2399 }
2400 final ByteBuffer[] valuesArray = values.toArray(new ByteBuffer[0]);
2401 final int[] valuesSizeArray = new int[numValues];
2402 final Status[] statusArray = new Status[numValues];
2403
2404 multiGet(nativeHandle_, readOptions.nativeHandle_, cfHandles, keysArray, keyOffsets, keyLengths,
2405 valuesArray, valuesSizeArray, statusArray);
2406
2407 final List<ByteBufferGetStatus> results = new ArrayList<>();
2408 for (int i = 0; i < numValues; i++) {
2409 final Status status = statusArray[i];
2410 if (status.getCode() == Status.Code.Ok) {
2411 final ByteBuffer value = valuesArray[i];
2412 value.position(Math.min(valuesSizeArray[i], value.capacity()));
2413 value.flip(); // prepare for read out
2414 results.add(new ByteBufferGetStatus(status, valuesSizeArray[i], value));
2415 } else {
2416 results.add(new ByteBufferGetStatus(status));
2417 }
2418 }
2419
2420 return results;
2421 }
2422
7c673cae 2423 /**
494da23a 2424 * If the key definitely does not exist in the database, then this method
1e59de90
TL
2425 * returns false, otherwise it returns true if the key might exist.
2426 * That is to say that this method is probabilistic and may return false
2427 * positives, but never a false negative.
f67539c2
TL
2428 *
2429 * If the caller wants to obtain value when the key
2430 * is found in memory, then {@code valueHolder} must be set.
7c673cae 2431 *
f67539c2
TL
2432 * This check is potentially lighter-weight than invoking
2433 * {@link #get(byte[])}. One way to make this lighter weight is to avoid
2434 * doing any IOs.
7c673cae 2435 *
494da23a 2436 * @param key byte array of a key to search for
f67539c2
TL
2437 * @param valueHolder non-null to retrieve the value if it is found, or null
2438 * if the value is not needed. If non-null, upon return of the function,
2439 * the {@code value} will be set if it could be retrieved.
2440 *
2441 * @return false if the key definitely does not exist in the database,
2442 * otherwise true.
7c673cae 2443 */
f67539c2
TL
2444 public boolean keyMayExist(final byte[] key,
2445 /* @Nullable */ final Holder<byte[]> valueHolder) {
2446 return keyMayExist(key, 0, key.length, valueHolder);
7c673cae
FG
2447 }
2448
2449 /**
494da23a 2450 * If the key definitely does not exist in the database, then this method
1e59de90
TL
2451 * returns false, otherwise it returns true if the key might exist.
2452 * That is to say that this method is probabilistic and may return false
2453 * positives, but never a false negative.
f67539c2
TL
2454 *
2455 * If the caller wants to obtain value when the key
2456 * is found in memory, then {@code valueHolder} must be set.
7c673cae 2457 *
f67539c2
TL
2458 * This check is potentially lighter-weight than invoking
2459 * {@link #get(byte[], int, int)}. One way to make this lighter weight is to
2460 * avoid doing any IOs.
7c673cae 2461 *
494da23a
TL
2462 * @param key byte array of a key to search for
2463 * @param offset the offset of the "key" array to be used, must be
2464 * non-negative and no larger than "key".length
2465 * @param len the length of the "key" array to be used, must be non-negative
2466 * and no larger than "key".length
f67539c2
TL
2467 * @param valueHolder non-null to retrieve the value if it is found, or null
2468 * if the value is not needed. If non-null, upon return of the function,
2469 * the {@code value} will be set if it could be retrieved.
7c673cae 2470 *
f67539c2
TL
2471 * @return false if the key definitely does not exist in the database,
2472 * otherwise true.
7c673cae 2473 */
f67539c2
TL
2474 public boolean keyMayExist(final byte[] key,
2475 final int offset, final int len,
2476 /* @Nullable */ final Holder<byte[]> valueHolder) {
2477 return keyMayExist((ColumnFamilyHandle)null, key, offset, len, valueHolder);
7c673cae
FG
2478 }
2479
2480 /**
494da23a 2481 * If the key definitely does not exist in the database, then this method
1e59de90
TL
2482 * returns false, otherwise it returns true if the key might exist.
2483 * That is to say that this method is probabilistic and may return false
2484 * positives, but never a false negative.
7c673cae 2485 *
f67539c2
TL
2486 * If the caller wants to obtain value when the key
2487 * is found in memory, then {@code valueHolder} must be set.
2488 *
2489 * This check is potentially lighter-weight than invoking
2490 * {@link #get(ColumnFamilyHandle,byte[])}. One way to make this lighter
2491 * weight is to avoid doing any IOs.
7c673cae 2492 *
494da23a
TL
2493 * @param columnFamilyHandle {@link ColumnFamilyHandle} instance
2494 * @param key byte array of a key to search for
f67539c2
TL
2495 * @param valueHolder non-null to retrieve the value if it is found, or null
2496 * if the value is not needed. If non-null, upon return of the function,
2497 * the {@code value} will be set if it could be retrieved.
2498 *
2499 * @return false if the key definitely does not exist in the database,
2500 * otherwise true.
7c673cae 2501 */
f67539c2
TL
2502 public boolean keyMayExist(
2503 final ColumnFamilyHandle columnFamilyHandle, final byte[] key,
2504 /* @Nullable */ final Holder<byte[]> valueHolder) {
2505 return keyMayExist(columnFamilyHandle, key, 0, key.length,
2506 valueHolder);
7c673cae
FG
2507 }
2508
2509 /**
494da23a 2510 * If the key definitely does not exist in the database, then this method
1e59de90
TL
2511 * returns false, otherwise it returns true if the key might exist.
2512 * That is to say that this method is probabilistic and may return false
2513 * positives, but never a false negative.
7c673cae 2514 *
f67539c2
TL
2515 * If the caller wants to obtain value when the key
2516 * is found in memory, then {@code valueHolder} must be set.
2517 *
2518 * This check is potentially lighter-weight than invoking
2519 * {@link #get(ColumnFamilyHandle, byte[], int, int)}. One way to make this
2520 * lighter weight is to avoid doing any IOs.
7c673cae 2521 *
494da23a
TL
2522 * @param columnFamilyHandle {@link ColumnFamilyHandle} instance
2523 * @param key byte array of a key to search for
2524 * @param offset the offset of the "key" array to be used, must be
2525 * non-negative and no larger than "key".length
2526 * @param len the length of the "key" array to be used, must be non-negative
2527 * and no larger than "key".length
f67539c2
TL
2528 * @param valueHolder non-null to retrieve the value if it is found, or null
2529 * if the value is not needed. If non-null, upon return of the function,
2530 * the {@code value} will be set if it could be retrieved.
2531 *
2532 * @return false if the key definitely does not exist in the database,
2533 * otherwise true.
7c673cae 2534 */
f67539c2
TL
2535 public boolean keyMayExist(
2536 final ColumnFamilyHandle columnFamilyHandle,
2537 final byte[] key, int offset, int len,
2538 /* @Nullable */ final Holder<byte[]> valueHolder) {
2539 return keyMayExist(columnFamilyHandle, null, key, offset, len,
2540 valueHolder);
7c673cae
FG
2541 }
2542
2543 /**
494da23a 2544 * If the key definitely does not exist in the database, then this method
1e59de90
TL
2545 * returns false, otherwise it returns true if the key might exist.
2546 * That is to say that this method is probabilistic and may return false
2547 * positives, but never a true negative.
7c673cae 2548 *
f67539c2
TL
2549 * If the caller wants to obtain value when the key
2550 * is found in memory, then {@code valueHolder} must be set.
2551 *
2552 * This check is potentially lighter-weight than invoking
2553 * {@link #get(ReadOptions, byte[])}. One way to make this
2554 * lighter weight is to avoid doing any IOs.
7c673cae 2555 *
494da23a
TL
2556 * @param readOptions {@link ReadOptions} instance
2557 * @param key byte array of a key to search for
f67539c2
TL
2558 * @param valueHolder non-null to retrieve the value if it is found, or null
2559 * if the value is not needed. If non-null, upon return of the function,
2560 * the {@code value} will be set if it could be retrieved.
2561 *
2562 * @return false if the key definitely does not exist in the database,
2563 * otherwise true.
7c673cae 2564 */
f67539c2
TL
2565 public boolean keyMayExist(
2566 final ReadOptions readOptions, final byte[] key,
2567 /* @Nullable */ final Holder<byte[]> valueHolder) {
2568 return keyMayExist(readOptions, key, 0, key.length,
2569 valueHolder);
7c673cae
FG
2570 }
2571
2572 /**
494da23a 2573 * If the key definitely does not exist in the database, then this method
1e59de90
TL
2574 * returns false, otherwise it returns true if the key might exist.
2575 * That is to say that this method is probabilistic and may return false
2576 * positives, but never a true negative.
f67539c2
TL
2577 *
2578 * If the caller wants to obtain value when the key
2579 * is found in memory, then {@code valueHolder} must be set.
7c673cae 2580 *
f67539c2
TL
2581 * This check is potentially lighter-weight than invoking
2582 * {@link #get(ReadOptions, byte[], int, int)}. One way to make this
2583 * lighter weight is to avoid doing any IOs.
7c673cae 2584 *
494da23a
TL
2585 * @param readOptions {@link ReadOptions} instance
2586 * @param key byte array of a key to search for
2587 * @param offset the offset of the "key" array to be used, must be
2588 * non-negative and no larger than "key".length
2589 * @param len the length of the "key" array to be used, must be non-negative
2590 * and no larger than "key".length
f67539c2
TL
2591 * @param valueHolder non-null to retrieve the value if it is found, or null
2592 * if the value is not needed. If non-null, upon return of the function,
2593 * the {@code value} will be set if it could be retrieved.
2594 *
2595 * @return false if the key definitely does not exist in the database,
2596 * otherwise true.
7c673cae 2597 */
f67539c2
TL
2598 public boolean keyMayExist(
2599 final ReadOptions readOptions,
494da23a 2600 final byte[] key, final int offset, final int len,
f67539c2
TL
2601 /* @Nullable */ final Holder<byte[]> valueHolder) {
2602 return keyMayExist(null, readOptions,
2603 key, offset, len, valueHolder);
7c673cae
FG
2604 }
2605
494da23a
TL
2606 /**
2607 * If the key definitely does not exist in the database, then this method
1e59de90
TL
2608 * returns false, otherwise it returns true if the key might exist.
2609 * That is to say that this method is probabilistic and may return false
2610 * positives, but never a true negative.
11fdf7f2 2611 *
f67539c2
TL
2612 * If the caller wants to obtain value when the key
2613 * is found in memory, then {@code valueHolder} must be set.
2614 *
2615 * This check is potentially lighter-weight than invoking
2616 * {@link #get(ColumnFamilyHandle, ReadOptions, byte[])}. One way to make this
2617 * lighter weight is to avoid doing any IOs.
11fdf7f2 2618 *
494da23a 2619 * @param columnFamilyHandle {@link ColumnFamilyHandle} instance
f67539c2 2620 * @param readOptions {@link ReadOptions} instance
494da23a 2621 * @param key byte array of a key to search for
f67539c2
TL
2622 * @param valueHolder non-null to retrieve the value if it is found, or null
2623 * if the value is not needed. If non-null, upon return of the function,
2624 * the {@code value} will be set if it could be retrieved.
2625 *
2626 * @return false if the key definitely does not exist in the database,
2627 * otherwise true.
494da23a 2628 */
f67539c2
TL
2629 public boolean keyMayExist(
2630 final ColumnFamilyHandle columnFamilyHandle,
2631 final ReadOptions readOptions, final byte[] key,
2632 /* @Nullable */ final Holder<byte[]> valueHolder) {
2633 return keyMayExist(columnFamilyHandle, readOptions,
2634 key, 0, key.length, valueHolder);
494da23a
TL
2635 }
2636
2637 /**
2638 * If the key definitely does not exist in the database, then this method
1e59de90
TL
2639 * returns false, otherwise it returns true if the key might exist.
2640 * That is to say that this method is probabilistic and may return false
2641 * positives, but never a false negative.
11fdf7f2 2642 *
f67539c2
TL
2643 * If the caller wants to obtain value when the key
2644 * is found in memory, then {@code valueHolder} must be set.
2645 *
2646 * This check is potentially lighter-weight than invoking
2647 * {@link #get(ColumnFamilyHandle, ReadOptions, byte[], int, int)}.
2648 * One way to make this lighter weight is to avoid doing any IOs.
11fdf7f2 2649 *
494da23a 2650 * @param columnFamilyHandle {@link ColumnFamilyHandle} instance
f67539c2 2651 * @param readOptions {@link ReadOptions} instance
494da23a
TL
2652 * @param key byte array of a key to search for
2653 * @param offset the offset of the "key" array to be used, must be
2654 * non-negative and no larger than "key".length
2655 * @param len the length of the "key" array to be used, must be non-negative
2656 * and no larger than "key".length
f67539c2
TL
2657 * @param valueHolder non-null to retrieve the value if it is found, or null
2658 * if the value is not needed. If non-null, upon return of the function,
2659 * the {@code value} will be set if it could be retrieved.
2660 *
2661 * @return false if the key definitely does not exist in the database,
2662 * otherwise true.
11fdf7f2 2663 */
f67539c2
TL
2664 public boolean keyMayExist(
2665 final ColumnFamilyHandle columnFamilyHandle,
2666 final ReadOptions readOptions,
2667 final byte[] key, final int offset, final int len,
2668 /* @Nullable */ final Holder<byte[]> valueHolder) {
494da23a 2669 checkBounds(offset, len, key.length);
f67539c2
TL
2670 if (valueHolder == null) {
2671 return keyMayExist(nativeHandle_,
2672 columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
2673 readOptions == null ? 0 : readOptions.nativeHandle_,
2674 key, offset, len);
2675 } else {
2676 final byte[][] result = keyMayExistFoundValue(
2677 nativeHandle_,
2678 columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
2679 readOptions == null ? 0 : readOptions.nativeHandle_,
2680 key, offset, len);
2681 if (result[0][0] == 0x0) {
2682 valueHolder.setValue(null);
2683 return false;
2684 } else if (result[0][0] == 0x1) {
2685 valueHolder.setValue(null);
2686 return true;
2687 } else {
2688 valueHolder.setValue(result[1]);
2689 return true;
2690 }
2691 }
11fdf7f2
TL
2692 }
2693
1e59de90
TL
2694 /**
2695 * If the key definitely does not exist in the database, then this method
2696 * returns false, otherwise it returns true if the key might exist.
2697 * That is to say that this method is probabilistic and may return false
2698 * positives, but never a false negative.
2699 *
2700 * @param key bytebuffer containing the value of the key
2701 * @return false if the key definitely does not exist in the database,
2702 * otherwise true.
2703 */
2704 public boolean keyMayExist(final ByteBuffer key) {
2705 return keyMayExist(null, (ReadOptions) null, key);
2706 }
2707
2708 /**
2709 * If the key definitely does not exist in the database, then this method
2710 * returns false, otherwise it returns true if the key might exist.
2711 * That is to say that this method is probabilistic and may return false
2712 * positives, but never a false negative.
2713 *
2714 * @param columnFamilyHandle the {@link ColumnFamilyHandle} to look for the key in
2715 * @param key bytebuffer containing the value of the key
2716 * @return false if the key definitely does not exist in the database,
2717 * otherwise true.
2718 */
2719 public boolean keyMayExist(final ColumnFamilyHandle columnFamilyHandle, final ByteBuffer key) {
2720 return keyMayExist(columnFamilyHandle, (ReadOptions) null, key);
2721 }
2722
2723 /**
2724 * If the key definitely does not exist in the database, then this method
2725 * returns false, otherwise it returns true if the key might exist.
2726 * That is to say that this method is probabilistic and may return false
2727 * positives, but never a false negative.
2728 *
2729 * @param readOptions the {@link ReadOptions} to use when reading the key/value
2730 * @param key bytebuffer containing the value of the key
2731 * @return false if the key definitely does not exist in the database,
2732 * otherwise true.
2733 */
2734 public boolean keyMayExist(final ReadOptions readOptions, final ByteBuffer key) {
2735 return keyMayExist(null, readOptions, key);
2736 }
2737
2738 /**
2739 * If the key definitely does not exist in the database, then this method
2740 * returns {@link KeyMayExist.KeyMayExistEnum#kNotExist},
2741 * otherwise if it can with best effort retreive the value, it returns {@link
2742 * KeyMayExist.KeyMayExistEnum#kExistsWithValue} otherwise it returns {@link
2743 * KeyMayExist.KeyMayExistEnum#kExistsWithoutValue}. The choice not to return a value which might
2744 * exist is at the discretion of the implementation; the only guarantee is that {@link
2745 * KeyMayExist.KeyMayExistEnum#kNotExist} is an assurance that the key does not exist.
2746 *
2747 * @param key bytebuffer containing the value of the key
2748 * @param value bytebuffer which will receive a value if the key exists and a value is known
2749 * @return a {@link KeyMayExist} object reporting if key may exist and if a value is provided
2750 */
2751 public KeyMayExist keyMayExist(final ByteBuffer key, final ByteBuffer value) {
2752 return keyMayExist(null, null, key, value);
2753 }
2754
2755 /**
2756 * If the key definitely does not exist in the database, then this method
2757 * returns {@link KeyMayExist.KeyMayExistEnum#kNotExist},
2758 * otherwise if it can with best effort retreive the value, it returns {@link
2759 * KeyMayExist.KeyMayExistEnum#kExistsWithValue} otherwise it returns {@link
2760 * KeyMayExist.KeyMayExistEnum#kExistsWithoutValue}. The choice not to return a value which might
2761 * exist is at the discretion of the implementation; the only guarantee is that {@link
2762 * KeyMayExist.KeyMayExistEnum#kNotExist} is an assurance that the key does not exist.
2763 *
2764 * @param columnFamilyHandle the {@link ColumnFamilyHandle} to look for the key in
2765 * @param key bytebuffer containing the value of the key
2766 * @param value bytebuffer which will receive a value if the key exists and a value is known
2767 * @return a {@link KeyMayExist} object reporting if key may exist and if a value is provided
2768 */
2769 public KeyMayExist keyMayExist(
2770 final ColumnFamilyHandle columnFamilyHandle, final ByteBuffer key, final ByteBuffer value) {
2771 return keyMayExist(columnFamilyHandle, null, key, value);
2772 }
2773
2774 /**
2775 * If the key definitely does not exist in the database, then this method
2776 * returns {@link KeyMayExist.KeyMayExistEnum#kNotExist},
2777 * otherwise if it can with best effort retreive the value, it returns {@link
2778 * KeyMayExist.KeyMayExistEnum#kExistsWithValue} otherwise it returns {@link
2779 * KeyMayExist.KeyMayExistEnum#kExistsWithoutValue}. The choice not to return a value which might
2780 * exist is at the discretion of the implementation; the only guarantee is that {@link
2781 * KeyMayExist.KeyMayExistEnum#kNotExist} is an assurance that the key does not exist.
2782 *
2783 * @param readOptions the {@link ReadOptions} to use when reading the key/value
2784 * @param key bytebuffer containing the value of the key
2785 * @param value bytebuffer which will receive a value if the key exists and a value is known
2786 * @return a {@link KeyMayExist} object reporting if key may exist and if a value is provided
2787 */
2788 public KeyMayExist keyMayExist(
2789 final ReadOptions readOptions, final ByteBuffer key, final ByteBuffer value) {
2790 return keyMayExist(null, readOptions, key, value);
2791 }
2792
2793 /**
2794 * If the key definitely does not exist in the database, then this method
2795 * returns false, otherwise it returns true if the key might exist.
2796 * That is to say that this method is probabilistic and may return false
2797 * positives, but never a false negative.
2798 *
2799 * @param columnFamilyHandle the {@link ColumnFamilyHandle} to look for the key in
2800 * @param readOptions the {@link ReadOptions} to use when reading the key/value
2801 * @param key bytebuffer containing the value of the key
2802 * @return false if the key definitely does not exist in the database,
2803 * otherwise true.
2804 */
2805 public boolean keyMayExist(final ColumnFamilyHandle columnFamilyHandle,
2806 final ReadOptions readOptions, final ByteBuffer key) {
2807 assert key != null : "key ByteBuffer parameter cannot be null";
2808 assert key.isDirect() : "key parameter must be a direct ByteBuffer";
2809 return keyMayExistDirect(nativeHandle_,
2810 columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
2811 readOptions == null ? 0 : readOptions.nativeHandle_, key, key.position(), key.limit());
2812 }
2813
2814 /**
2815 * If the key definitely does not exist in the database, then this method
2816 * returns {@link KeyMayExist.KeyMayExistEnum#kNotExist},
2817 * otherwise if it can with best effort retreive the value, it returns {@link
2818 * KeyMayExist.KeyMayExistEnum#kExistsWithValue} otherwise it returns {@link
2819 * KeyMayExist.KeyMayExistEnum#kExistsWithoutValue}. The choice not to return a value which might
2820 * exist is at the discretion of the implementation; the only guarantee is that {@link
2821 * KeyMayExist.KeyMayExistEnum#kNotExist} is an assurance that the key does not exist.
2822 *
2823 * @param columnFamilyHandle the {@link ColumnFamilyHandle} to look for the key in
2824 * @param readOptions the {@link ReadOptions} to use when reading the key/value
2825 * @param key bytebuffer containing the value of the key
2826 * @param value bytebuffer which will receive a value if the key exists and a value is known
2827 * @return a {@link KeyMayExist} object reporting if key may exist and if a value is provided
2828 */
2829 public KeyMayExist keyMayExist(final ColumnFamilyHandle columnFamilyHandle,
2830 final ReadOptions readOptions, final ByteBuffer key, final ByteBuffer value) {
2831 assert key != null : "key ByteBuffer parameter cannot be null";
2832 assert key.isDirect() : "key parameter must be a direct ByteBuffer";
2833 assert value
2834 != null
2835 : "value ByteBuffer parameter cannot be null. If you do not need the value, use a different version of the method";
2836 assert value.isDirect() : "value parameter must be a direct ByteBuffer";
2837
2838 final int[] result = keyMayExistDirectFoundValue(nativeHandle_,
2839 columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
2840 readOptions == null ? 0 : readOptions.nativeHandle_, key, key.position(), key.remaining(),
2841 value, value.position(), value.remaining());
2842 final int valueLength = result[1];
2843 value.limit(value.position() + Math.min(valueLength, value.remaining()));
2844 return new KeyMayExist(KeyMayExist.KeyMayExistEnum.values()[result[0]], valueLength);
2845 }
2846
7c673cae
FG
2847 /**
2848 * <p>Return a heap-allocated iterator over the contents of the
2849 * database. The result of newIterator() is initially invalid
2850 * (caller must call one of the Seek methods on the iterator
2851 * before using it).</p>
2852 *
2853 * <p>Caller should close the iterator when it is no longer needed.
2854 * The returned iterator should be closed before this db is closed.
2855 * </p>
2856 *
2857 * @return instance of iterator object.
2858 */
2859 public RocksIterator newIterator() {
2860 return new RocksIterator(this, iterator(nativeHandle_));
2861 }
2862
2863 /**
2864 * <p>Return a heap-allocated iterator over the contents of the
2865 * database. The result of newIterator() is initially invalid
2866 * (caller must call one of the Seek methods on the iterator
2867 * before using it).</p>
2868 *
2869 * <p>Caller should close the iterator when it is no longer needed.
2870 * The returned iterator should be closed before this db is closed.
2871 * </p>
2872 *
2873 * @param readOptions {@link ReadOptions} instance.
2874 * @return instance of iterator object.
2875 */
2876 public RocksIterator newIterator(final ReadOptions readOptions) {
2877 return new RocksIterator(this, iterator(nativeHandle_,
2878 readOptions.nativeHandle_));
2879 }
2880
7c673cae 2881 /**
1e59de90
TL
2882 * <p>Return a heap-allocated iterator over the contents of a
2883 * ColumnFamily. The result of newIterator() is initially invalid
7c673cae
FG
2884 * (caller must call one of the Seek methods on the iterator
2885 * before using it).</p>
2886 *
2887 * <p>Caller should close the iterator when it is no longer needed.
2888 * The returned iterator should be closed before this db is closed.
2889 * </p>
2890 *
2891 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
2892 * instance
2893 * @return instance of iterator object.
2894 */
2895 public RocksIterator newIterator(
2896 final ColumnFamilyHandle columnFamilyHandle) {
2897 return new RocksIterator(this, iteratorCF(nativeHandle_,
2898 columnFamilyHandle.nativeHandle_));
2899 }
2900
2901 /**
1e59de90
TL
2902 * <p>Return a heap-allocated iterator over the contents of a
2903 * ColumnFamily. The result of newIterator() is initially invalid
7c673cae
FG
2904 * (caller must call one of the Seek methods on the iterator
2905 * before using it).</p>
2906 *
2907 * <p>Caller should close the iterator when it is no longer needed.
2908 * The returned iterator should be closed before this db is closed.
2909 * </p>
2910 *
2911 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
2912 * instance
2913 * @param readOptions {@link ReadOptions} instance.
2914 * @return instance of iterator object.
2915 */
2916 public RocksIterator newIterator(final ColumnFamilyHandle columnFamilyHandle,
2917 final ReadOptions readOptions) {
2918 return new RocksIterator(this, iteratorCF(nativeHandle_,
2919 columnFamilyHandle.nativeHandle_, readOptions.nativeHandle_));
2920 }
2921
2922 /**
2923 * Returns iterators from a consistent database state across multiple
2924 * column families. Iterators are heap allocated and need to be deleted
2925 * before the db is deleted
2926 *
2927 * @param columnFamilyHandleList {@link java.util.List} containing
2928 * {@link org.rocksdb.ColumnFamilyHandle} instances.
2929 * @return {@link java.util.List} containing {@link org.rocksdb.RocksIterator}
2930 * instances
2931 *
2932 * @throws RocksDBException thrown if error happens in underlying
2933 * native library.
2934 */
2935 public List<RocksIterator> newIterators(
2936 final List<ColumnFamilyHandle> columnFamilyHandleList)
2937 throws RocksDBException {
2938 return newIterators(columnFamilyHandleList, new ReadOptions());
2939 }
2940
2941 /**
2942 * Returns iterators from a consistent database state across multiple
2943 * column families. Iterators are heap allocated and need to be deleted
2944 * before the db is deleted
2945 *
2946 * @param columnFamilyHandleList {@link java.util.List} containing
2947 * {@link org.rocksdb.ColumnFamilyHandle} instances.
2948 * @param readOptions {@link ReadOptions} instance.
2949 * @return {@link java.util.List} containing {@link org.rocksdb.RocksIterator}
2950 * instances
2951 *
2952 * @throws RocksDBException thrown if error happens in underlying
2953 * native library.
2954 */
2955 public List<RocksIterator> newIterators(
2956 final List<ColumnFamilyHandle> columnFamilyHandleList,
2957 final ReadOptions readOptions) throws RocksDBException {
2958
2959 final long[] columnFamilyHandles = new long[columnFamilyHandleList.size()];
2960 for (int i = 0; i < columnFamilyHandleList.size(); i++) {
2961 columnFamilyHandles[i] = columnFamilyHandleList.get(i).nativeHandle_;
2962 }
2963
2964 final long[] iteratorRefs = iterators(nativeHandle_, columnFamilyHandles,
2965 readOptions.nativeHandle_);
2966
2967 final List<RocksIterator> iterators = new ArrayList<>(
2968 columnFamilyHandleList.size());
2969 for (int i=0; i<columnFamilyHandleList.size(); i++){
2970 iterators.add(new RocksIterator(this, iteratorRefs[i]));
2971 }
2972 return iterators;
2973 }
2974
494da23a 2975
7c673cae 2976 /**
494da23a
TL
2977 * <p>Return a handle to the current DB state. Iterators created with
2978 * this handle will all observe a stable snapshot of the current DB
2979 * state. The caller must call ReleaseSnapshot(result) when the
2980 * snapshot is no longer needed.</p>
7c673cae 2981 *
494da23a
TL
2982 * <p>nullptr will be returned if the DB fails to take a snapshot or does
2983 * not support snapshot.</p>
2984 *
2985 * @return Snapshot {@link Snapshot} instance
7c673cae 2986 */
494da23a
TL
2987 public Snapshot getSnapshot() {
2988 long snapshotHandle = getSnapshot(nativeHandle_);
2989 if (snapshotHandle != 0) {
2990 return new Snapshot(snapshotHandle);
2991 }
2992 return null;
7c673cae
FG
2993 }
2994
2995 /**
494da23a 2996 * Release a previously acquired snapshot.
7c673cae 2997 *
494da23a
TL
2998 * The caller must not use "snapshot" after this call.
2999 *
3000 * @param snapshot {@link Snapshot} instance
3001 */
3002 public void releaseSnapshot(final Snapshot snapshot) {
3003 if (snapshot != null) {
3004 releaseSnapshot(nativeHandle_, snapshot.nativeHandle_);
3005 }
3006 }
3007
3008 /**
3009 * DB implements can export properties about their state
3010 * via this method on a per column family level.
3011 *
3012 * <p>If {@code property} is a valid property understood by this DB
3013 * implementation, fills {@code value} with its current value and
3014 * returns true. Otherwise returns false.</p>
3015 *
3016 * <p>Valid property names include:
3017 * <ul>
3018 * <li>"rocksdb.num-files-at-level&lt;N&gt;" - return the number of files at
3019 * level &lt;N&gt;, where &lt;N&gt; is an ASCII representation of a level
3020 * number (e.g. "0").</li>
3021 * <li>"rocksdb.stats" - returns a multi-line string that describes statistics
3022 * about the internal operation of the DB.</li>
3023 * <li>"rocksdb.sstables" - returns a multi-line string that describes all
3024 * of the sstables that make up the db contents.</li>
3025 * </ul>
3026 *
3027 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
3028 * instance, or null for the default column family.
3029 * @param property to be fetched. See above for examples
3030 * @return property value
7c673cae
FG
3031 *
3032 * @throws RocksDBException thrown if error happens in underlying
3033 * native library.
3034 */
494da23a
TL
3035 public String getProperty(
3036 /* @Nullable */ final ColumnFamilyHandle columnFamilyHandle,
3037 final String property) throws RocksDBException {
3038 return getProperty(nativeHandle_,
3039 columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
3040 property, property.length());
7c673cae
FG
3041 }
3042
3043 /**
494da23a
TL
3044 * DB implementations can export properties about their state
3045 * via this method. If "property" is a valid property understood by this
3046 * DB implementation, fills "*value" with its current value and returns
3047 * true. Otherwise returns false.
7c673cae 3048 *
494da23a
TL
3049 * <p>Valid property names include:
3050 * <ul>
3051 * <li>"rocksdb.num-files-at-level&lt;N&gt;" - return the number of files at
3052 * level &lt;N&gt;, where &lt;N&gt; is an ASCII representation of a level
3053 * number (e.g. "0").</li>
3054 * <li>"rocksdb.stats" - returns a multi-line string that describes statistics
3055 * about the internal operation of the DB.</li>
3056 * <li>"rocksdb.sstables" - returns a multi-line string that describes all
3057 * of the sstables that make up the db contents.</li>
3058 *</ul>
3059 *
3060 * @param property to be fetched. See above for examples
3061 * @return property value
7c673cae
FG
3062 *
3063 * @throws RocksDBException thrown if error happens in underlying
3064 * native library.
3065 */
494da23a
TL
3066 public String getProperty(final String property) throws RocksDBException {
3067 return getProperty(null, property);
7c673cae
FG
3068 }
3069
494da23a 3070
7c673cae 3071 /**
494da23a 3072 * Gets a property map.
7c673cae 3073 *
494da23a 3074 * @param property to be fetched.
7c673cae 3075 *
494da23a
TL
3076 * @return the property map
3077 *
3078 * @throws RocksDBException if an error happens in the underlying native code.
7c673cae 3079 */
494da23a
TL
3080 public Map<String, String> getMapProperty(final String property)
3081 throws RocksDBException {
3082 return getMapProperty(null, property);
3083 }
3084
3085 /**
3086 * Gets a property map.
3087 *
3088 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
3089 * instance, or null for the default column family.
3090 * @param property to be fetched.
3091 *
3092 * @return the property map
3093 *
3094 * @throws RocksDBException if an error happens in the underlying native code.
3095 */
3096 public Map<String, String> getMapProperty(
3097 /* @Nullable */ final ColumnFamilyHandle columnFamilyHandle,
3098 final String property) throws RocksDBException {
3099 return getMapProperty(nativeHandle_,
3100 columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
3101 property, property.length());
3102 }
3103
3104 /**
3105 * <p> Similar to GetProperty(), but only works for a subset of properties
3106 * whose return value is a numerical value. Return the value as long.</p>
3107 *
3108 * <p><strong>Note</strong>: As the returned property is of type
3109 * {@code uint64_t} on C++ side the returning value can be negative
3110 * because Java supports in Java 7 only signed long values.</p>
3111 *
3112 * <p><strong>Java 7</strong>: To mitigate the problem of the non
3113 * existent unsigned long tpye, values should be encapsulated using
3114 * {@link java.math.BigInteger} to reflect the correct value. The correct
3115 * behavior is guaranteed if {@code 2^64} is added to negative values.</p>
3116 *
3117 * <p><strong>Java 8</strong>: In Java 8 the value should be treated as
3118 * unsigned long using provided methods of type {@link Long}.</p>
3119 *
3120 * @param property to be fetched.
3121 *
3122 * @return numerical property value.
3123 *
3124 * @throws RocksDBException if an error happens in the underlying native code.
3125 */
3126 public long getLongProperty(final String property) throws RocksDBException {
3127 return getLongProperty(null, property);
3128 }
3129
3130 /**
3131 * <p> Similar to GetProperty(), but only works for a subset of properties
3132 * whose return value is a numerical value. Return the value as long.</p>
3133 *
3134 * <p><strong>Note</strong>: As the returned property is of type
3135 * {@code uint64_t} on C++ side the returning value can be negative
3136 * because Java supports in Java 7 only signed long values.</p>
3137 *
3138 * <p><strong>Java 7</strong>: To mitigate the problem of the non
3139 * existent unsigned long tpye, values should be encapsulated using
3140 * {@link java.math.BigInteger} to reflect the correct value. The correct
3141 * behavior is guaranteed if {@code 2^64} is added to negative values.</p>
3142 *
3143 * <p><strong>Java 8</strong>: In Java 8 the value should be treated as
3144 * unsigned long using provided methods of type {@link Long}.</p>
3145 *
3146 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
3147 * instance, or null for the default column family
3148 * @param property to be fetched.
3149 *
3150 * @return numerical property value
3151 *
3152 * @throws RocksDBException if an error happens in the underlying native code.
3153 */
3154 public long getLongProperty(
3155 /* @Nullable */ final ColumnFamilyHandle columnFamilyHandle,
3156 final String property) throws RocksDBException {
3157 return getLongProperty(nativeHandle_,
3158 columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
3159 property, property.length());
3160 }
3161
3162 /**
3163 * Reset internal stats for DB and all column families.
3164 *
3165 * Note this doesn't reset {@link Options#statistics()} as it is not
3166 * owned by DB.
f67539c2
TL
3167 *
3168 * @throws RocksDBException if an error occurs whilst reseting the stats
494da23a
TL
3169 */
3170 public void resetStats() throws RocksDBException {
3171 resetStats(nativeHandle_);
3172 }
3173
3174 /**
3175 * <p> Return sum of the getLongProperty of all the column families</p>
3176 *
3177 * <p><strong>Note</strong>: As the returned property is of type
3178 * {@code uint64_t} on C++ side the returning value can be negative
3179 * because Java supports in Java 7 only signed long values.</p>
3180 *
3181 * <p><strong>Java 7</strong>: To mitigate the problem of the non
3182 * existent unsigned long tpye, values should be encapsulated using
3183 * {@link java.math.BigInteger} to reflect the correct value. The correct
3184 * behavior is guaranteed if {@code 2^64} is added to negative values.</p>
3185 *
3186 * <p><strong>Java 8</strong>: In Java 8 the value should be treated as
3187 * unsigned long using provided methods of type {@link Long}.</p>
3188 *
3189 * @param property to be fetched.
3190 *
3191 * @return numerical property value
3192 *
3193 * @throws RocksDBException if an error happens in the underlying native code.
3194 */
3195 public long getAggregatedLongProperty(final String property)
7c673cae 3196 throws RocksDBException {
494da23a
TL
3197 return getAggregatedLongProperty(nativeHandle_, property,
3198 property.length());
3199 }
3200
3201 /**
3202 * Get the approximate file system space used by keys in each range.
3203 *
3204 * Note that the returned sizes measure file system space usage, so
3205 * if the user data compresses by a factor of ten, the returned
3206 * sizes will be one-tenth the size of the corresponding user data size.
3207 *
3208 * If {@code sizeApproximationFlags} defines whether the returned size
3209 * should include the recently written data in the mem-tables (if
3210 * the mem-table type supports it), data serialized to disk, or both.
3211 *
3212 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
3213 * instance, or null for the default column family
3214 * @param ranges the ranges over which to approximate sizes
3215 * @param sizeApproximationFlags flags to determine what to include in the
3216 * approximation.
3217 *
3218 * @return the sizes
3219 */
3220 public long[] getApproximateSizes(
3221 /*@Nullable*/ final ColumnFamilyHandle columnFamilyHandle,
3222 final List<Range> ranges,
3223 final SizeApproximationFlag... sizeApproximationFlags) {
3224
3225 byte flags = 0x0;
3226 for (final SizeApproximationFlag sizeApproximationFlag
3227 : sizeApproximationFlags) {
3228 flags |= sizeApproximationFlag.getValue();
3229 }
3230
3231 return getApproximateSizes(nativeHandle_,
3232 columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
3233 toRangeSliceHandles(ranges), flags);
3234 }
3235
3236 /**
3237 * Get the approximate file system space used by keys in each range for
3238 * the default column family.
3239 *
3240 * Note that the returned sizes measure file system space usage, so
3241 * if the user data compresses by a factor of ten, the returned
3242 * sizes will be one-tenth the size of the corresponding user data size.
3243 *
3244 * If {@code sizeApproximationFlags} defines whether the returned size
3245 * should include the recently written data in the mem-tables (if
3246 * the mem-table type supports it), data serialized to disk, or both.
3247 *
3248 * @param ranges the ranges over which to approximate sizes
3249 * @param sizeApproximationFlags flags to determine what to include in the
3250 * approximation.
3251 *
3252 * @return the sizes.
3253 */
3254 public long[] getApproximateSizes(final List<Range> ranges,
3255 final SizeApproximationFlag... sizeApproximationFlags) {
3256 return getApproximateSizes(null, ranges, sizeApproximationFlags);
3257 }
3258
3259 public static class CountAndSize {
3260 public final long count;
3261 public final long size;
3262
3263 public CountAndSize(final long count, final long size) {
3264 this.count = count;
3265 this.size = size;
3266 }
3267 }
3268
3269 /**
3270 * This method is similar to
3271 * {@link #getApproximateSizes(ColumnFamilyHandle, List, SizeApproximationFlag...)},
3272 * except that it returns approximate number of records and size in memtables.
3273 *
3274 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
3275 * instance, or null for the default column family
3276 * @param range the ranges over which to get the memtable stats
3277 *
3278 * @return the count and size for the range
3279 */
3280 public CountAndSize getApproximateMemTableStats(
3281 /*@Nullable*/ final ColumnFamilyHandle columnFamilyHandle,
3282 final Range range) {
3283 final long[] result = getApproximateMemTableStats(nativeHandle_,
3284 columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
3285 range.start.getNativeHandle(),
3286 range.limit.getNativeHandle());
3287 return new CountAndSize(result[0], result[1]);
7c673cae
FG
3288 }
3289
3290 /**
494da23a
TL
3291 * This method is similar to
3292 * {@link #getApproximateSizes(ColumnFamilyHandle, List, SizeApproximationFlag...)},
3293 * except that it returns approximate number of records and size in memtables.
7c673cae 3294 *
494da23a 3295 * @param range the ranges over which to get the memtable stats
7c673cae 3296 *
494da23a 3297 * @return the count and size for the range
7c673cae 3298 */
494da23a
TL
3299 public CountAndSize getApproximateMemTableStats(
3300 final Range range) {
3301 return getApproximateMemTableStats(null, range);
7c673cae
FG
3302 }
3303
3304 /**
3305 * <p>Range compaction of database.</p>
3306 * <p><strong>Note</strong>: After the database has been compacted,
3307 * all data will have been pushed down to the last level containing
3308 * any data.</p>
3309 *
3310 * <p><strong>See also</strong></p>
3311 * <ul>
7c673cae 3312 * <li>{@link #compactRange(byte[], byte[])}</li>
7c673cae
FG
3313 * </ul>
3314 *
3315 * @throws RocksDBException thrown if an error occurs within the native
3316 * part of the library.
3317 */
3318 public void compactRange() throws RocksDBException {
494da23a
TL
3319 compactRange(null);
3320 }
3321
3322 /**
3323 * <p>Range compaction of column family.</p>
3324 * <p><strong>Note</strong>: After the database has been compacted,
3325 * all data will have been pushed down to the last level containing
3326 * any data.</p>
3327 *
3328 * <p><strong>See also</strong></p>
3329 * <ul>
3330 * <li>
494da23a
TL
3331 * {@link #compactRange(ColumnFamilyHandle, byte[], byte[])}
3332 * </li>
494da23a
TL
3333 * </ul>
3334 *
3335 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
3336 * instance, or null for the default column family.
3337 *
3338 * @throws RocksDBException thrown if an error occurs within the native
3339 * part of the library.
3340 */
3341 public void compactRange(
3342 /* @Nullable */ final ColumnFamilyHandle columnFamilyHandle)
3343 throws RocksDBException {
3344 compactRange(nativeHandle_, null, -1, null, -1, 0,
3345 columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_);
7c673cae
FG
3346 }
3347
3348 /**
3349 * <p>Range compaction of database.</p>
3350 * <p><strong>Note</strong>: After the database has been compacted,
3351 * all data will have been pushed down to the last level containing
3352 * any data.</p>
3353 *
3354 * <p><strong>See also</strong></p>
3355 * <ul>
3356 * <li>{@link #compactRange()}</li>
7c673cae
FG
3357 * </ul>
3358 *
3359 * @param begin start of key range (included in range)
3360 * @param end end of key range (excluded from range)
3361 *
3362 * @throws RocksDBException thrown if an error occurs within the native
3363 * part of the library.
3364 */
3365 public void compactRange(final byte[] begin, final byte[] end)
3366 throws RocksDBException {
494da23a 3367 compactRange(null, begin, end);
7c673cae
FG
3368 }
3369
3370 /**
494da23a 3371 * <p>Range compaction of column family.</p>
7c673cae
FG
3372 * <p><strong>Note</strong>: After the database has been compacted,
3373 * all data will have been pushed down to the last level containing
3374 * any data.</p>
3375 *
7c673cae
FG
3376 * <p><strong>See also</strong></p>
3377 * <ul>
494da23a 3378 * <li>{@link #compactRange(ColumnFamilyHandle)}</li>
7c673cae
FG
3379 * </ul>
3380 *
494da23a
TL
3381 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
3382 * instance, or null for the default column family.
3383 * @param begin start of key range (included in range)
3384 * @param end end of key range (excluded from range)
7c673cae
FG
3385 *
3386 * @throws RocksDBException thrown if an error occurs within the native
3387 * part of the library.
3388 */
494da23a
TL
3389 public void compactRange(
3390 /* @Nullable */ final ColumnFamilyHandle columnFamilyHandle,
3391 final byte[] begin, final byte[] end) throws RocksDBException {
3392 compactRange(nativeHandle_,
3393 begin, begin == null ? -1 : begin.length,
3394 end, end == null ? -1 : end.length,
3395 0, columnFamilyHandle == null ? 0: columnFamilyHandle.nativeHandle_);
7c673cae
FG
3396 }
3397
11fdf7f2
TL
3398 /**
3399 * <p>Range compaction of column family.</p>
3400 * <p><strong>Note</strong>: After the database has been compacted,
3401 * all data will have been pushed down to the last level containing
3402 * any data.</p>
3403 *
3404 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle} instance.
3405 * @param begin start of key range (included in range)
3406 * @param end end of key range (excluded from range)
3407 * @param compactRangeOptions options for the compaction
3408 *
3409 * @throws RocksDBException thrown if an error occurs within the native
3410 * part of the library.
3411 */
f67539c2
TL
3412 public void compactRange(
3413 /* @Nullable */ final ColumnFamilyHandle columnFamilyHandle,
494da23a
TL
3414 final byte[] begin, final byte[] end,
3415 final CompactRangeOptions compactRangeOptions) throws RocksDBException {
3416 compactRange(nativeHandle_,
3417 begin, begin == null ? -1 : begin.length,
3418 end, end == null ? -1 : end.length,
f67539c2
TL
3419 compactRangeOptions.nativeHandle_,
3420 columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_);
11fdf7f2
TL
3421 }
3422
7c673cae 3423 /**
494da23a 3424 * Change the options for the column family handle.
7c673cae 3425 *
494da23a
TL
3426 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
3427 * instance, or null for the default column family.
3428 * @param mutableColumnFamilyOptions the options.
f67539c2
TL
3429 *
3430 * @throws RocksDBException if an error occurs whilst setting the options
494da23a
TL
3431 */
3432 public void setOptions(
3433 /* @Nullable */final ColumnFamilyHandle columnFamilyHandle,
3434 final MutableColumnFamilyOptions mutableColumnFamilyOptions)
3435 throws RocksDBException {
1e59de90
TL
3436 setOptions(nativeHandle_, columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
3437 mutableColumnFamilyOptions.getKeys(), mutableColumnFamilyOptions.getValues());
3438 }
3439
3440 /**
3441 * Get the options for the column family handle
3442 *
3443 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
3444 * instance, or null for the default column family.
3445 *
3446 * @return the options parsed from the options string return by RocksDB
3447 *
3448 * @throws RocksDBException if an error occurs while getting the options string, or parsing the
3449 * resulting options string into options
3450 */
3451 public MutableColumnFamilyOptions.MutableColumnFamilyOptionsBuilder getOptions(
3452 /* @Nullable */ final ColumnFamilyHandle columnFamilyHandle) throws RocksDBException {
3453 String optionsString = getOptions(
3454 nativeHandle_, columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_);
3455 return MutableColumnFamilyOptions.parse(optionsString, true);
3456 }
3457
3458 /**
3459 * Default column family options
3460 *
3461 * @return the options parsed from the options string return by RocksDB
3462 *
3463 * @throws RocksDBException if an error occurs while getting the options string, or parsing the
3464 * resulting options string into options
3465 */
3466 public MutableColumnFamilyOptions.MutableColumnFamilyOptionsBuilder getOptions()
3467 throws RocksDBException {
3468 return getOptions(null);
3469 }
3470
3471 /**
3472 * Get the database options
3473 *
3474 * @return the DB options parsed from the options string return by RocksDB
3475 *
3476 * @throws RocksDBException if an error occurs while getting the options string, or parsing the
3477 * resulting options string into options
3478 */
3479 public MutableDBOptions.MutableDBOptionsBuilder getDBOptions() throws RocksDBException {
3480 String optionsString = getDBOptions(nativeHandle_);
3481 return MutableDBOptions.parse(optionsString, true);
494da23a
TL
3482 }
3483
3484 /**
3485 * Change the options for the default column family handle.
7c673cae 3486 *
494da23a 3487 * @param mutableColumnFamilyOptions the options.
f67539c2
TL
3488 *
3489 * @throws RocksDBException if an error occurs whilst setting the options
494da23a
TL
3490 */
3491 public void setOptions(
3492 final MutableColumnFamilyOptions mutableColumnFamilyOptions)
3493 throws RocksDBException {
3494 setOptions(null, mutableColumnFamilyOptions);
3495 }
3496
3497 /**
3498 * Set the options for the column family handle.
7c673cae 3499 *
494da23a 3500 * @param mutableDBoptions the options.
f67539c2
TL
3501 *
3502 * @throws RocksDBException if an error occurs whilst setting the options
494da23a
TL
3503 */
3504 public void setDBOptions(final MutableDBOptions mutableDBoptions)
3505 throws RocksDBException {
3506 setDBOptions(nativeHandle_,
3507 mutableDBoptions.getKeys(),
3508 mutableDBoptions.getValues());
3509 }
3510
3511 /**
f67539c2 3512 * Takes a list of files specified by file names and
494da23a
TL
3513 * compacts them to the specified level.
3514 *
3515 * Note that the behavior is different from
3516 * {@link #compactRange(ColumnFamilyHandle, byte[], byte[])}
3517 * in that CompactFiles() performs the compaction job using the CURRENT
3518 * thread.
3519 *
3520 * @param compactionOptions compaction options
3521 * @param inputFileNames the name of the files to compact
3522 * @param outputLevel the level to which they should be compacted
3523 * @param outputPathId the id of the output path, or -1
3524 * @param compactionJobInfo the compaction job info, this parameter
3525 * will be updated with the info from compacting the files,
3526 * can just be null if you don't need it.
f67539c2
TL
3527 *
3528 * @return the list of compacted files
3529 *
3530 * @throws RocksDBException if an error occurs during compaction
494da23a
TL
3531 */
3532 public List<String> compactFiles(
3533 final CompactionOptions compactionOptions,
3534 final List<String> inputFileNames,
3535 final int outputLevel,
3536 final int outputPathId,
3537 /* @Nullable */ final CompactionJobInfo compactionJobInfo)
3538 throws RocksDBException {
3539 return compactFiles(compactionOptions, null, inputFileNames, outputLevel,
3540 outputPathId, compactionJobInfo);
3541 }
3542
3543 /**
3544 * Takes a list of files specified by file names and
3545 * compacts them to the specified level.
3546 *
3547 * Note that the behavior is different from
3548 * {@link #compactRange(ColumnFamilyHandle, byte[], byte[])}
3549 * in that CompactFiles() performs the compaction job using the CURRENT
3550 * thread.
3551 *
3552 * @param compactionOptions compaction options
3553 * @param columnFamilyHandle columnFamilyHandle, or null for the
3554 * default column family
3555 * @param inputFileNames the name of the files to compact
3556 * @param outputLevel the level to which they should be compacted
3557 * @param outputPathId the id of the output path, or -1
3558 * @param compactionJobInfo the compaction job info, this parameter
3559 * will be updated with the info from compacting the files,
3560 * can just be null if you don't need it.
f67539c2
TL
3561 *
3562 * @return the list of compacted files
3563 *
3564 * @throws RocksDBException if an error occurs during compaction
494da23a
TL
3565 */
3566 public List<String> compactFiles(
3567 final CompactionOptions compactionOptions,
3568 /* @Nullable */ final ColumnFamilyHandle columnFamilyHandle,
3569 final List<String> inputFileNames,
3570 final int outputLevel,
3571 final int outputPathId,
3572 /* @Nullable */ final CompactionJobInfo compactionJobInfo)
3573 throws RocksDBException {
3574 return Arrays.asList(compactFiles(nativeHandle_, compactionOptions.nativeHandle_,
3575 columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
3576 inputFileNames.toArray(new String[0]),
3577 outputLevel,
3578 outputPathId,
3579 compactionJobInfo == null ? 0 : compactionJobInfo.nativeHandle_));
3580 }
3581
20effc67
TL
3582 /**
3583 * This function will cancel all currently running background processes.
3584 *
3585 * @param wait if true, wait for all background work to be cancelled before
3586 * returning.
3587 *
3588 */
3589 public void cancelAllBackgroundWork(boolean wait) {
3590 cancelAllBackgroundWork(nativeHandle_, wait);
3591 }
3592
494da23a
TL
3593 /**
3594 * This function will wait until all currently running background processes
3595 * finish. After it returns, no background process will be run until
3596 * {@link #continueBackgroundWork()} is called
3597 *
f67539c2 3598 * @throws RocksDBException if an error occurs when pausing background work
494da23a
TL
3599 */
3600 public void pauseBackgroundWork() throws RocksDBException {
3601 pauseBackgroundWork(nativeHandle_);
3602 }
3603
3604 /**
3605 * Resumes background work which was suspended by
3606 * previously calling {@link #pauseBackgroundWork()}
3607 *
f67539c2 3608 * @throws RocksDBException if an error occurs when resuming background work
494da23a
TL
3609 */
3610 public void continueBackgroundWork() throws RocksDBException {
3611 continueBackgroundWork(nativeHandle_);
3612 }
3613
3614 /**
3615 * Enable automatic compactions for the given column
3616 * families if they were previously disabled.
3617 *
3618 * The function will first set the
3619 * {@link ColumnFamilyOptions#disableAutoCompactions()} option for each
3620 * column family to false, after which it will schedule a flush/compaction.
3621 *
3622 * NOTE: Setting disableAutoCompactions to 'false' through
3623 * {@link #setOptions(ColumnFamilyHandle, MutableColumnFamilyOptions)}
3624 * does NOT schedule a flush/compaction afterwards, and only changes the
3625 * parameter itself within the column family option.
3626 *
3627 * @param columnFamilyHandles the column family handles
f67539c2
TL
3628 *
3629 * @throws RocksDBException if an error occurs whilst enabling auto-compaction
494da23a
TL
3630 */
3631 public void enableAutoCompaction(
3632 final List<ColumnFamilyHandle> columnFamilyHandles)
3633 throws RocksDBException {
3634 enableAutoCompaction(nativeHandle_,
3635 toNativeHandleList(columnFamilyHandles));
3636 }
3637
3638 /**
3639 * Number of levels used for this DB.
3640 *
3641 * @return the number of levels
3642 */
3643 public int numberLevels() {
3644 return numberLevels(null);
3645 }
3646
3647 /**
3648 * Number of levels used for a column family in this DB.
3649 *
3650 * @param columnFamilyHandle the column family handle, or null
3651 * for the default column family
3652 *
3653 * @return the number of levels
3654 */
3655 public int numberLevels(/* @Nullable */final ColumnFamilyHandle columnFamilyHandle) {
3656 return numberLevels(nativeHandle_,
3657 columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_);
3658 }
3659
3660 /**
3661 * Maximum level to which a new compacted memtable is pushed if it
3662 * does not create overlap.
f67539c2
TL
3663 *
3664 * @return the maximum level
494da23a
TL
3665 */
3666 public int maxMemCompactionLevel() {
3667 return maxMemCompactionLevel(null);
3668 }
3669
3670 /**
3671 * Maximum level to which a new compacted memtable is pushed if it
3672 * does not create overlap.
3673 *
3674 * @param columnFamilyHandle the column family handle
f67539c2
TL
3675 *
3676 * @return the maximum level
494da23a
TL
3677 */
3678 public int maxMemCompactionLevel(
f67539c2 3679 /* @Nullable */ final ColumnFamilyHandle columnFamilyHandle) {
494da23a
TL
3680 return maxMemCompactionLevel(nativeHandle_,
3681 columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_);
3682 }
3683
3684 /**
3685 * Number of files in level-0 that would stop writes.
f67539c2
TL
3686 *
3687 * @return the number of files
494da23a
TL
3688 */
3689 public int level0StopWriteTrigger() {
3690 return level0StopWriteTrigger(null);
3691 }
3692
3693 /**
3694 * Number of files in level-0 that would stop writes.
3695 *
3696 * @param columnFamilyHandle the column family handle
f67539c2
TL
3697 *
3698 * @return the number of files
494da23a
TL
3699 */
3700 public int level0StopWriteTrigger(
3701 /* @Nullable */final ColumnFamilyHandle columnFamilyHandle) {
3702 return level0StopWriteTrigger(nativeHandle_,
3703 columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_);
3704 }
3705
3706 /**
3707 * Get DB name -- the exact same name that was provided as an argument to
3708 * as path to {@link #open(Options, String)}.
3709 *
3710 * @return the DB name
3711 */
3712 public String getName() {
3713 return getName(nativeHandle_);
3714 }
3715
3716 /**
3717 * Get the Env object from the DB
3718 *
3719 * @return the env
3720 */
3721 public Env getEnv() {
3722 final long envHandle = getEnv(nativeHandle_);
3723 if (envHandle == Env.getDefault().nativeHandle_) {
3724 return Env.getDefault();
3725 } else {
3726 final Env env = new RocksEnv(envHandle);
3727 env.disOwnNativeHandle(); // we do not own the Env!
3728 return env;
3729 }
3730 }
3731
3732 /**
3733 * <p>Flush all memory table data.</p>
3734 *
3735 * <p>Note: it must be ensured that the FlushOptions instance
3736 * is not GC'ed before this method finishes. If the wait parameter is
3737 * set to false, flush processing is asynchronous.</p>
3738 *
3739 * @param flushOptions {@link org.rocksdb.FlushOptions} instance.
3740 * @throws RocksDBException thrown if an error occurs within the native
3741 * part of the library.
3742 */
3743 public void flush(final FlushOptions flushOptions)
3744 throws RocksDBException {
3745 flush(flushOptions, (List<ColumnFamilyHandle>) null);
3746 }
3747
3748 /**
3749 * <p>Flush all memory table data.</p>
11fdf7f2 3750 *
494da23a
TL
3751 * <p>Note: it must be ensured that the FlushOptions instance
3752 * is not GC'ed before this method finishes. If the wait parameter is
3753 * set to false, flush processing is asynchronous.</p>
7c673cae 3754 *
494da23a
TL
3755 * @param flushOptions {@link org.rocksdb.FlushOptions} instance.
3756 * @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle} instance.
7c673cae
FG
3757 * @throws RocksDBException thrown if an error occurs within the native
3758 * part of the library.
3759 */
494da23a
TL
3760 public void flush(final FlushOptions flushOptions,
3761 /* @Nullable */ final ColumnFamilyHandle columnFamilyHandle)
3762 throws RocksDBException {
3763 flush(flushOptions,
3764 columnFamilyHandle == null ? null : Arrays.asList(columnFamilyHandle));
7c673cae
FG
3765 }
3766
3767 /**
494da23a 3768 * Flushes multiple column families.
7c673cae 3769 *
494da23a
TL
3770 * If atomic flush is not enabled, this is equivalent to calling
3771 * {@link #flush(FlushOptions, ColumnFamilyHandle)} multiple times.
11fdf7f2 3772 *
494da23a
TL
3773 * If atomic flush is enabled, this will flush all column families
3774 * specified up to the latest sequence number at the time when flush is
3775 * requested.
7c673cae 3776 *
494da23a
TL
3777 * @param flushOptions {@link org.rocksdb.FlushOptions} instance.
3778 * @param columnFamilyHandles column family handles.
7c673cae
FG
3779 * @throws RocksDBException thrown if an error occurs within the native
3780 * part of the library.
3781 */
494da23a
TL
3782 public void flush(final FlushOptions flushOptions,
3783 /* @Nullable */ final List<ColumnFamilyHandle> columnFamilyHandles)
7c673cae 3784 throws RocksDBException {
494da23a
TL
3785 flush(nativeHandle_, flushOptions.nativeHandle_,
3786 toNativeHandleList(columnFamilyHandles));
7c673cae
FG
3787 }
3788
3789 /**
494da23a
TL
3790 * Flush the WAL memory buffer to the file. If {@code sync} is true,
3791 * it calls {@link #syncWal()} afterwards.
7c673cae 3792 *
494da23a 3793 * @param sync true to also fsync to disk.
f67539c2
TL
3794 *
3795 * @throws RocksDBException if an error occurs whilst flushing
7c673cae 3796 */
494da23a
TL
3797 public void flushWal(final boolean sync) throws RocksDBException {
3798 flushWal(nativeHandle_, sync);
7c673cae
FG
3799 }
3800
3801 /**
494da23a 3802 * Sync the WAL.
7c673cae 3803 *
494da23a
TL
3804 * Note that {@link #write(WriteOptions, WriteBatch)} followed by
3805 * {@link #syncWal()} is not exactly the same as
3806 * {@link #write(WriteOptions, WriteBatch)} with
3807 * {@link WriteOptions#sync()} set to true; In the latter case the changes
3808 * won't be visible until the sync is done.
3809 *
3810 * Currently only works if {@link Options#allowMmapWrites()} is set to false.
f67539c2
TL
3811 *
3812 * @throws RocksDBException if an error occurs whilst syncing
7c673cae 3813 */
494da23a
TL
3814 public void syncWal() throws RocksDBException {
3815 syncWal(nativeHandle_);
7c673cae
FG
3816 }
3817
3818 /**
3819 * <p>The sequence number of the most recent transaction.</p>
3820 *
3821 * @return sequence number of the most
3822 * recent transaction.
3823 */
3824 public long getLatestSequenceNumber() {
3825 return getLatestSequenceNumber(nativeHandle_);
3826 }
3827
3828 /**
3829 * <p>Prevent file deletions. Compactions will continue to occur,
3830 * but no obsolete files will be deleted. Calling this multiple
3831 * times have the same effect as calling it once.</p>
3832 *
3833 * @throws RocksDBException thrown if operation was not performed
3834 * successfully.
3835 */
3836 public void disableFileDeletions() throws RocksDBException {
3837 disableFileDeletions(nativeHandle_);
3838 }
3839
3840 /**
3841 * <p>Allow compactions to delete obsolete files.
3842 * If force == true, the call to EnableFileDeletions()
3843 * will guarantee that file deletions are enabled after
3844 * the call, even if DisableFileDeletions() was called
3845 * multiple times before.</p>
3846 *
3847 * <p>If force == false, EnableFileDeletions will only
3848 * enable file deletion after it's been called at least
3849 * as many times as DisableFileDeletions(), enabling
3850 * the two methods to be called by two threads
3851 * concurrently without synchronization
3852 * -- i.e., file deletions will be enabled only after both
3853 * threads call EnableFileDeletions()</p>
3854 *
3855 * @param force boolean value described above.
3856 *
3857 * @throws RocksDBException thrown if operation was not performed
3858 * successfully.
3859 */
3860 public void enableFileDeletions(final boolean force)
3861 throws RocksDBException {
3862 enableFileDeletions(nativeHandle_, force);
3863 }
3864
494da23a
TL
3865 public static class LiveFiles {
3866 /**
3867 * The valid size of the manifest file. The manifest file is an ever growing
3868 * file, but only the portion specified here is valid for this snapshot.
3869 */
3870 public final long manifestFileSize;
3871
3872 /**
3873 * The files are relative to the {@link #getName()} and are not
3874 * absolute paths. Despite being relative paths, the file names begin
3875 * with "/".
3876 */
3877 public final List<String> files;
3878
3879 LiveFiles(final long manifestFileSize, final List<String> files) {
3880 this.manifestFileSize = manifestFileSize;
3881 this.files = files;
3882 }
3883 }
3884
3885 /**
3886 * Retrieve the list of all files in the database after flushing the memtable.
3887 *
3888 * See {@link #getLiveFiles(boolean)}.
3889 *
3890 * @return the live files
f67539c2
TL
3891 *
3892 * @throws RocksDBException if an error occurs whilst retrieving the list
3893 * of live files
494da23a
TL
3894 */
3895 public LiveFiles getLiveFiles() throws RocksDBException {
3896 return getLiveFiles(true);
3897 }
3898
3899 /**
3900 * Retrieve the list of all files in the database.
3901 *
3902 * In case you have multiple column families, even if {@code flushMemtable}
3903 * is true, you still need to call {@link #getSortedWalFiles()}
3904 * after {@link #getLiveFiles(boolean)} to compensate for new data that
3905 * arrived to already-flushed column families while other column families
3906 * were flushing.
3907 *
3908 * NOTE: Calling {@link #getLiveFiles(boolean)} followed by
3909 * {@link #getSortedWalFiles()} can generate a lossless backup.
3910 *
3911 * @param flushMemtable set to true to flush before recoding the live
3912 * files. Setting to false is useful when we don't want to wait for flush
3913 * which may have to wait for compaction to complete taking an
3914 * indeterminate time.
3915 *
3916 * @return the live files
f67539c2
TL
3917 *
3918 * @throws RocksDBException if an error occurs whilst retrieving the list
3919 * of live files
494da23a
TL
3920 */
3921 public LiveFiles getLiveFiles(final boolean flushMemtable)
3922 throws RocksDBException {
3923 final String[] result = getLiveFiles(nativeHandle_, flushMemtable);
3924 if (result == null) {
3925 return null;
3926 }
3927 final String[] files = Arrays.copyOf(result, result.length - 1);
3928 final long manifestFileSize = Long.parseLong(result[result.length - 1]);
3929
3930 return new LiveFiles(manifestFileSize, Arrays.asList(files));
3931 }
3932
3933 /**
3934 * Retrieve the sorted list of all wal files with earliest file first.
3935 *
3936 * @return the log files
f67539c2
TL
3937 *
3938 * @throws RocksDBException if an error occurs whilst retrieving the list
3939 * of sorted WAL files
494da23a
TL
3940 */
3941 public List<LogFile> getSortedWalFiles() throws RocksDBException {
3942 final LogFile[] logFiles = getSortedWalFiles(nativeHandle_);
3943 return Arrays.asList(logFiles);
3944 }
3945
7c673cae
FG
3946 /**
3947 * <p>Returns an iterator that is positioned at a write-batch containing
3948 * seq_number. If the sequence number is non existent, it returns an iterator
3949 * at the first available seq_no after the requested seq_no.</p>
3950 *
3951 * <p>Must set WAL_ttl_seconds or WAL_size_limit_MB to large values to
3952 * use this api, else the WAL files will get
3953 * cleared aggressively and the iterator might keep getting invalid before
3954 * an update is read.</p>
3955 *
3956 * @param sequenceNumber sequence number offset
3957 *
3958 * @return {@link org.rocksdb.TransactionLogIterator} instance.
3959 *
3960 * @throws org.rocksdb.RocksDBException if iterator cannot be retrieved
3961 * from native-side.
3962 */
3963 public TransactionLogIterator getUpdatesSince(final long sequenceNumber)
3964 throws RocksDBException {
3965 return new TransactionLogIterator(
3966 getUpdatesSince(nativeHandle_, sequenceNumber));
3967 }
3968
494da23a
TL
3969 /**
3970 * Delete the file name from the db directory and update the internal state to
3971 * reflect that. Supports deletion of sst and log files only. 'name' must be
3972 * path relative to the db directory. eg. 000001.sst, /archive/000003.log
3973 *
3974 * @param name the file name
f67539c2
TL
3975 *
3976 * @throws RocksDBException if an error occurs whilst deleting the file
494da23a
TL
3977 */
3978 public void deleteFile(final String name) throws RocksDBException {
3979 deleteFile(nativeHandle_, name);
7c673cae
FG
3980 }
3981
494da23a
TL
3982 /**
3983 * Gets a list of all table files metadata.
3984 *
3985 * @return table files metadata.
3986 */
3987 public List<LiveFileMetaData> getLiveFilesMetaData() {
3988 return Arrays.asList(getLiveFilesMetaData(nativeHandle_));
3989 }
3990
3991 /**
3992 * Obtains the meta data of the specified column family of the DB.
3993 *
3994 * @param columnFamilyHandle the column family
3995 *
3996 * @return the column family metadata
3997 */
3998 public ColumnFamilyMetaData getColumnFamilyMetaData(
3999 /* @Nullable */ final ColumnFamilyHandle columnFamilyHandle) {
4000 return getColumnFamilyMetaData(nativeHandle_,
4001 columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_);
4002 }
4003
4004 /**
4005 * Obtains the meta data of the default column family of the DB.
4006 *
4007 * @return the column family metadata
4008 */
20effc67 4009 public ColumnFamilyMetaData getColumnFamilyMetaData() {
494da23a 4010 return getColumnFamilyMetaData(null);
7c673cae
FG
4011 }
4012
11fdf7f2
TL
4013 /**
4014 * ingestExternalFile will load a list of external SST files (1) into the DB
4015 * We will try to find the lowest possible level that the file can fit in, and
4016 * ingest the file into this level (2). A file that have a key range that
4017 * overlap with the memtable key range will require us to Flush the memtable
4018 * first before ingesting the file.
4019 *
4020 * (1) External SST files can be created using {@link SstFileWriter}
4021 * (2) We will try to ingest the files to the lowest possible level
4022 * even if the file compression doesn't match the level compression
4023 *
4024 * @param filePathList The list of files to ingest
4025 * @param ingestExternalFileOptions the options for the ingestion
4026 *
4027 * @throws RocksDBException thrown if error happens in underlying
4028 * native library.
4029 */
4030 public void ingestExternalFile(final List<String> filePathList,
4031 final IngestExternalFileOptions ingestExternalFileOptions)
7c673cae 4032 throws RocksDBException {
11fdf7f2 4033 ingestExternalFile(nativeHandle_, getDefaultColumnFamily().nativeHandle_,
494da23a 4034 filePathList.toArray(new String[0]),
11fdf7f2 4035 filePathList.size(), ingestExternalFileOptions.nativeHandle_);
7c673cae
FG
4036 }
4037
11fdf7f2
TL
4038 /**
4039 * ingestExternalFile will load a list of external SST files (1) into the DB
4040 * We will try to find the lowest possible level that the file can fit in, and
4041 * ingest the file into this level (2). A file that have a key range that
4042 * overlap with the memtable key range will require us to Flush the memtable
4043 * first before ingesting the file.
4044 *
4045 * (1) External SST files can be created using {@link SstFileWriter}
4046 * (2) We will try to ingest the files to the lowest possible level
4047 * even if the file compression doesn't match the level compression
4048 *
4049 * @param columnFamilyHandle The column family for the ingested files
4050 * @param filePathList The list of files to ingest
4051 * @param ingestExternalFileOptions the options for the ingestion
4052 *
4053 * @throws RocksDBException thrown if error happens in underlying
4054 * native library.
4055 */
4056 public void ingestExternalFile(final ColumnFamilyHandle columnFamilyHandle,
4057 final List<String> filePathList,
4058 final IngestExternalFileOptions ingestExternalFileOptions)
7c673cae 4059 throws RocksDBException {
11fdf7f2 4060 ingestExternalFile(nativeHandle_, columnFamilyHandle.nativeHandle_,
494da23a 4061 filePathList.toArray(new String[0]),
11fdf7f2 4062 filePathList.size(), ingestExternalFileOptions.nativeHandle_);
7c673cae
FG
4063 }
4064
494da23a
TL
4065 /**
4066 * Verify checksum
4067 *
4068 * @throws RocksDBException if the checksum is not valid
4069 */
4070 public void verifyChecksum() throws RocksDBException {
4071 verifyChecksum(nativeHandle_);
4072 }
4073
4074 /**
4075 * Gets the handle for the default column family
4076 *
4077 * @return The handle of the default column family
4078 */
4079 public ColumnFamilyHandle getDefaultColumnFamily() {
4080 final ColumnFamilyHandle cfHandle = new ColumnFamilyHandle(this,
4081 getDefaultColumnFamily(nativeHandle_));
4082 cfHandle.disOwnNativeHandle();
4083 return cfHandle;
4084 }
4085
4086 /**
4087 * Get the properties of all tables.
4088 *
4089 * @param columnFamilyHandle the column family handle, or null for the default
4090 * column family.
4091 *
4092 * @return the properties
f67539c2
TL
4093 *
4094 * @throws RocksDBException if an error occurs whilst getting the properties
494da23a
TL
4095 */
4096 public Map<String, TableProperties> getPropertiesOfAllTables(
4097 /* @Nullable */final ColumnFamilyHandle columnFamilyHandle)
4098 throws RocksDBException {
4099 return getPropertiesOfAllTables(nativeHandle_,
4100 columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_);
4101 }
4102
4103 /**
4104 * Get the properties of all tables in the default column family.
4105 *
4106 * @return the properties
f67539c2
TL
4107 *
4108 * @throws RocksDBException if an error occurs whilst getting the properties
494da23a
TL
4109 */
4110 public Map<String, TableProperties> getPropertiesOfAllTables()
4111 throws RocksDBException {
4112 return getPropertiesOfAllTables(null);
4113 }
4114
4115 /**
4116 * Get the properties of tables in range.
4117 *
4118 * @param columnFamilyHandle the column family handle, or null for the default
4119 * column family.
4120 * @param ranges the ranges over which to get the table properties
4121 *
4122 * @return the properties
f67539c2
TL
4123 *
4124 * @throws RocksDBException if an error occurs whilst getting the properties
494da23a
TL
4125 */
4126 public Map<String, TableProperties> getPropertiesOfTablesInRange(
4127 /* @Nullable */final ColumnFamilyHandle columnFamilyHandle,
4128 final List<Range> ranges) throws RocksDBException {
4129 return getPropertiesOfTablesInRange(nativeHandle_,
4130 columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
4131 toRangeSliceHandles(ranges));
4132 }
4133
4134 /**
4135 * Get the properties of tables in range for the default column family.
4136 *
4137 * @param ranges the ranges over which to get the table properties
4138 *
4139 * @return the properties
f67539c2
TL
4140 *
4141 * @throws RocksDBException if an error occurs whilst getting the properties
494da23a
TL
4142 */
4143 public Map<String, TableProperties> getPropertiesOfTablesInRange(
4144 final List<Range> ranges) throws RocksDBException {
4145 return getPropertiesOfTablesInRange(null, ranges);
4146 }
4147
4148 /**
4149 * Suggest the range to compact.
4150 *
4151 * @param columnFamilyHandle the column family handle, or null for the default
4152 * column family.
4153 *
4154 * @return the suggested range.
f67539c2
TL
4155 *
4156 * @throws RocksDBException if an error occurs whilst suggesting the range
494da23a
TL
4157 */
4158 public Range suggestCompactRange(
4159 /* @Nullable */final ColumnFamilyHandle columnFamilyHandle)
4160 throws RocksDBException {
4161 final long[] rangeSliceHandles = suggestCompactRange(nativeHandle_,
4162 columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_);
4163 return new Range(new Slice(rangeSliceHandles[0]),
4164 new Slice(rangeSliceHandles[1]));
4165 }
4166
4167 /**
4168 * Suggest the range to compact for the default column family.
4169 *
4170 * @return the suggested range.
f67539c2
TL
4171 *
4172 * @throws RocksDBException if an error occurs whilst suggesting the range
494da23a
TL
4173 */
4174 public Range suggestCompactRange()
4175 throws RocksDBException {
4176 return suggestCompactRange(null);
4177 }
4178
4179 /**
4180 * Promote L0.
4181 *
4182 * @param columnFamilyHandle the column family handle,
4183 * or null for the default column family.
f67539c2
TL
4184 * @param targetLevel the target level for L0
4185 *
4186 * @throws RocksDBException if an error occurs whilst promoting L0
494da23a
TL
4187 */
4188 public void promoteL0(
4189 /* @Nullable */final ColumnFamilyHandle columnFamilyHandle,
4190 final int targetLevel) throws RocksDBException {
4191 promoteL0(nativeHandle_,
4192 columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
4193 targetLevel);
4194 }
4195
4196 /**
4197 * Promote L0 for the default column family.
f67539c2
TL
4198 *
4199 * @param targetLevel the target level for L0
4200 *
4201 * @throws RocksDBException if an error occurs whilst promoting L0
494da23a
TL
4202 */
4203 public void promoteL0(final int targetLevel)
4204 throws RocksDBException {
4205 promoteL0(null, targetLevel);
4206 }
4207
4208 /**
4209 * Trace DB operations.
4210 *
4211 * Use {@link #endTrace()} to stop tracing.
4212 *
4213 * @param traceOptions the options
4214 * @param traceWriter the trace writer
f67539c2
TL
4215 *
4216 * @throws RocksDBException if an error occurs whilst starting the trace
494da23a
TL
4217 */
4218 public void startTrace(final TraceOptions traceOptions,
4219 final AbstractTraceWriter traceWriter) throws RocksDBException {
4220 startTrace(nativeHandle_, traceOptions.getMaxTraceFileSize(),
4221 traceWriter.nativeHandle_);
4222 /**
4223 * NOTE: {@link #startTrace(long, long, long) transfers the ownership
4224 * from Java to C++, so we must disown the native handle here.
4225 */
4226 traceWriter.disOwnNativeHandle();
4227 }
4228
4229 /**
4230 * Stop tracing DB operations.
4231 *
4232 * See {@link #startTrace(TraceOptions, AbstractTraceWriter)}
f67539c2
TL
4233 *
4234 * @throws RocksDBException if an error occurs whilst ending the trace
494da23a
TL
4235 */
4236 public void endTrace() throws RocksDBException {
4237 endTrace(nativeHandle_);
4238 }
4239
20effc67
TL
4240 /**
4241 * Make the secondary instance catch up with the primary by tailing and
4242 * replaying the MANIFEST and WAL of the primary.
4243 * Column families created by the primary after the secondary instance starts
4244 * will be ignored unless the secondary instance closes and restarts with the
4245 * newly created column families.
4246 * Column families that exist before secondary instance starts and dropped by
4247 * the primary afterwards will be marked as dropped. However, as long as the
4248 * secondary instance does not delete the corresponding column family
4249 * handles, the data of the column family is still accessible to the
4250 * secondary.
4251 *
4252 * @throws RocksDBException thrown if error happens in underlying
4253 * native library.
4254 */
4255 public void tryCatchUpWithPrimary() throws RocksDBException {
4256 tryCatchUpWithPrimary(nativeHandle_);
4257 }
4258
f67539c2
TL
4259 /**
4260 * Delete files in multiple ranges at once.
4261 * Delete files in a lot of ranges one at a time can be slow, use this API for
4262 * better performance in that case.
4263 *
4264 * @param columnFamily - The column family for operation (null for default)
4265 * @param includeEnd - Whether ranges should include end
4266 * @param ranges - pairs of ranges (from1, to1, from2, to2, ...)
4267 *
4268 * @throws RocksDBException thrown if error happens in underlying
4269 * native library.
4270 */
4271 public void deleteFilesInRanges(final ColumnFamilyHandle columnFamily,
4272 final List<byte[]> ranges, final boolean includeEnd)
4273 throws RocksDBException {
4274 if (ranges.size() == 0) {
4275 return;
4276 }
4277 if ((ranges.size() % 2) != 0) {
4278 throw new IllegalArgumentException("Ranges size needs to be multiple of 2 "
4279 + "(from1, to1, from2, to2, ...), but is " + ranges.size());
4280 }
4281
4282 final byte[][] rangesArray = ranges.toArray(new byte[ranges.size()][]);
4283
4284 deleteFilesInRanges(nativeHandle_, columnFamily == null ? 0 : columnFamily.nativeHandle_,
4285 rangesArray, includeEnd);
4286 }
4287
11fdf7f2
TL
4288 /**
4289 * Static method to destroy the contents of the specified database.
4290 * Be very careful using this method.
4291 *
4292 * @param path the path to the Rocksdb database.
4293 * @param options {@link org.rocksdb.Options} instance.
4294 *
4295 * @throws RocksDBException thrown if error happens in underlying
4296 * native library.
4297 */
4298 public static void destroyDB(final String path, final Options options)
7c673cae 4299 throws RocksDBException {
11fdf7f2 4300 destroyDB(path, options.nativeHandle_);
7c673cae
FG
4301 }
4302
494da23a
TL
4303 private /* @Nullable */ long[] toNativeHandleList(
4304 /* @Nullable */ final List<? extends RocksObject> objectList) {
4305 if (objectList == null) {
4306 return null;
4307 }
4308 final int len = objectList.size();
4309 final long[] handleList = new long[len];
4310 for (int i = 0; i < len; i++) {
4311 handleList[i] = objectList.get(i).nativeHandle_;
4312 }
4313 return handleList;
4314 }
4315
4316 private static long[] toRangeSliceHandles(final List<Range> ranges) {
4317 final long rangeSliceHandles[] = new long [ranges.size() * 2];
4318 for (int i = 0, j = 0; i < ranges.size(); i++) {
4319 final Range range = ranges.get(i);
4320 rangeSliceHandles[j++] = range.start.getNativeHandle();
4321 rangeSliceHandles[j++] = range.limit.getNativeHandle();
4322 }
4323 return rangeSliceHandles;
4324 }
4325
1e59de90 4326 protected void storeOptionsInstance(DBOptionsInterface<?> options) {
494da23a
TL
4327 options_ = options;
4328 }
4329
4330 private static void checkBounds(int offset, int len, int size) {
4331 if ((offset | len | (offset + len) | (size - (offset + len))) < 0) {
4332 throw new IndexOutOfBoundsException(String.format("offset(%d), len(%d), size(%d)", offset, len, size));
4333 }
4334 }
4335
4336 private static int computeCapacityHint(final int estimatedNumberOfItems) {
4337 // Default load factor for HashMap is 0.75, so N * 1.5 will be at the load
4338 // limit. We add +1 for a buffer.
4339 return (int)Math.ceil(estimatedNumberOfItems * 1.5 + 1.0);
7c673cae
FG
4340 }
4341
4342 // native methods
494da23a 4343 private native static long open(final long optionsHandle,
7c673cae
FG
4344 final String path) throws RocksDBException;
4345
4346 /**
4347 * @param optionsHandle Native handle pointing to an Options object
4348 * @param path The directory path for the database files
4349 * @param columnFamilyNames An array of column family names
4350 * @param columnFamilyOptions An array of native handles pointing to
4351 * ColumnFamilyOptions objects
4352 *
4353 * @return An array of native handles, [0] is the handle of the RocksDB object
4354 * [1..1+n] are handles of the ColumnFamilyReferences
4355 *
4356 * @throws RocksDBException thrown if the database could not be opened
4357 */
494da23a 4358 private native static long[] open(final long optionsHandle,
7c673cae
FG
4359 final String path, final byte[][] columnFamilyNames,
4360 final long[] columnFamilyOptions) throws RocksDBException;
4361
20effc67
TL
4362 private native static long openROnly(final long optionsHandle, final String path,
4363 final boolean errorIfWalFileExists) throws RocksDBException;
7c673cae
FG
4364
4365 /**
4366 * @param optionsHandle Native handle pointing to an Options object
4367 * @param path The directory path for the database files
4368 * @param columnFamilyNames An array of column family names
4369 * @param columnFamilyOptions An array of native handles pointing to
4370 * ColumnFamilyOptions objects
4371 *
4372 * @return An array of native handles, [0] is the handle of the RocksDB object
4373 * [1..1+n] are handles of the ColumnFamilyReferences
4374 *
4375 * @throws RocksDBException thrown if the database could not be opened
4376 */
20effc67
TL
4377 private native static long[] openROnly(final long optionsHandle, final String path,
4378 final byte[][] columnFamilyNames, final long[] columnFamilyOptions,
4379 final boolean errorIfWalFileExists) throws RocksDBException;
4380
4381 private native static long openAsSecondary(final long optionsHandle, final String path,
4382 final String secondaryPath) throws RocksDBException;
4383
4384 private native static long[] openAsSecondary(final long optionsHandle, final String path,
4385 final String secondaryPath, final byte[][] columnFamilyNames,
4386 final long[] columnFamilyOptions) throws RocksDBException;
7c673cae 4387
494da23a
TL
4388 @Override protected native void disposeInternal(final long handle);
4389
4390 private native static void closeDatabase(final long handle)
4391 throws RocksDBException;
4392 private native static byte[][] listColumnFamilies(final long optionsHandle,
4393 final String path) throws RocksDBException;
4394 private native long createColumnFamily(final long handle,
4395 final byte[] columnFamilyName, final int columnFamilyNamelen,
4396 final long columnFamilyOptions) throws RocksDBException;
4397 private native long[] createColumnFamilies(final long handle,
4398 final long columnFamilyOptionsHandle, final byte[][] columnFamilyNames)
4399 throws RocksDBException;
4400 private native long[] createColumnFamilies(final long handle,
4401 final long columnFamilyOptionsHandles[], final byte[][] columnFamilyNames)
4402 throws RocksDBException;
4403 private native void dropColumnFamily(
4404 final long handle, final long cfHandle) throws RocksDBException;
4405 private native void dropColumnFamilies(final long handle,
4406 final long[] cfHandles) throws RocksDBException;
494da23a
TL
4407 private native void put(final long handle, final byte[] key,
4408 final int keyOffset, final int keyLength, final byte[] value,
4409 final int valueOffset, int valueLength) throws RocksDBException;
4410 private native void put(final long handle, final byte[] key, final int keyOffset,
4411 final int keyLength, final byte[] value, final int valueOffset,
4412 final int valueLength, final long cfHandle) throws RocksDBException;
4413 private native void put(final long handle, final long writeOptHandle,
4414 final byte[] key, final int keyOffset, final int keyLength,
4415 final byte[] value, final int valueOffset, final int valueLength)
4416 throws RocksDBException;
4417 private native void put(final long handle, final long writeOptHandle,
4418 final byte[] key, final int keyOffset, final int keyLength,
4419 final byte[] value, final int valueOffset, final int valueLength,
4420 final long cfHandle) throws RocksDBException;
4421 private native void delete(final long handle, final byte[] key,
4422 final int keyOffset, final int keyLength) throws RocksDBException;
4423 private native void delete(final long handle, final byte[] key,
4424 final int keyOffset, final int keyLength, final long cfHandle)
4425 throws RocksDBException;
4426 private native void delete(final long handle, final long writeOptHandle,
4427 final byte[] key, final int keyOffset, final int keyLength)
4428 throws RocksDBException;
4429 private native void delete(final long handle, final long writeOptHandle,
4430 final byte[] key, final int keyOffset, final int keyLength,
4431 final long cfHandle) throws RocksDBException;
4432 private native void singleDelete(
4433 final long handle, final byte[] key, final int keyLen)
4434 throws RocksDBException;
4435 private native void singleDelete(
4436 final long handle, final byte[] key, final int keyLen,
4437 final long cfHandle) throws RocksDBException;
4438 private native void singleDelete(
4439 final long handle, final long writeOptHandle, final byte[] key,
4440 final int keyLen) throws RocksDBException;
4441 private native void singleDelete(
4442 final long handle, final long writeOptHandle,
4443 final byte[] key, final int keyLen, final long cfHandle)
7c673cae 4444 throws RocksDBException;
494da23a
TL
4445 private native void deleteRange(final long handle, final byte[] beginKey,
4446 final int beginKeyOffset, final int beginKeyLength, final byte[] endKey,
4447 final int endKeyOffset, final int endKeyLength) throws RocksDBException;
4448 private native void deleteRange(final long handle, final byte[] beginKey,
4449 final int beginKeyOffset, final int beginKeyLength, final byte[] endKey,
4450 final int endKeyOffset, final int endKeyLength, final long cfHandle)
4451 throws RocksDBException;
4452 private native void deleteRange(final long handle, final long writeOptHandle,
4453 final byte[] beginKey, final int beginKeyOffset, final int beginKeyLength,
4454 final byte[] endKey, final int endKeyOffset, final int endKeyLength)
4455 throws RocksDBException;
4456 private native void deleteRange(
4457 final long handle, final long writeOptHandle, final byte[] beginKey,
4458 final int beginKeyOffset, final int beginKeyLength, final byte[] endKey,
4459 final int endKeyOffset, final int endKeyLength, final long cfHandle)
4460 throws RocksDBException;
4461 private native void merge(final long handle, final byte[] key,
4462 final int keyOffset, final int keyLength, final byte[] value,
4463 final int valueOffset, final int valueLength) throws RocksDBException;
4464 private native void merge(final long handle, final byte[] key,
4465 final int keyOffset, final int keyLength, final byte[] value,
4466 final int valueOffset, final int valueLength, final long cfHandle)
4467 throws RocksDBException;
4468 private native void merge(final long handle, final long writeOptHandle,
4469 final byte[] key, final int keyOffset, final int keyLength,
4470 final byte[] value, final int valueOffset, final int valueLength)
4471 throws RocksDBException;
4472 private native void merge(final long handle, final long writeOptHandle,
4473 final byte[] key, final int keyOffset, final int keyLength,
4474 final byte[] value, final int valueOffset, final int valueLength,
4475 final long cfHandle) throws RocksDBException;
4476 private native void write0(final long handle, final long writeOptHandle,
4477 final long wbHandle) throws RocksDBException;
4478 private native void write1(final long handle, final long writeOptHandle,
4479 final long wbwiHandle) throws RocksDBException;
4480 private native int get(final long handle, final byte[] key,
4481 final int keyOffset, final int keyLength, final byte[] value,
4482 final int valueOffset, final int valueLength) throws RocksDBException;
4483 private native int get(final long handle, final byte[] key,
4484 final int keyOffset, final int keyLength, byte[] value,
4485 final int valueOffset, final int valueLength, final long cfHandle)
4486 throws RocksDBException;
4487 private native int get(final long handle, final long readOptHandle,
4488 final byte[] key, final int keyOffset, final int keyLength,
4489 final byte[] value, final int valueOffset, final int valueLength)
4490 throws RocksDBException;
4491 private native int get(final long handle, final long readOptHandle,
4492 final byte[] key, final int keyOffset, final int keyLength,
4493 final byte[] value, final int valueOffset, final int valueLength,
4494 final long cfHandle) throws RocksDBException;
4495 private native byte[] get(final long handle, byte[] key, final int keyOffset,
4496 final int keyLength) throws RocksDBException;
4497 private native byte[] get(final long handle, final byte[] key,
4498 final int keyOffset, final int keyLength, final long cfHandle)
4499 throws RocksDBException;
4500 private native byte[] get(final long handle, final long readOptHandle,
4501 final byte[] key, final int keyOffset, final int keyLength)
4502 throws RocksDBException;
4503 private native byte[] get(final long handle,
4504 final long readOptHandle, final byte[] key, final int keyOffset,
4505 final int keyLength, final long cfHandle) throws RocksDBException;
4506 private native byte[][] multiGet(final long dbHandle, final byte[][] keys,
4507 final int[] keyOffsets, final int[] keyLengths);
4508 private native byte[][] multiGet(final long dbHandle, final byte[][] keys,
4509 final int[] keyOffsets, final int[] keyLengths,
4510 final long[] columnFamilyHandles);
4511 private native byte[][] multiGet(final long dbHandle, final long rOptHandle,
4512 final byte[][] keys, final int[] keyOffsets, final int[] keyLengths);
4513 private native byte[][] multiGet(final long dbHandle, final long rOptHandle,
4514 final byte[][] keys, final int[] keyOffsets, final int[] keyLengths,
4515 final long[] columnFamilyHandles);
1e59de90
TL
4516
4517 private native void multiGet(final long dbHandle, final long rOptHandle,
4518 final long[] columnFamilyHandles, final ByteBuffer[] keysArray, final int[] keyOffsets,
4519 final int[] keyLengths, final ByteBuffer[] valuesArray, final int[] valuesSizeArray,
4520 final Status[] statusArray);
4521
f67539c2
TL
4522 private native boolean keyMayExist(
4523 final long handle, final long cfHandle, final long readOptHandle,
4524 final byte[] key, final int keyOffset, final int keyLength);
4525 private native byte[][] keyMayExistFoundValue(
4526 final long handle, final long cfHandle, final long readOptHandle,
4527 final byte[] key, final int keyOffset, final int keyLength);
4528 private native void putDirect(long handle, long writeOptHandle, ByteBuffer key, int keyOffset,
4529 int keyLength, ByteBuffer value, int valueOffset, int valueLength, long cfHandle)
4530 throws RocksDBException;
494da23a
TL
4531 private native long iterator(final long handle);
4532 private native long iterator(final long handle, final long readOptHandle);
4533 private native long iteratorCF(final long handle, final long cfHandle);
4534 private native long iteratorCF(final long handle, final long cfHandle,
4535 final long readOptHandle);
4536 private native long[] iterators(final long handle,
4537 final long[] columnFamilyHandles, final long readOptHandle)
7c673cae 4538 throws RocksDBException;
494da23a
TL
4539 private native long getSnapshot(final long nativeHandle);
4540 private native void releaseSnapshot(
4541 final long nativeHandle, final long snapshotHandle);
4542 private native String getProperty(final long nativeHandle,
4543 final long cfHandle, final String property, final int propertyLength)
7c673cae 4544 throws RocksDBException;
494da23a
TL
4545 private native Map<String, String> getMapProperty(final long nativeHandle,
4546 final long cfHandle, final String property, final int propertyLength)
7c673cae 4547 throws RocksDBException;
f67539c2
TL
4548 private native int getDirect(long handle, long readOptHandle, ByteBuffer key, int keyOffset,
4549 int keyLength, ByteBuffer value, int valueOffset, int valueLength, long cfHandle)
4550 throws RocksDBException;
1e59de90
TL
4551 private native boolean keyMayExistDirect(final long handle, final long cfHhandle,
4552 final long readOptHandle, final ByteBuffer key, final int keyOffset, final int keyLength);
4553 private native int[] keyMayExistDirectFoundValue(final long handle, final long cfHhandle,
4554 final long readOptHandle, final ByteBuffer key, final int keyOffset, final int keyLength,
4555 final ByteBuffer value, final int valueOffset, final int valueLength);
f67539c2
TL
4556 private native void deleteDirect(long handle, long optHandle, ByteBuffer key, int keyOffset,
4557 int keyLength, long cfHandle) throws RocksDBException;
494da23a
TL
4558 private native long getLongProperty(final long nativeHandle,
4559 final long cfHandle, final String property, final int propertyLength)
7c673cae 4560 throws RocksDBException;
494da23a 4561 private native void resetStats(final long nativeHandle)
7c673cae 4562 throws RocksDBException;
494da23a
TL
4563 private native long getAggregatedLongProperty(final long nativeHandle,
4564 final String property, int propertyLength) throws RocksDBException;
4565 private native long[] getApproximateSizes(final long nativeHandle,
4566 final long columnFamilyHandle, final long[] rangeSliceHandles,
4567 final byte includeFlags);
1e59de90
TL
4568 private native long[] getApproximateMemTableStats(final long nativeHandle,
4569 final long columnFamilyHandle, final long rangeStartSliceHandle,
4570 final long rangeLimitSliceHandle);
494da23a
TL
4571 private native void compactRange(final long handle,
4572 /* @Nullable */ final byte[] begin, final int beginLen,
4573 /* @Nullable */ final byte[] end, final int endLen,
4574 final long compactRangeOptHandle, final long cfHandle)
7c673cae 4575 throws RocksDBException;
494da23a
TL
4576 private native void setOptions(final long handle, final long cfHandle,
4577 final String[] keys, final String[] values) throws RocksDBException;
1e59de90 4578 private native String getOptions(final long handle, final long cfHandle);
494da23a
TL
4579 private native void setDBOptions(final long handle,
4580 final String[] keys, final String[] values) throws RocksDBException;
1e59de90 4581 private native String getDBOptions(final long handle);
494da23a
TL
4582 private native String[] compactFiles(final long handle,
4583 final long compactionOptionsHandle,
4584 final long columnFamilyHandle,
4585 final String[] inputFileNames,
4586 final int outputLevel,
4587 final int outputPathId,
4588 final long compactionJobInfoHandle) throws RocksDBException;
20effc67
TL
4589 private native void cancelAllBackgroundWork(final long handle,
4590 final boolean wait);
494da23a 4591 private native void pauseBackgroundWork(final long handle)
7c673cae 4592 throws RocksDBException;
494da23a 4593 private native void continueBackgroundWork(final long handle)
7c673cae 4594 throws RocksDBException;
494da23a
TL
4595 private native void enableAutoCompaction(final long handle,
4596 final long[] columnFamilyHandles) throws RocksDBException;
4597 private native int numberLevels(final long handle,
4598 final long columnFamilyHandle);
4599 private native int maxMemCompactionLevel(final long handle,
4600 final long columnFamilyHandle);
4601 private native int level0StopWriteTrigger(final long handle,
4602 final long columnFamilyHandle);
4603 private native String getName(final long handle);
4604 private native long getEnv(final long handle);
4605 private native void flush(final long handle, final long flushOptHandle,
4606 /* @Nullable */ final long[] cfHandles) throws RocksDBException;
4607 private native void flushWal(final long handle, final boolean sync)
7c673cae 4608 throws RocksDBException;
494da23a
TL
4609 private native void syncWal(final long handle) throws RocksDBException;
4610 private native long getLatestSequenceNumber(final long handle);
494da23a
TL
4611 private native void disableFileDeletions(long handle) throws RocksDBException;
4612 private native void enableFileDeletions(long handle, boolean force)
7c673cae 4613 throws RocksDBException;
494da23a
TL
4614 private native String[] getLiveFiles(final long handle,
4615 final boolean flushMemtable) throws RocksDBException;
4616 private native LogFile[] getSortedWalFiles(final long handle)
7c673cae 4617 throws RocksDBException;
494da23a
TL
4618 private native long getUpdatesSince(final long handle,
4619 final long sequenceNumber) throws RocksDBException;
4620 private native void deleteFile(final long handle, final String name)
7c673cae 4621 throws RocksDBException;
494da23a
TL
4622 private native LiveFileMetaData[] getLiveFilesMetaData(final long handle);
4623 private native ColumnFamilyMetaData getColumnFamilyMetaData(
4624 final long handle, final long columnFamilyHandle);
4625 private native void ingestExternalFile(final long handle,
4626 final long columnFamilyHandle, final String[] filePathList,
4627 final int filePathListLen, final long ingestExternalFileOptionsHandle)
7c673cae 4628 throws RocksDBException;
494da23a
TL
4629 private native void verifyChecksum(final long handle) throws RocksDBException;
4630 private native long getDefaultColumnFamily(final long handle);
4631 private native Map<String, TableProperties> getPropertiesOfAllTables(
4632 final long handle, final long columnFamilyHandle) throws RocksDBException;
4633 private native Map<String, TableProperties> getPropertiesOfTablesInRange(
4634 final long handle, final long columnFamilyHandle,
4635 final long[] rangeSliceHandles);
4636 private native long[] suggestCompactRange(final long handle,
4637 final long columnFamilyHandle) throws RocksDBException;
4638 private native void promoteL0(final long handle,
4639 final long columnFamilyHandle, final int tragetLevel)
7c673cae 4640 throws RocksDBException;
494da23a
TL
4641 private native void startTrace(final long handle, final long maxTraceFileSize,
4642 final long traceWriterHandle) throws RocksDBException;
4643 private native void endTrace(final long handle) throws RocksDBException;
20effc67 4644 private native void tryCatchUpWithPrimary(final long handle) throws RocksDBException;
f67539c2
TL
4645 private native void deleteFilesInRanges(long handle, long cfHandle, final byte[][] ranges,
4646 boolean include_end) throws RocksDBException;
494da23a 4647
11fdf7f2
TL
4648 private native static void destroyDB(final String path,
4649 final long optionsHandle) throws RocksDBException;
494da23a 4650
20effc67
TL
4651 private native static int version();
4652
1e59de90 4653 protected DBOptionsInterface<?> options_;
20effc67
TL
4654 private static Version version;
4655
4656 public static class Version {
4657 private final byte major;
4658 private final byte minor;
4659 private final byte patch;
4660
4661 public Version(final byte major, final byte minor, final byte patch) {
4662 this.major = major;
4663 this.minor = minor;
4664 this.patch = patch;
4665 }
4666
4667 public int getMajor() {
4668 return major;
4669 }
4670
4671 public int getMinor() {
4672 return minor;
4673 }
4674
4675 public int getPatch() {
4676 return patch;
4677 }
4678
4679 @Override
4680 public String toString() {
4681 return getMajor() + "." + getMinor() + "." + getPatch();
4682 }
4683
4684 private static Version fromEncodedVersion(int encodedVersion) {
4685 final byte patch = (byte) (encodedVersion & 0xff);
4686 encodedVersion >>= 8;
4687 final byte minor = (byte) (encodedVersion & 0xff);
4688 encodedVersion >>= 8;
4689 final byte major = (byte) (encodedVersion & 0xff);
4690
4691 return new Version(major, minor, patch);
4692 }
4693 }
7c673cae 4694}