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