org.forstdb.RocksDB Maven / Gradle / Ivy
Show all versions of forstjni Show documentation
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
// This source code is licensed under both the GPLv2 (found in the
// COPYING file in the root directory) and Apache 2.0 License
// (found in the LICENSE.Apache file in the root directory).
package org.forstdb;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.forstdb.util.BufferUtil.CheckBounds;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import org.forstdb.util.Environment;
/**
* A RocksDB is a persistent ordered map from keys to values. It is safe for
* concurrent access from multiple threads without any external synchronization.
* All methods of this class could potentially throw RocksDBException, which
* indicates sth wrong at the RocksDB library side and the call failed.
*/
public class RocksDB extends RocksObject {
public static final byte[] DEFAULT_COLUMN_FAMILY = "default".getBytes(UTF_8);
public static final int NOT_FOUND = -1;
private enum LibraryState {
NOT_LOADED,
LOADING,
LOADED
}
private static final AtomicReference libraryLoaded =
new AtomicReference<>(LibraryState.NOT_LOADED);
static final String PERFORMANCE_OPTIMIZATION_FOR_A_VERY_SPECIFIC_WORKLOAD =
"Performance optimization for a very specific workload";
private static final String BB_ALL_DIRECT_OR_INDIRECT =
"ByteBuffer parameters must all be direct, or must all be indirect";
private ColumnFamilyHandle defaultColumnFamilyHandle_;
private final ReadOptions defaultReadOptions_ = new ReadOptions();
private final List ownedColumnFamilyHandles = new ArrayList<>();
/**
* Loads the necessary library files.
* Calling this method twice will have no effect.
* By default the method extracts the shared library for loading at
* java.io.tmpdir, however, you can override this temporary location by
* setting the environment variable ROCKSDB_SHAREDLIB_DIR.
*/
@SuppressWarnings("PMD.EmptyCatchBlock")
public static void loadLibrary() {
if (libraryLoaded.get() == LibraryState.LOADED) {
return;
}
if (libraryLoaded.compareAndSet(LibraryState.NOT_LOADED,
LibraryState.LOADING)) {
final String tmpDir = System.getenv("ROCKSDB_SHAREDLIB_DIR");
// loading possibly necessary libraries.
for (final CompressionType compressionType : CompressionType.values()) {
try {
if (compressionType.getLibraryName() != null) {
System.loadLibrary(compressionType.getLibraryName());
}
} catch (final UnsatisfiedLinkError e) {
// since it may be optional, we ignore its loading failure here.
}
}
try {
NativeLibraryLoader.getInstance().loadLibrary(tmpDir);
} catch (final IOException e) {
libraryLoaded.set(LibraryState.NOT_LOADED);
throw new RuntimeException("Unable to load the RocksDB shared library",
e);
}
final int encodedVersion = version();
version = Version.fromEncodedVersion(encodedVersion);
libraryLoaded.set(LibraryState.LOADED);
return;
}
while (libraryLoaded.get() == LibraryState.LOADING) {
try {
Thread.sleep(10);
} catch(final InterruptedException e) {
throw new RuntimeException("Loading the RocksDB shared library is interrupted",
e);
}
}
}
/**
* Tries to load the necessary library files from the given list of
* directories.
*
* @param paths a list of strings where each describes a directory
* of a library.
*/
@SuppressWarnings("PMD.EmptyCatchBlock")
public static void loadLibrary(final List paths) {
if (libraryLoaded.get() == LibraryState.LOADED) {
return;
}
if (libraryLoaded.compareAndSet(LibraryState.NOT_LOADED,
LibraryState.LOADING)) {
for (final CompressionType compressionType : CompressionType.values()) {
if (compressionType.equals(CompressionType.NO_COMPRESSION)) {
continue;
}
for (final String path : paths) {
try {
System.load(path + "/" + Environment.getSharedLibraryFileName(
compressionType.getLibraryName()));
break;
} catch (final UnsatisfiedLinkError e) {
// since they are optional, we ignore loading fails.
}
}
}
boolean success = false;
UnsatisfiedLinkError err = null;
for (final String path : paths) {
try {
System.load(path + "/" +
Environment.getJniLibraryFileName("rocksdbjni"));
success = true;
break;
} catch (final UnsatisfiedLinkError e) {
err = e;
}
}
if (!success) {
libraryLoaded.set(LibraryState.NOT_LOADED);
throw err;
}
final int encodedVersion = version();
version = Version.fromEncodedVersion(encodedVersion);
libraryLoaded.set(LibraryState.LOADED);
return;
}
while (libraryLoaded.get() == LibraryState.LOADING) {
try {
Thread.sleep(10);
} catch(final InterruptedException e) {
throw new RuntimeException("Loading the RocksDB shared library is interrupted",
e);
}
}
}
public static Version rocksdbVersion() {
return version;
}
/**
* Private constructor.
*
* @param nativeHandle The native handle of the C++ RocksDB object
*/
protected RocksDB(final long nativeHandle) {
super(nativeHandle);
}
/**
* The factory constructor of RocksDB that opens a RocksDB instance given
* the path to the database using the default options w/ createIfMissing
* set to true.
*
* @param path the path to the rocksdb.
* @return a {@link RocksDB} instance on success, null if the specified
* {@link RocksDB} can not be opened.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
* @see Options#setCreateIfMissing(boolean)
*/
public static RocksDB open(final String path) throws RocksDBException {
RocksDB.loadLibrary();
try (Options options = new Options()) {
options.setCreateIfMissing(true);
return open(options, path);
}
}
/**
* The factory constructor of RocksDB that opens a RocksDB instance given
* the path to the database using the specified options and db path and a list
* of column family names.
*
* If opened in read write mode every existing column family name must be
* passed within the list to this method.
*
* If opened in read-only mode only a subset of existing column families must
* be passed to this method.
*
* Options instance *should* not be disposed before all DBs using this options
* instance have been closed. If user doesn't call options dispose explicitly,
* then this options instance will be GC'd automatically
*
* ColumnFamily handles are disposed when the RocksDB instance is disposed.
*
*
* @param path the path to the rocksdb.
* @param columnFamilyDescriptors list of column family descriptors
* @param columnFamilyHandles will be filled with ColumnFamilyHandle instances
* on open.
* @return a {@link RocksDB} instance on success, null if the specified
* {@link RocksDB} can not be opened.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
* @see DBOptions#setCreateIfMissing(boolean)
*/
public static RocksDB open(final String path,
final List columnFamilyDescriptors,
final List columnFamilyHandles)
throws RocksDBException {
try (DBOptions options = new DBOptions()) {
return open(options, path, columnFamilyDescriptors, columnFamilyHandles);
}
}
/**
* The factory constructor of RocksDB that opens a RocksDB instance given
* the path to the database using the specified options and db path.
*
*
* Options instance *should* not be disposed before all DBs using this options
* instance have been closed. If user doesn't call options dispose explicitly,
* then this options instance will be GC'd automatically.
*
* Options instance can be re-used to open multiple DBs if DB statistics is
* not used. If DB statistics are required, then its recommended to open DB
* with new Options instance as underlying native statistics instance does not
* use any locks to prevent concurrent updates.
*
* @param options {@link org.forstdb.Options} instance.
* @param path the path to the rocksdb.
* @return a {@link RocksDB} instance on success, null if the specified
* {@link RocksDB} can not be opened.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*
* @see Options#setCreateIfMissing(boolean)
*/
public static RocksDB open(final Options options, final String path)
throws RocksDBException {
// when non-default Options is used, keeping an Options reference
// in RocksDB can prevent Java to GC during the life-time of
// the currently-created RocksDB.
final RocksDB db = new RocksDB(open(options.nativeHandle_, path));
db.storeOptionsInstance(options);
db.storeDefaultColumnFamilyHandle(db.makeDefaultColumnFamilyHandle());
return db;
}
/**
* The factory constructor of RocksDB that opens a RocksDB instance given
* the path to the database using the specified options and db path and a list
* of column family names.
*
* If opened in read write mode every existing column family name must be
* passed within the list to this method.
*
* If opened in read-only mode only a subset of existing column families must
* be passed to this method.
*
* Options instance *should* not be disposed before all DBs using this options
* instance have been closed. If user doesn't call options dispose explicitly,
* then this options instance will be GC'd automatically.
*
* Options instance can be re-used to open multiple DBs if DB statistics is
* not used. If DB statistics are required, then its recommended to open DB
* with new Options instance as underlying native statistics instance does not
* use any locks to prevent concurrent updates.
*
* ColumnFamily handles are disposed when the RocksDB instance is disposed.
*
*
* @param options {@link org.forstdb.DBOptions} instance.
* @param path the path to the rocksdb.
* @param columnFamilyDescriptors list of column family descriptors
* @param columnFamilyHandles will be filled with ColumnFamilyHandle instances
* on open.
* @return a {@link RocksDB} instance on success, null if the specified
* {@link RocksDB} can not be opened.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*
* @see DBOptions#setCreateIfMissing(boolean)
*/
public static RocksDB open(final DBOptions options, final String path,
final List columnFamilyDescriptors,
final List columnFamilyHandles)
throws RocksDBException {
final byte[][] cfNames = new byte[columnFamilyDescriptors.size()][];
final long[] cfOptionHandles = new long[columnFamilyDescriptors.size()];
for (int i = 0; i < columnFamilyDescriptors.size(); i++) {
final ColumnFamilyDescriptor cfDescriptor = columnFamilyDescriptors
.get(i);
cfNames[i] = cfDescriptor.getName();
cfOptionHandles[i] = cfDescriptor.getOptions().nativeHandle_;
}
final long[] handles = open(options.nativeHandle_, path, cfNames,
cfOptionHandles);
final RocksDB db = new RocksDB(handles[0]);
db.storeOptionsInstance(options);
for (int i = 1; i < handles.length; i++) {
final ColumnFamilyHandle columnFamilyHandle = // NOPMD - CloseResource
new ColumnFamilyHandle(db, handles[i]);
columnFamilyHandles.add(columnFamilyHandle);
}
db.ownedColumnFamilyHandles.addAll(columnFamilyHandles);
db.storeDefaultColumnFamilyHandle(db.makeDefaultColumnFamilyHandle());
return db;
}
/**
* The factory constructor of RocksDB that opens a RocksDB instance in
* Read-Only mode given the path to the database using the default
* options.
*
* @param path the path to the RocksDB.
* @return a {@link RocksDB} instance on success, null if the specified
* {@link RocksDB} can not be opened.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public static RocksDB openReadOnly(final String path)
throws RocksDBException {
RocksDB.loadLibrary();
// This allows to use the rocksjni default Options instead of
// the c++ one.
try (Options options = new Options()) {
return openReadOnly(options, path);
}
}
/**
* The factory constructor of RocksDB that opens a RocksDB instance in
* Read-Only mode given the path to the database using the specified
* options and db path.
*
* Options instance *should* not be disposed before all DBs using this options
* instance have been closed. If user doesn't call options dispose explicitly,
* then this options instance will be GC'd automatically.
*
* @param options {@link Options} instance.
* @param path the path to the RocksDB.
* @return a {@link RocksDB} instance on success, null if the specified
* {@link RocksDB} can not be opened.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public static RocksDB openReadOnly(final Options options, final String path)
throws RocksDBException {
return openReadOnly(options, path, false);
}
/**
* The factory constructor of RocksDB that opens a RocksDB instance in
* Read-Only mode given the path to the database using the specified
* options and db path.
*
* Options instance *should* not be disposed before all DBs using this options
* instance have been closed. If user doesn't call options dispose explicitly,
* then this options instance will be GC'd automatically.
*
* @param options {@link Options} instance.
* @param path the path to the RocksDB.
* @param errorIfWalFileExists true to raise an error when opening the db
* if a Write Ahead Log file exists, false otherwise.
* @return a {@link RocksDB} instance on success, null if the specified
* {@link RocksDB} can not be opened.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public static RocksDB openReadOnly(final Options options, final String path,
final boolean errorIfWalFileExists) throws RocksDBException {
// when non-default Options is used, keeping an Options reference
// in RocksDB can prevent Java to GC during the life-time of
// the currently-created RocksDB.
final RocksDB db = new RocksDB(openROnly(options.nativeHandle_, path, errorIfWalFileExists));
db.storeOptionsInstance(options);
db.storeDefaultColumnFamilyHandle(db.makeDefaultColumnFamilyHandle());
return db;
}
/**
* The factory constructor of RocksDB that opens a RocksDB instance in
* Read-Only mode given the path to the database using the default
* options.
*
* @param path the path to the RocksDB.
* @param columnFamilyDescriptors list of column family descriptors
* @param columnFamilyHandles will be filled with ColumnFamilyHandle instances
* on open.
* @return a {@link RocksDB} instance on success, null if the specified
* {@link RocksDB} can not be opened.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public static RocksDB openReadOnly(final String path,
final List columnFamilyDescriptors,
final List columnFamilyHandles)
throws RocksDBException {
// This allows to use the rocksjni default Options instead of
// the c++ one.
try (DBOptions options = new DBOptions()) {
return openReadOnly(options, path, columnFamilyDescriptors, columnFamilyHandles, false);
}
}
/**
* The factory constructor of RocksDB that opens a RocksDB instance in
* Read-Only mode given the path to the database using the specified
* options and db path.
*
* This open method allows to open RocksDB using a subset of available
* column families
* Options instance *should* not be disposed before all DBs using this
* options instance have been closed. If user doesn't call options dispose
* explicitly,then this options instance will be GC'd automatically.
*
* @param options {@link DBOptions} instance.
* @param path the path to the RocksDB.
* @param columnFamilyDescriptors list of column family descriptors
* @param columnFamilyHandles will be filled with ColumnFamilyHandle instances
* on open.
* @return a {@link RocksDB} instance on success, null if the specified
* {@link RocksDB} can not be opened.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public static RocksDB openReadOnly(final DBOptions options, final String path,
final List columnFamilyDescriptors,
final List columnFamilyHandles) throws RocksDBException {
return openReadOnly(options, path, columnFamilyDescriptors, columnFamilyHandles, false);
}
/**
* The factory constructor of RocksDB that opens a RocksDB instance in
* Read-Only mode given the path to the database using the specified
* options and db path.
*
* This open method allows to open RocksDB using a subset of available
* column families
* Options instance *should* not be disposed before all DBs using this
* options instance have been closed. If user doesn't call options dispose
* explicitly,then this options instance will be GC'd automatically.
*
* @param options {@link DBOptions} instance.
* @param path the path to the RocksDB.
* @param columnFamilyDescriptors list of column family descriptors
* @param columnFamilyHandles will be filled with ColumnFamilyHandle instances
* on open.
* @param errorIfWalFileExists true to raise an error when opening the db
* if a Write Ahead Log file exists, false otherwise.
* @return a {@link RocksDB} instance on success, null if the specified
* {@link RocksDB} can not be opened.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public static RocksDB openReadOnly(final DBOptions options, final String path,
final List columnFamilyDescriptors,
final List columnFamilyHandles, final boolean errorIfWalFileExists)
throws RocksDBException {
// when non-default Options is used, keeping an Options reference
// in RocksDB can prevent Java to GC during the life-time of
// the currently-created RocksDB.
final byte[][] cfNames = new byte[columnFamilyDescriptors.size()][];
final long[] cfOptionHandles = new long[columnFamilyDescriptors.size()];
for (int i = 0; i < columnFamilyDescriptors.size(); i++) {
final ColumnFamilyDescriptor cfDescriptor = columnFamilyDescriptors
.get(i);
cfNames[i] = cfDescriptor.getName();
cfOptionHandles[i] = cfDescriptor.getOptions().nativeHandle_;
}
final long[] handles =
openROnly(options.nativeHandle_, path, cfNames, cfOptionHandles, errorIfWalFileExists);
final RocksDB db = new RocksDB(handles[0]);
db.storeOptionsInstance(options);
for (int i = 1; i < handles.length; i++) {
final ColumnFamilyHandle columnFamilyHandle = // NOPMD - CloseResource
new ColumnFamilyHandle(db, handles[i]);
columnFamilyHandles.add(columnFamilyHandle);
}
db.ownedColumnFamilyHandles.addAll(columnFamilyHandles);
db.storeDefaultColumnFamilyHandle(db.makeDefaultColumnFamilyHandle());
return db;
}
/**
* Open DB as secondary instance with only the default column family.
*
* The secondary instance can dynamically tail the MANIFEST of
* a primary that must have already been created. User can call
* {@link #tryCatchUpWithPrimary()} to make the secondary instance catch up
* with primary (WAL tailing is NOT supported now) whenever the user feels
* necessary. Column families created by the primary after the secondary
* instance starts are currently ignored by the secondary instance.
* Column families opened by secondary and dropped by the primary will be
* dropped by secondary as well. However the user of the secondary instance
* can still access the data of such dropped column family as long as they
* do not destroy the corresponding column family handle.
* WAL tailing is not supported at present, but will arrive soon.
*
* @param options the options to open the secondary instance.
* @param path the path to the primary RocksDB instance.
* @param secondaryPath points to a directory where the secondary instance
* stores its info log
*
* @return a {@link RocksDB} instance on success, null if the specified
* {@link RocksDB} can not be opened.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public static RocksDB openAsSecondary(final Options options, final String path,
final String secondaryPath) throws RocksDBException {
// when non-default Options is used, keeping an Options reference
// in RocksDB can prevent Java to GC during the life-time of
// the currently-created RocksDB.
final RocksDB db = new RocksDB(openAsSecondary(options.nativeHandle_, path, secondaryPath));
db.storeOptionsInstance(options);
db.storeDefaultColumnFamilyHandle(db.makeDefaultColumnFamilyHandle());
return db;
}
/**
* Open DB as secondary instance with column families.
* You can open a subset of column families in secondary mode.
*
* The secondary instance can dynamically tail the MANIFEST of
* a primary that must have already been created. User can call
* {@link #tryCatchUpWithPrimary()} to make the secondary instance catch up
* with primary (WAL tailing is NOT supported now) whenever the user feels
* necessary. Column families created by the primary after the secondary
* instance starts are currently ignored by the secondary instance.
* Column families opened by secondary and dropped by the primary will be
* dropped by secondary as well. However the user of the secondary instance
* can still access the data of such dropped column family as long as they
* do not destroy the corresponding column family handle.
* WAL tailing is not supported at present, but will arrive soon.
*
* @param options the options to open the secondary instance.
* @param path the path to the primary RocksDB instance.
* @param secondaryPath points to a directory where the secondary instance
* stores its info log.
* @param columnFamilyDescriptors list of column family descriptors
* @param columnFamilyHandles will be filled with ColumnFamilyHandle instances
* on open.
*
* @return a {@link RocksDB} instance on success, null if the specified
* {@link RocksDB} can not be opened.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public static RocksDB openAsSecondary(final DBOptions options, final String path,
final String secondaryPath, final List columnFamilyDescriptors,
final List columnFamilyHandles) throws RocksDBException {
// when non-default Options is used, keeping an Options reference
// in RocksDB can prevent Java to GC during the life-time of
// the currently-created RocksDB.
final byte[][] cfNames = new byte[columnFamilyDescriptors.size()][];
final long[] cfOptionHandles = new long[columnFamilyDescriptors.size()];
for (int i = 0; i < columnFamilyDescriptors.size(); i++) {
final ColumnFamilyDescriptor cfDescriptor = columnFamilyDescriptors.get(i);
cfNames[i] = cfDescriptor.getName();
cfOptionHandles[i] = cfDescriptor.getOptions().nativeHandle_;
}
final long[] handles =
openAsSecondary(options.nativeHandle_, path, secondaryPath, cfNames, cfOptionHandles);
final RocksDB db = new RocksDB(handles[0]);
db.storeOptionsInstance(options);
for (int i = 1; i < handles.length; i++) {
final ColumnFamilyHandle columnFamilyHandle = // NOPMD - CloseResource
new ColumnFamilyHandle(db, handles[i]);
columnFamilyHandles.add(columnFamilyHandle);
}
db.ownedColumnFamilyHandles.addAll(columnFamilyHandles);
db.storeDefaultColumnFamilyHandle(db.makeDefaultColumnFamilyHandle());
return db;
}
/**
* This is similar to {@link #close()} except that it
* throws an exception if any error occurs.
*
* This will not fsync the WAL files.
* If syncing is required, the caller must first call {@link #syncWal()}
* or {@link #write(WriteOptions, WriteBatch)} using an empty write batch
* with {@link WriteOptions#setSync(boolean)} set to true.
*
* See also {@link #close()}.
*
* @throws RocksDBException if an error occurs whilst closing.
*/
public void closeE() throws RocksDBException {
for (final ColumnFamilyHandle columnFamilyHandle : // NOPMD - CloseResource
ownedColumnFamilyHandles) {
columnFamilyHandle.close();
}
ownedColumnFamilyHandles.clear();
if (owningHandle_.compareAndSet(true, false)) {
try {
closeDatabase(nativeHandle_);
} finally {
disposeInternal();
}
}
}
/**
* This is similar to {@link #closeE()} except that it
* silently ignores any errors.
*
* This will not fsync the WAL files.
* If syncing is required, the caller must first call {@link #syncWal()}
* or {@link #write(WriteOptions, WriteBatch)} using an empty write batch
* with {@link WriteOptions#setSync(boolean)} set to true.
*
* See also {@link #close()}.
*/
@SuppressWarnings("PMD.EmptyCatchBlock")
@Override
public void close() {
for (final ColumnFamilyHandle columnFamilyHandle : // NOPMD - CloseResource
ownedColumnFamilyHandles) {
columnFamilyHandle.close();
}
ownedColumnFamilyHandles.clear();
if (owningHandle_.compareAndSet(true, false)) {
try {
closeDatabase(nativeHandle_);
} catch (final RocksDBException e) {
// silently ignore the error report
} finally {
disposeInternal();
}
}
}
/**
* Static method to determine all available column families for a
* rocksdb database identified by path
*
* @param options Options for opening the database
* @param path Absolute path to rocksdb database
* @return List<byte[]> List containing the column family names
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public static List listColumnFamilies(final Options options,
final String path) throws RocksDBException {
return Arrays.asList(RocksDB.listColumnFamilies(options.nativeHandle_,
path));
}
/**
* Creates a new column family with the name columnFamilyName and
* allocates a ColumnFamilyHandle within an internal structure.
* The ColumnFamilyHandle is automatically disposed with DB disposal.
*
* @param columnFamilyDescriptor column family to be created.
* @return {@link org.forstdb.ColumnFamilyHandle} instance.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public ColumnFamilyHandle createColumnFamily(
final ColumnFamilyDescriptor columnFamilyDescriptor)
throws RocksDBException {
final ColumnFamilyHandle columnFamilyHandle = new ColumnFamilyHandle(this,
createColumnFamily(nativeHandle_, columnFamilyDescriptor.getName(),
columnFamilyDescriptor.getName().length,
columnFamilyDescriptor.getOptions().nativeHandle_));
ownedColumnFamilyHandles.add(columnFamilyHandle);
return columnFamilyHandle;
}
/**
* Bulk create column families with the same column family options.
*
* @param columnFamilyOptions the options for the column families.
* @param columnFamilyNames the names of the column families.
*
* @return the handles to the newly created column families.
*
* @throws RocksDBException if an error occurs whilst creating
* the column families
*/
public List createColumnFamilies(
final ColumnFamilyOptions columnFamilyOptions,
final List columnFamilyNames) throws RocksDBException {
final byte[][] cfNames = columnFamilyNames.toArray(
new byte[0][]);
final long[] cfHandles = createColumnFamilies(nativeHandle_,
columnFamilyOptions.nativeHandle_, cfNames);
final List columnFamilyHandles =
new ArrayList<>(cfHandles.length);
for (final long cfHandle : cfHandles) {
final ColumnFamilyHandle columnFamilyHandle = new ColumnFamilyHandle(this, cfHandle); // NOPMD
columnFamilyHandles.add(columnFamilyHandle);
}
ownedColumnFamilyHandles.addAll(columnFamilyHandles);
return columnFamilyHandles;
}
/**
* Bulk create column families with the same column family options.
*
* @param columnFamilyDescriptors the descriptions of the column families.
*
* @return the handles to the newly created column families.
*
* @throws RocksDBException if an error occurs whilst creating
* the column families
*/
public List createColumnFamilies(
final List columnFamilyDescriptors)
throws RocksDBException {
final long[] cfOptsHandles = new long[columnFamilyDescriptors.size()];
final byte[][] cfNames = new byte[columnFamilyDescriptors.size()][];
for (int i = 0; i < columnFamilyDescriptors.size(); i++) {
final ColumnFamilyDescriptor columnFamilyDescriptor
= columnFamilyDescriptors.get(i);
cfOptsHandles[i] = columnFamilyDescriptor.getOptions().nativeHandle_;
cfNames[i] = columnFamilyDescriptor.getName();
}
final long[] cfHandles = createColumnFamilies(nativeHandle_,
cfOptsHandles, cfNames);
final List columnFamilyHandles =
new ArrayList<>(cfHandles.length);
for (final long cfHandle : cfHandles) {
final ColumnFamilyHandle columnFamilyHandle = new ColumnFamilyHandle(this, cfHandle); // NOPMD
columnFamilyHandles.add(columnFamilyHandle);
}
ownedColumnFamilyHandles.addAll(columnFamilyHandles);
return columnFamilyHandles;
}
/**
* Creates a new column family with the name columnFamilyName and
* import external SST files specified in `metadata` allocates a
* ColumnFamilyHandle within an internal structure.
* The ColumnFamilyHandle is automatically disposed with DB disposal.
*
* @param columnFamilyDescriptor column family to be created.
* @return {@link org.forstdb.ColumnFamilyHandle} instance.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public ColumnFamilyHandle createColumnFamilyWithImport(
final ColumnFamilyDescriptor columnFamilyDescriptor,
final ImportColumnFamilyOptions importColumnFamilyOptions,
final ExportImportFilesMetaData metadata) throws RocksDBException {
List metadatas = new ArrayList<>();
metadatas.add(metadata);
return createColumnFamilyWithImport(
columnFamilyDescriptor, importColumnFamilyOptions, metadatas);
}
public ColumnFamilyHandle createColumnFamilyWithImport(
final ColumnFamilyDescriptor columnFamilyDescriptor,
final ImportColumnFamilyOptions importColumnFamilyOptions,
final List metadatas) throws RocksDBException {
final int metadataNum = metadatas.size();
final long[] metadataHandleList = new long[metadataNum];
for (int i = 0; i < metadataNum; i++) {
metadataHandleList[i] = metadatas.get(i).getNativeHandle();
}
final ColumnFamilyHandle columnFamilyHandle = new ColumnFamilyHandle(this,
createColumnFamilyWithImport(nativeHandle_, columnFamilyDescriptor.getName(),
columnFamilyDescriptor.getName().length,
columnFamilyDescriptor.getOptions().nativeHandle_,
importColumnFamilyOptions.nativeHandle_, metadataHandleList));
ownedColumnFamilyHandles.add(columnFamilyHandle);
return columnFamilyHandle;
}
/**
* Drops the column family specified by {@code columnFamilyHandle}. This call
* only records a drop record in the manifest and prevents the column
* family from flushing and compacting.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void dropColumnFamily(final ColumnFamilyHandle columnFamilyHandle)
throws RocksDBException {
dropColumnFamily(nativeHandle_, columnFamilyHandle.nativeHandle_);
}
// Bulk drop column families. This call only records drop records in the
// manifest and prevents the column families from flushing and compacting.
// In case of error, the request may succeed partially. User may call
// ListColumnFamilies to check the result.
public void dropColumnFamilies(
final List columnFamilies) throws RocksDBException {
final long[] cfHandles = new long[columnFamilies.size()];
for (int i = 0; i < columnFamilies.size(); i++) {
cfHandles[i] = columnFamilies.get(i).nativeHandle_;
}
dropColumnFamilies(nativeHandle_, cfHandles);
}
/**
* Deletes native column family handle of given {@link ColumnFamilyHandle} Java object
* and removes reference from {@link RocksDB#ownedColumnFamilyHandles}.
*
* @param columnFamilyHandle column family handle object.
*/
public void destroyColumnFamilyHandle(final ColumnFamilyHandle columnFamilyHandle) {
for (int i = 0; i < ownedColumnFamilyHandles.size(); ++i) {
final ColumnFamilyHandle ownedHandle = ownedColumnFamilyHandles.get(i); // NOPMD
if (ownedHandle.equals(columnFamilyHandle)) {
columnFamilyHandle.close();
ownedColumnFamilyHandles.remove(i);
return;
}
}
}
/**
* Set the database entry for "key" to "value".
*
* @param key the specified key to be inserted.
* @param value the value associated with the specified key.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void put(final byte[] key, final byte[] value)
throws RocksDBException {
put(nativeHandle_, key, 0, key.length, value, 0, value.length);
}
/**
* Set the database entry for "key" to "value".
*
* @param key The specified key to be inserted
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be non-negative
* and no larger than ("key".length - offset)
* @param value the value associated with the specified key
* @param vOffset the offset of the "value" array to be used, must be
* non-negative and no longer than "key".length
* @param vLen the length of the "value" array to be used, must be
* non-negative and no larger than ("value".length - offset)
*
* @throws RocksDBException thrown if errors happens in underlying native
* library.
* @throws IndexOutOfBoundsException if an offset or length is out of bounds
*/
public void put(final byte[] key, final int offset, final int len,
final byte[] value, final int vOffset, final int vLen)
throws RocksDBException {
CheckBounds(offset, len, key.length);
CheckBounds(vOffset, vLen, value.length);
put(nativeHandle_, key, offset, len, value, vOffset, vLen);
}
/**
* Set the database entry for "key" to "value" in the specified
* column family.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance
* @param key the specified key to be inserted.
* @param value the value associated with the specified key.
*
* throws IllegalArgumentException if column family is not present
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void put(final ColumnFamilyHandle columnFamilyHandle,
final byte[] key, final byte[] value) throws RocksDBException {
put(nativeHandle_, key, 0, key.length, value, 0, value.length,
columnFamilyHandle.nativeHandle_);
}
/**
* Set the database entry for "key" to "value" in the specified
* column family.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance
* @param key The specified key to be inserted
* @param offset the offset of the "key" array to be used, must
* be non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be non-negative
* and no larger than ("key".length - offset)
* @param value the value associated with the specified key
* @param vOffset the offset of the "value" array to be used, must be
* non-negative and no longer than "key".length
* @param vLen the length of the "value" array to be used, must be
* non-negative and no larger than ("value".length - offset)
*
* @throws RocksDBException thrown if errors happens in underlying native
* library.
* @throws IndexOutOfBoundsException if an offset or length is out of bounds
*/
public void put(final ColumnFamilyHandle columnFamilyHandle,
final byte[] key, final int offset, final int len,
final byte[] value, final int vOffset, final int vLen)
throws RocksDBException {
CheckBounds(offset, len, key.length);
CheckBounds(vOffset, vLen, value.length);
put(nativeHandle_, key, offset, len, value, vOffset, vLen,
columnFamilyHandle.nativeHandle_);
}
/**
* Set the database entry for "key" to "value".
*
* @param writeOpts {@link org.forstdb.WriteOptions} instance.
* @param key the specified key to be inserted.
* @param value the value associated with the specified key.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void put(final WriteOptions writeOpts, final byte[] key,
final byte[] value) throws RocksDBException {
put(nativeHandle_, writeOpts.nativeHandle_,
key, 0, key.length, value, 0, value.length);
}
/**
* Set the database entry for "key" to "value".
*
* @param writeOpts {@link org.forstdb.WriteOptions} instance.
* @param key The specified key to be inserted
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be non-negative
* and no larger than ("key".length - offset)
* @param value the value associated with the specified key
* @param vOffset the offset of the "value" array to be used, must be
* non-negative and no longer than "key".length
* @param vLen the length of the "value" array to be used, must be
* non-negative and no larger than ("value".length - offset)
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
* @throws IndexOutOfBoundsException if an offset or length is out of bounds
*/
public void put(final WriteOptions writeOpts,
final byte[] key, final int offset, final int len,
final byte[] value, final int vOffset, final int vLen)
throws RocksDBException {
CheckBounds(offset, len, key.length);
CheckBounds(vOffset, vLen, value.length);
put(nativeHandle_, writeOpts.nativeHandle_,
key, offset, len, value, vOffset, vLen);
}
/**
* Set the database entry for "key" to "value" for the specified
* column family.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance
* @param writeOpts {@link org.forstdb.WriteOptions} instance.
* @param key the specified key to be inserted.
* @param value the value associated with the specified key.
*
* throws IllegalArgumentException if column family is not present
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
* @see IllegalArgumentException
*/
public void put(final ColumnFamilyHandle columnFamilyHandle,
final WriteOptions writeOpts, final byte[] key,
final byte[] value) throws RocksDBException {
put(nativeHandle_, writeOpts.nativeHandle_, key, 0, key.length, value,
0, value.length, columnFamilyHandle.nativeHandle_);
}
/**
* Set the database entry for "key" to "value" for the specified
* column family.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance
* @param writeOpts {@link org.forstdb.WriteOptions} instance.
* @param key the specified key to be inserted. Position and limit is used.
* Supports direct buffer only.
* @param value the value associated with the specified key. Position and limit is used.
* Supports direct buffer only.
*
* throws IllegalArgumentException if column family is not present
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
* @see IllegalArgumentException
*/
public void put(final ColumnFamilyHandle columnFamilyHandle, final WriteOptions writeOpts,
final ByteBuffer key, final ByteBuffer value) throws RocksDBException {
if (key.isDirect() && value.isDirect()) {
putDirect(nativeHandle_, writeOpts.nativeHandle_, key, key.position(), key.remaining(), value,
value.position(), value.remaining(), columnFamilyHandle.nativeHandle_);
} else if (!key.isDirect() && !value.isDirect()) {
assert key.hasArray();
assert value.hasArray();
put(nativeHandle_, writeOpts.nativeHandle_, key.array(), key.arrayOffset() + key.position(),
key.remaining(), value.array(), value.arrayOffset() + value.position(), value.remaining(),
columnFamilyHandle.nativeHandle_);
} else {
throw new RocksDBException(BB_ALL_DIRECT_OR_INDIRECT);
}
key.position(key.limit());
value.position(value.limit());
}
/**
* Set the database entry for "key" to "value".
*
* @param writeOpts {@link org.forstdb.WriteOptions} instance.
* @param key the specified key to be inserted. Position and limit is used.
* Supports direct buffer only.
* @param value the value associated with the specified key. Position and limit is used.
* Supports direct buffer only.
*
* throws IllegalArgumentException if column family is not present
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
* @see IllegalArgumentException
*/
public void put(final WriteOptions writeOpts, final ByteBuffer key, final ByteBuffer value)
throws RocksDBException {
if (key.isDirect() && value.isDirect()) {
putDirect(nativeHandle_, writeOpts.nativeHandle_, key, key.position(), key.remaining(), value,
value.position(), value.remaining(), 0);
} else if (!key.isDirect() && !value.isDirect()) {
assert key.hasArray();
assert value.hasArray();
put(nativeHandle_, writeOpts.nativeHandle_, key.array(), key.arrayOffset() + key.position(),
key.remaining(), value.array(), value.arrayOffset() + value.position(),
value.remaining());
} else {
throw new RocksDBException(BB_ALL_DIRECT_OR_INDIRECT);
}
key.position(key.limit());
value.position(value.limit());
}
/**
* Set the database entry for "key" to "value" for the specified
* column family.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance
* @param writeOpts {@link org.forstdb.WriteOptions} instance.
* @param key The specified key to be inserted
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be non-negative
* and no larger than ("key".length - offset)
* @param value the value associated with the specified key
* @param vOffset the offset of the "value" array to be used, must be
* non-negative and no longer than "key".length
* @param vLen the length of the "value" array to be used, must be
* non-negative and no larger than ("value".length - offset)
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
* @throws IndexOutOfBoundsException if an offset or length is out of bounds
*/
public void 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)
throws RocksDBException {
CheckBounds(offset, len, key.length);
CheckBounds(vOffset, vLen, value.length);
put(nativeHandle_, writeOpts.nativeHandle_, key, offset, len, value,
vOffset, vLen, columnFamilyHandle.nativeHandle_);
}
/**
* Delete the database entry (if any) for "key". Returns OK on
* success, and a non-OK status on error. It is not an error if "key"
* did not exist in the database.
*
* @param key Key to delete within database
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void delete(final byte[] key) throws RocksDBException {
delete(nativeHandle_, key, 0, key.length);
}
/**
* Delete the database entry (if any) for "key". Returns OK on
* success, and a non-OK status on error. It is not an error if "key"
* did not exist in the database.
*
* @param key Key to delete within database
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be
* non-negative and no larger than ("key".length - offset)
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void delete(final byte[] key, final int offset, final int len)
throws RocksDBException {
delete(nativeHandle_, key, offset, len);
}
/**
* Delete the database entry (if any) for "key". Returns OK on
* success, and a non-OK status on error. It is not an error if "key"
* did not exist in the database.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance
* @param key Key to delete within database
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void delete(final ColumnFamilyHandle columnFamilyHandle,
final byte[] key) throws RocksDBException {
delete(nativeHandle_, key, 0, key.length, columnFamilyHandle.nativeHandle_);
}
/**
* Delete the database entry (if any) for "key". Returns OK on
* success, and a non-OK status on error. It is not an error if "key"
* did not exist in the database.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance
* @param key Key to delete within database
* @param offset the offset of the "key" array to be used,
* must be non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be non-negative
* and no larger than ("value".length - offset)
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void delete(final ColumnFamilyHandle columnFamilyHandle,
final byte[] key, final int offset, final int len)
throws RocksDBException {
delete(nativeHandle_, key, offset, len, columnFamilyHandle.nativeHandle_);
}
/**
* Delete the database entry (if any) for "key". Returns OK on
* success, and a non-OK status on error. It is not an error if "key"
* did not exist in the database.
*
* @param writeOpt WriteOptions to be used with delete operation
* @param key Key to delete within database
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void delete(final WriteOptions writeOpt, final byte[] key)
throws RocksDBException {
delete(nativeHandle_, writeOpt.nativeHandle_, key, 0, key.length);
}
/**
* Delete the database entry (if any) for "key". Returns OK on
* success, and a non-OK status on error. It is not an error if "key"
* did not exist in the database.
*
* @param writeOpt WriteOptions to be used with delete operation
* @param key Key to delete within database
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be
* non-negative and no larger than ("key".length - offset)
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void delete(final WriteOptions writeOpt, final byte[] key,
final int offset, final int len) throws RocksDBException {
delete(nativeHandle_, writeOpt.nativeHandle_, key, offset, len);
}
/**
* Delete the database entry (if any) for "key". Returns OK on
* success, and a non-OK status on error. It is not an error if "key"
* did not exist in the database.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance
* @param writeOpt WriteOptions to be used with delete operation
* @param key Key to delete within database
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void delete(final ColumnFamilyHandle columnFamilyHandle,
final WriteOptions writeOpt, final byte[] key)
throws RocksDBException {
delete(nativeHandle_, writeOpt.nativeHandle_, key, 0, key.length,
columnFamilyHandle.nativeHandle_);
}
/**
* Delete the database entry (if any) for "key". Returns OK on
* success, and a non-OK status on error. It is not an error if "key"
* did not exist in the database.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance
* @param writeOpt WriteOptions to be used with delete operation
* @param key Key to delete within database
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be
* non-negative and no larger than ("key".length - offset)
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void delete(final ColumnFamilyHandle columnFamilyHandle,
final WriteOptions writeOpt, final byte[] key, final int offset,
final int len) throws RocksDBException {
delete(nativeHandle_, writeOpt.nativeHandle_, key, offset, len,
columnFamilyHandle.nativeHandle_);
}
/**
* Get the value associated with the specified key within column family.
*
* @param opt {@link org.forstdb.ReadOptions} instance.
* @param key the key to retrieve the value. It is using position and limit.
* Supports direct buffer only.
* @param value the out-value to receive the retrieved value.
* It is using position and limit. Limit is set according to value size.
* Supports direct buffer only.
* @return The size of the actual value that matches the specified
* {@code key} in byte. If the return value is greater than the
* length of {@code value}, then it indicates that the size of the
* input buffer {@code value} is insufficient and partial result will
* be returned. RocksDB.NOT_FOUND will be returned if the value not
* found.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public int get(final ReadOptions opt, final ByteBuffer key, final ByteBuffer value)
throws RocksDBException {
final int result;
if (key.isDirect() && value.isDirect()) {
result = getDirect(nativeHandle_, opt.nativeHandle_, key, key.position(), key.remaining(),
value, value.position(), value.remaining(), 0);
} else if (!key.isDirect() && !value.isDirect()) {
result =
get(nativeHandle_, opt.nativeHandle_, key.array(), key.arrayOffset() + key.position(),
key.remaining(), value.array(), value.arrayOffset() + value.position(),
value.remaining(), defaultColumnFamilyHandle_.nativeHandle_);
} else {
throw new RocksDBException(BB_ALL_DIRECT_OR_INDIRECT);
}
if (result != NOT_FOUND) {
value.limit(Math.min(value.limit(), value.position() + result));
}
key.position(key.limit());
return result;
}
/**
* Get the value associated with the specified key within column family.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance
* @param opt {@link org.forstdb.ReadOptions} instance.
* @param key the key to retrieve the value. It is using position and limit.
* Supports direct buffer only.
* @param value the out-value to receive the retrieved value.
* It is using position and limit. Limit is set according to value size.
* Supports direct buffer only.
* @return The size of the actual value that matches the specified
* {@code key} in byte. If the return value is greater than the
* length of {@code value}, then it indicates that the size of the
* input buffer {@code value} is insufficient and partial result will
* be returned. RocksDB.NOT_FOUND will be returned if the value not
* found.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public int get(final ColumnFamilyHandle columnFamilyHandle, final ReadOptions opt,
final ByteBuffer key, final ByteBuffer value) throws RocksDBException {
assert key.isDirect() && value.isDirect();
final int result =
getDirect(nativeHandle_, opt.nativeHandle_, key, key.position(), key.remaining(), value,
value.position(), value.remaining(), columnFamilyHandle.nativeHandle_);
if (result != NOT_FOUND) {
value.limit(Math.min(value.limit(), value.position() + result));
}
key.position(key.limit());
return result;
}
/**
* Remove the database entry for {@code key}. Requires that the key exists
* and was not overwritten. It is not an error if the key did not exist
* in the database.
*
* If a key is overwritten (by calling {@link #put(byte[], byte[])} multiple
* times), then the result of calling SingleDelete() on this key is undefined.
* SingleDelete() only behaves correctly if there has been only one Put()
* for this key since the previous call to SingleDelete() for this key.
*
* This feature is currently an experimental performance optimization
* for a very specific workload. It is up to the caller to ensure that
* SingleDelete is only used for a key that is not deleted using Delete() or
* written using Merge(). Mixing SingleDelete operations with Deletes and
* Merges can result in undefined behavior.
*
* @param key Key to delete within database
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
@Experimental(PERFORMANCE_OPTIMIZATION_FOR_A_VERY_SPECIFIC_WORKLOAD)
public void singleDelete(final byte[] key) throws RocksDBException {
singleDelete(nativeHandle_, key, key.length);
}
/**
* Remove the database entry for {@code key}. Requires that the key exists
* and was not overwritten. It is not an error if the key did not exist
* in the database.
*
* If a key is overwritten (by calling {@link #put(byte[], byte[])} multiple
* times), then the result of calling SingleDelete() on this key is undefined.
* SingleDelete() only behaves correctly if there has been only one Put()
* for this key since the previous call to SingleDelete() for this key.
*
* This feature is currently an experimental performance optimization
* for a very specific workload. It is up to the caller to ensure that
* SingleDelete is only used for a key that is not deleted using Delete() or
* written using Merge(). Mixing SingleDelete operations with Deletes and
* Merges can result in undefined behavior.
*
* @param columnFamilyHandle The column family to delete the key from
* @param key Key to delete within database
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
@Experimental(PERFORMANCE_OPTIMIZATION_FOR_A_VERY_SPECIFIC_WORKLOAD)
public void singleDelete(final ColumnFamilyHandle columnFamilyHandle, final byte[] key)
throws RocksDBException {
singleDelete(nativeHandle_, key, key.length,
columnFamilyHandle.nativeHandle_);
}
/**
* Remove the database entry for {@code key}. Requires that the key exists
* and was not overwritten. It is not an error if the key did not exist
* in the database.
*
* If a key is overwritten (by calling {@link #put(byte[], byte[])} multiple
* times), then the result of calling SingleDelete() on this key is undefined.
* SingleDelete() only behaves correctly if there has been only one Put()
* for this key since the previous call to SingleDelete() for this key.
*
* This feature is currently an experimental performance optimization
* for a very specific workload. It is up to the caller to ensure that
* SingleDelete is only used for a key that is not deleted using Delete() or
* written using Merge(). Mixing SingleDelete operations with Deletes and
* Merges can result in undefined behavior.
*
* Note: consider setting {@link WriteOptions#setSync(boolean)} true.
*
* @param writeOpt Write options for the delete
* @param key Key to delete within database
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
@Experimental(PERFORMANCE_OPTIMIZATION_FOR_A_VERY_SPECIFIC_WORKLOAD)
public void singleDelete(final WriteOptions writeOpt, final byte[] key) throws RocksDBException {
singleDelete(nativeHandle_, writeOpt.nativeHandle_, key, key.length);
}
/**
* Remove the database entry for {@code key}. Requires that the key exists
* and was not overwritten. It is not an error if the key did not exist
* in the database.
*
* If a key is overwritten (by calling {@link #put(byte[], byte[])} multiple
* times), then the result of calling SingleDelete() on this key is undefined.
* SingleDelete() only behaves correctly if there has been only one Put()
* for this key since the previous call to SingleDelete() for this key.
*
* This feature is currently an experimental performance optimization
* for a very specific workload. It is up to the caller to ensure that
* SingleDelete is only used for a key that is not deleted using Delete() or
* written using Merge(). Mixing SingleDelete operations with Deletes and
* Merges can result in undefined behavior.
*
* Note: consider setting {@link WriteOptions#setSync(boolean)} true.
*
* @param columnFamilyHandle The column family to delete the key from
* @param writeOpt Write options for the delete
* @param key Key to delete within database
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
@Experimental(PERFORMANCE_OPTIMIZATION_FOR_A_VERY_SPECIFIC_WORKLOAD)
public void singleDelete(final ColumnFamilyHandle columnFamilyHandle, final WriteOptions writeOpt,
final byte[] key) throws RocksDBException {
singleDelete(nativeHandle_, writeOpt.nativeHandle_, key, key.length,
columnFamilyHandle.nativeHandle_);
}
/**
* Removes the database entries in the range ["beginKey", "endKey"), i.e.,
* including "beginKey" and excluding "endKey". a non-OK status on error. It
* is not an error if no keys exist in the range ["beginKey", "endKey").
*
* Delete the database entry (if any) for "key". Returns OK on success, and a
* non-OK status on error. It is not an error if "key" did not exist in the
* database.
*
* @param beginKey First key to delete within database (inclusive)
* @param endKey Last key to delete within database (exclusive)
*
* @throws RocksDBException thrown if error happens in underlying native
* library.
*/
public void deleteRange(final byte[] beginKey, final byte[] endKey)
throws RocksDBException {
deleteRange(nativeHandle_, beginKey, 0, beginKey.length, endKey, 0,
endKey.length);
}
/**
* Removes the database entries in the range ["beginKey", "endKey"), i.e.,
* including "beginKey" and excluding "endKey". a non-OK status on error. It
* is not an error if no keys exist in the range ["beginKey", "endKey").
*
* Delete the database entry (if any) for "key". Returns OK on success, and a
* non-OK status on error. It is not an error if "key" did not exist in the
* database.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle} instance
* @param beginKey First key to delete within database (inclusive)
* @param endKey Last key to delete within database (exclusive)
*
* @throws RocksDBException thrown if error happens in underlying native
* library.
*/
public void deleteRange(final ColumnFamilyHandle columnFamilyHandle,
final byte[] beginKey, final byte[] endKey) throws RocksDBException {
deleteRange(nativeHandle_, beginKey, 0, beginKey.length, endKey, 0,
endKey.length, columnFamilyHandle.nativeHandle_);
}
/**
* Removes the database entries in the range ["beginKey", "endKey"), i.e.,
* including "beginKey" and excluding "endKey". a non-OK status on error. It
* is not an error if no keys exist in the range ["beginKey", "endKey").
*
* Delete the database entry (if any) for "key". Returns OK on success, and a
* non-OK status on error. It is not an error if "key" did not exist in the
* database.
*
* @param writeOpt WriteOptions to be used with delete operation
* @param beginKey First key to delete within database (inclusive)
* @param endKey Last key to delete within database (exclusive)
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void deleteRange(final WriteOptions writeOpt, final byte[] beginKey,
final byte[] endKey) throws RocksDBException {
deleteRange(nativeHandle_, writeOpt.nativeHandle_, beginKey, 0,
beginKey.length, endKey, 0, endKey.length);
}
/**
* Removes the database entries in the range ["beginKey", "endKey"), i.e.,
* including "beginKey" and excluding "endKey". a non-OK status on error. It
* is not an error if no keys exist in the range ["beginKey", "endKey").
*
* Delete the database entry (if any) for "key". Returns OK on success, and a
* non-OK status on error. It is not an error if "key" did not exist in the
* database.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle} instance
* @param writeOpt WriteOptions to be used with delete operation
* @param beginKey First key to delete within database (included)
* @param endKey Last key to delete within database (excluded)
*
* @throws RocksDBException thrown if error happens in underlying native
* library.
*/
public void deleteRange(final ColumnFamilyHandle columnFamilyHandle,
final WriteOptions writeOpt, final byte[] beginKey, final byte[] endKey)
throws RocksDBException {
deleteRange(nativeHandle_, writeOpt.nativeHandle_, beginKey, 0,
beginKey.length, endKey, 0, endKey.length,
columnFamilyHandle.nativeHandle_);
}
/**
* Add merge operand for key/value pair.
*
* @param key the specified key to be merged.
* @param value the value to be merged with the current value for the
* specified key.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void merge(final byte[] key, final byte[] value)
throws RocksDBException {
merge(nativeHandle_, key, 0, key.length, value, 0, value.length);
}
/**
* Add merge operand for key/value pair.
*
* @param key the specified key to be merged.
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be non-negative
* and no larger than ("key".length - offset)
* @param value the value to be merged with the current value for the
* specified key.
* @param vOffset the offset of the "value" array to be used, must be
* non-negative and no longer than "key".length
* @param vLen the length of the "value" array to be used, must be
* non-negative and must be non-negative and no larger than
* ("value".length - offset)
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
* @throws IndexOutOfBoundsException if an offset or length is out of bounds
*/
public void merge(final byte[] key, final int offset, final int len, final byte[] value,
final int vOffset, final int vLen) throws RocksDBException {
CheckBounds(offset, len, key.length);
CheckBounds(vOffset, vLen, value.length);
merge(nativeHandle_, key, offset, len, value, vOffset, vLen);
}
/**
* Add merge operand for key/value pair in a ColumnFamily.
*
* @param columnFamilyHandle {@link ColumnFamilyHandle} instance
* @param key the specified key to be merged.
* @param value the value to be merged with the current value for
* the specified key.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void merge(final ColumnFamilyHandle columnFamilyHandle,
final byte[] key, final byte[] value) throws RocksDBException {
merge(nativeHandle_, key, 0, key.length, value, 0, value.length,
columnFamilyHandle.nativeHandle_);
}
/**
* Add merge operand for key/value pair in a ColumnFamily.
*
* @param columnFamilyHandle {@link ColumnFamilyHandle} instance
* @param key the specified key to be merged.
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be non-negative
* and no larger than ("key".length - offset)
* @param value the value to be merged with the current value for
* the specified key.
* @param vOffset the offset of the "value" array to be used, must be
* non-negative and no longer than "key".length
* @param vLen the length of the "value" array to be used, must be
* must be non-negative and no larger than ("value".length - offset)
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
* @throws IndexOutOfBoundsException if an offset or length is out of bounds
*/
public void merge(final ColumnFamilyHandle columnFamilyHandle,
final byte[] key, final int offset, final int len, final byte[] value,
final int vOffset, final int vLen) throws RocksDBException {
CheckBounds(offset, len, key.length);
CheckBounds(vOffset, vLen, value.length);
merge(nativeHandle_, key, offset, len, value, vOffset, vLen,
columnFamilyHandle.nativeHandle_);
}
/**
* Add merge operand for key/value pair.
*
* @param writeOpts {@link WriteOptions} for this write.
* @param key the specified key to be merged.
* @param value the value to be merged with the current value for
* the specified key.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void merge(final WriteOptions writeOpts, final byte[] key,
final byte[] value) throws RocksDBException {
merge(nativeHandle_, writeOpts.nativeHandle_,
key, 0, key.length, value, 0, value.length);
}
/**
* Add merge operand for key/value pair.
*
* @param writeOpts {@link WriteOptions} for this write.
* @param key the specified key to be merged.
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be non-negative
* and no larger than ("value".length - offset)
* @param value the value to be merged with the current value for
* the specified key.
* @param vOffset the offset of the "value" array to be used, must be
* non-negative and no longer than "key".length
* @param vLen the length of the "value" array to be used, must be
* non-negative and no larger than ("value".length - offset)
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
* @throws IndexOutOfBoundsException if an offset or length is out of bounds
*/
public void merge(final WriteOptions writeOpts,
final byte[] key, final int offset, final int len,
final byte[] value, final int vOffset, final int vLen)
throws RocksDBException {
CheckBounds(offset, len, key.length);
CheckBounds(vOffset, vLen, value.length);
merge(nativeHandle_, writeOpts.nativeHandle_,
key, offset, len, value, vOffset, vLen);
}
public void merge(final WriteOptions writeOpts, final ByteBuffer key, final ByteBuffer value)
throws RocksDBException {
if (key.isDirect() && value.isDirect()) {
mergeDirect(nativeHandle_, writeOpts.nativeHandle_, key, key.position(), key.remaining(),
value, value.position(), value.remaining(), 0);
} else if (!key.isDirect() && !value.isDirect()) {
assert key.hasArray();
assert value.hasArray();
merge(nativeHandle_, writeOpts.nativeHandle_, key.array(), key.arrayOffset() + key.position(),
key.remaining(), value.array(), value.arrayOffset() + value.position(),
value.remaining());
} else {
throw new RocksDBException(BB_ALL_DIRECT_OR_INDIRECT);
}
key.position(key.limit());
value.position(value.limit());
}
public void merge(final ColumnFamilyHandle columnFamilyHandle, final WriteOptions writeOpts,
final ByteBuffer key, final ByteBuffer value) throws RocksDBException {
if (key.isDirect() && value.isDirect()) {
mergeDirect(nativeHandle_, writeOpts.nativeHandle_, key, key.position(), key.remaining(),
value, value.position(), value.remaining(), columnFamilyHandle.nativeHandle_);
} else if (!key.isDirect() && !value.isDirect()) {
assert key.hasArray();
assert value.hasArray();
merge(nativeHandle_, writeOpts.nativeHandle_, key.array(), key.arrayOffset() + key.position(),
key.remaining(), value.array(), value.arrayOffset() + value.position(), value.remaining(),
columnFamilyHandle.nativeHandle_);
} else {
throw new RocksDBException(BB_ALL_DIRECT_OR_INDIRECT);
}
key.position(key.limit());
value.position(value.limit());
}
/**
* Delete the database entry (if any) for "key". Returns OK on
* success, and a non-OK status on error. It is not an error if "key"
* did not exist in the database.
*
* @param writeOpt WriteOptions to be used with delete operation
* @param key Key to delete within database. It is using position and limit.
* Supports direct buffer only.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void delete(final WriteOptions writeOpt, final ByteBuffer key) throws RocksDBException {
assert key.isDirect();
deleteDirect(nativeHandle_, writeOpt.nativeHandle_, key, key.position(), key.remaining(), 0);
key.position(key.limit());
}
/**
* Delete the database entry (if any) for "key". Returns OK on
* success, and a non-OK status on error. It is not an error if "key"
* did not exist in the database.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance
* @param writeOpt WriteOptions to be used with delete operation
* @param key Key to delete within database. It is using position and limit.
* Supports direct buffer only.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void delete(final ColumnFamilyHandle columnFamilyHandle, final WriteOptions writeOpt,
final ByteBuffer key) throws RocksDBException {
assert key.isDirect();
deleteDirect(nativeHandle_, writeOpt.nativeHandle_, key, key.position(), key.remaining(),
columnFamilyHandle.nativeHandle_);
key.position(key.limit());
}
/**
* Add merge operand for key/value pair.
*
* @param columnFamilyHandle {@link ColumnFamilyHandle} instance
* @param writeOpts {@link WriteOptions} for this write.
* @param key the specified key to be merged.
* @param value the value to be merged with the current value for the
* specified key.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void merge(final ColumnFamilyHandle columnFamilyHandle,
final WriteOptions writeOpts, final byte[] key, final byte[] value)
throws RocksDBException {
merge(nativeHandle_, writeOpts.nativeHandle_,
key, 0, key.length, value, 0, value.length,
columnFamilyHandle.nativeHandle_);
}
/**
* Add merge operand for key/value pair.
*
* @param columnFamilyHandle {@link ColumnFamilyHandle} instance
* @param writeOpts {@link WriteOptions} for this write.
* @param key the specified key to be merged.
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be non-negative
* and no larger than ("key".length - offset)
* @param value the value to be merged with the current value for
* the specified key.
* @param vOffset the offset of the "value" array to be used, must be
* non-negative and no longer than "key".length
* @param vLen the length of the "value" array to be used, must be
* non-negative and no larger than ("value".length - offset)
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
* @throws IndexOutOfBoundsException if an offset or length is out of bounds
*/
public void 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)
throws RocksDBException {
CheckBounds(offset, len, key.length);
CheckBounds(vOffset, vLen, value.length);
merge(nativeHandle_, writeOpts.nativeHandle_,
key, offset, len, value, vOffset, vLen,
columnFamilyHandle.nativeHandle_);
}
/**
* Apply the specified updates to the database.
*
* @param writeOpts WriteOptions instance
* @param updates WriteBatch instance
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void write(final WriteOptions writeOpts, final WriteBatch updates)
throws RocksDBException {
write0(nativeHandle_, writeOpts.nativeHandle_, updates.nativeHandle_);
}
/**
* Apply the specified updates to the database.
*
* @param writeOpts WriteOptions instance
* @param updates WriteBatchWithIndex instance
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void write(final WriteOptions writeOpts,
final WriteBatchWithIndex updates) throws RocksDBException {
write1(nativeHandle_, writeOpts.nativeHandle_, updates.nativeHandle_);
}
// TODO(AR) we should improve the #get() API, returning -1 (RocksDB.NOT_FOUND) is not very nice
// when we could communicate better status into, also the C++ code show that -2 could be returned
/**
* Get the value associated with the specified key within column family*
*
* @param key the key to retrieve the value.
* @param value the out-value to receive the retrieved value.
*
* @return The size of the actual value that matches the specified
* {@code key} in byte. If the return value is greater than the
* length of {@code value}, then it indicates that the size of the
* input buffer {@code value} is insufficient and partial result will
* be returned. RocksDB.NOT_FOUND will be returned if the value not
* found.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public int get(final byte[] key, final byte[] value) throws RocksDBException {
return get(nativeHandle_, key, 0, key.length, value, 0, value.length);
}
/**
* Get the value associated with the specified key within column family*
*
* @param key the key to retrieve the value.
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be non-negative
* and no larger than ("key".length - offset)
* @param value the out-value to receive the retrieved value.
* @param vOffset the offset of the "value" array to be used, must be
* non-negative and no longer than "value".length
* @param vLen the length of the "value" array to be used, must be
* non-negative and and no larger than ("value".length - offset)
*
* @return The size of the actual value that matches the specified
* {@code key} in byte. If the return value is greater than the
* length of {@code value}, then it indicates that the size of the
* input buffer {@code value} is insufficient and partial result will
* be returned. RocksDB.NOT_FOUND will be returned if the value not
* found.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public int get(final byte[] key, final int offset, final int len,
final byte[] value, final int vOffset, final int vLen)
throws RocksDBException {
CheckBounds(offset, len, key.length);
CheckBounds(vOffset, vLen, value.length);
return get(nativeHandle_, key, offset, len, value, vOffset, vLen);
}
/**
* Get the value associated with the specified key within column family.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance
* @param key the key to retrieve the value.
* @param value the out-value to receive the retrieved value.
* @return The size of the actual value that matches the specified
* {@code key} in byte. If the return value is greater than the
* length of {@code value}, then it indicates that the size of the
* input buffer {@code value} is insufficient and partial result will
* be returned. RocksDB.NOT_FOUND will be returned if the value not
* found.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public int get(final ColumnFamilyHandle columnFamilyHandle, final byte[] key,
final byte[] value) throws RocksDBException, IllegalArgumentException {
return get(nativeHandle_, key, 0, key.length, value, 0, value.length,
columnFamilyHandle.nativeHandle_);
}
/**
* Get the value associated with the specified key within column family.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance
* @param key the key to retrieve the value.
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be non-negative
* an no larger than ("key".length - offset)
* @param value the out-value to receive the retrieved value.
* @param vOffset the offset of the "value" array to be used, must be
* non-negative and no longer than "key".length
* @param vLen the length of the "value" array to be used, must be
* non-negative and no larger than ("value".length - offset)
*
* @return The size of the actual value that matches the specified
* {@code key} in byte. If the return value is greater than the
* length of {@code value}, then it indicates that the size of the
* input buffer {@code value} is insufficient and partial result will
* be returned. RocksDB.NOT_FOUND will be returned if the value not
* found.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public int get(final ColumnFamilyHandle columnFamilyHandle, final byte[] key,
final int offset, final int len, final byte[] value, final int vOffset,
final int vLen) throws RocksDBException, IllegalArgumentException {
CheckBounds(offset, len, key.length);
CheckBounds(vOffset, vLen, value.length);
return get(nativeHandle_, key, offset, len, value, vOffset, vLen,
columnFamilyHandle.nativeHandle_);
}
/**
* Get the value associated with the specified key.
*
* @param opt {@link org.forstdb.ReadOptions} instance.
* @param key the key to retrieve the value.
* @param value the out-value to receive the retrieved value.
* @return The size of the actual value that matches the specified
* {@code key} in byte. If the return value is greater than the
* length of {@code value}, then it indicates that the size of the
* input buffer {@code value} is insufficient and partial result will
* be returned. RocksDB.NOT_FOUND will be returned if the value not
* found.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public int get(final ReadOptions opt, final byte[] key,
final byte[] value) throws RocksDBException {
return get(nativeHandle_, opt.nativeHandle_,
key, 0, key.length, value, 0, value.length);
}
/**
* Get the value associated with the specified key.
*
* @param opt {@link org.forstdb.ReadOptions} instance.
* @param key the key to retrieve the value.
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be non-negative
* and no larger than ("key".length - offset)
* @param value the out-value to receive the retrieved value.
* @param vOffset the offset of the "value" array to be used, must be
* non-negative and no longer than "key".length
* @param vLen the length of the "value" array to be used, must be
* non-negative and no larger than ("value".length - offset)
* @return The size of the actual value that matches the specified
* {@code key} in byte. If the return value is greater than the
* length of {@code value}, then it indicates that the size of the
* input buffer {@code value} is insufficient and partial result will
* be returned. RocksDB.NOT_FOUND will be returned if the value not
* found.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public int get(final ReadOptions opt, final byte[] key, final int offset,
final int len, final byte[] value, final int vOffset, final int vLen)
throws RocksDBException {
CheckBounds(offset, len, key.length);
CheckBounds(vOffset, vLen, value.length);
return get(nativeHandle_, opt.nativeHandle_,
key, offset, len, value, vOffset, vLen);
}
/**
* Get the value associated with the specified key within column family.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance
* @param opt {@link org.forstdb.ReadOptions} instance.
* @param key the key to retrieve the value.
* @param value the out-value to receive the retrieved value.
* @return The size of the actual value that matches the specified
* {@code key} in byte. If the return value is greater than the
* length of {@code value}, then it indicates that the size of the
* input buffer {@code value} is insufficient and partial result will
* be returned. RocksDB.NOT_FOUND will be returned if the value not
* found.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public int get(final ColumnFamilyHandle columnFamilyHandle,
final ReadOptions opt, final byte[] key, final byte[] value)
throws RocksDBException {
return get(nativeHandle_, opt.nativeHandle_, key, 0, key.length, value,
0, value.length, columnFamilyHandle.nativeHandle_);
}
/**
* Get the value associated with the specified key within column family.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance
* @param opt {@link org.forstdb.ReadOptions} instance.
* @param key the key to retrieve the value.
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be
* non-negative and and no larger than ("key".length - offset)
* @param value the out-value to receive the retrieved value.
* @param vOffset the offset of the "value" array to be used, must be
* non-negative and no longer than "key".length
* @param vLen the length of the "value" array to be used, and must be
* non-negative and no larger than ("value".length - offset)
* @return The size of the actual value that matches the specified
* {@code key} in byte. If the return value is greater than the
* length of {@code value}, then it indicates that the size of the
* input buffer {@code value} is insufficient and partial result will
* be returned. RocksDB.NOT_FOUND will be returned if the value not
* found.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public int 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)
throws RocksDBException {
CheckBounds(offset, len, key.length);
CheckBounds(vOffset, vLen, value.length);
return get(nativeHandle_, opt.nativeHandle_, key, offset, len, value,
vOffset, vLen, columnFamilyHandle.nativeHandle_);
}
/**
* The simplified version of get which returns a new byte array storing
* the value associated with the specified input key if any. null will be
* returned if the specified key is not found.
*
* @param key the key retrieve the value.
* @return a byte array storing the value associated with the input key if
* any. null if it does not find the specified key.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public byte[] get(final byte[] key) throws RocksDBException {
return get(nativeHandle_, key, 0, key.length);
}
/**
* The simplified version of get which returns a new byte array storing
* the value associated with the specified input key if any. null will be
* returned if the specified key is not found.
*
* @param key the key retrieve the value.
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be non-negative
* and no larger than ("key".length - offset)
* @return a byte array storing the value associated with the input key if
* any. null if it does not find the specified key.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public byte[] get(final byte[] key, final int offset,
final int len) throws RocksDBException {
CheckBounds(offset, len, key.length);
return get(nativeHandle_, key, offset, len);
}
/**
* The simplified version of get which returns a new byte array storing
* the value associated with the specified input key if any. null will be
* returned if the specified key is not found.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance
* @param key the key retrieve the value.
* @return a byte array storing the value associated with the input key if
* any. null if it does not find the specified key.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public byte[] get(final ColumnFamilyHandle columnFamilyHandle,
final byte[] key) throws RocksDBException {
return get(nativeHandle_, key, 0, key.length,
columnFamilyHandle.nativeHandle_);
}
/**
* The simplified version of get which returns a new byte array storing
* the value associated with the specified input key if any. null will be
* returned if the specified key is not found.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance
* @param key the key retrieve the value.
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be non-negative
* and no larger than ("key".length - offset)
* @return a byte array storing the value associated with the input key if
* any. null if it does not find the specified key.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public byte[] get(final ColumnFamilyHandle columnFamilyHandle,
final byte[] key, final int offset, final int len)
throws RocksDBException {
CheckBounds(offset, len, key.length);
return get(nativeHandle_, key, offset, len,
columnFamilyHandle.nativeHandle_);
}
/**
* The simplified version of get which returns a new byte array storing
* the value associated with the specified input key if any. null will be
* returned if the specified key is not found.
*
* @param key the key retrieve the value.
* @param opt Read options.
* @return a byte array storing the value associated with the input key if
* any. null if it does not find the specified key.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public byte[] get(final ReadOptions opt, final byte[] key)
throws RocksDBException {
return get(nativeHandle_, opt.nativeHandle_, key, 0, key.length);
}
/**
* The simplified version of get which returns a new byte array storing
* the value associated with the specified input key if any. null will be
* returned if the specified key is not found.
*
* @param key the key retrieve the value.
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be non-negative
* and no larger than ("key".length - offset)
* @param opt Read options.
* @return a byte array storing the value associated with the input key if
* any. null if it does not find the specified key.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public byte[] get(final ReadOptions opt, final byte[] key, final int offset,
final int len) throws RocksDBException {
CheckBounds(offset, len, key.length);
return get(nativeHandle_, opt.nativeHandle_, key, offset, len);
}
/**
* The simplified version of get which returns a new byte array storing
* the value associated with the specified input key if any. null will be
* returned if the specified key is not found.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance
* @param key the key retrieve the value.
* @param opt Read options.
* @return a byte array storing the value associated with the input key if
* any. null if it does not find the specified key.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public byte[] get(final ColumnFamilyHandle columnFamilyHandle,
final ReadOptions opt, final byte[] key) throws RocksDBException {
return get(nativeHandle_, opt.nativeHandle_, key, 0, key.length,
columnFamilyHandle.nativeHandle_);
}
/**
* The simplified version of get which returns a new byte array storing
* the value associated with the specified input key if any. null will be
* returned if the specified key is not found.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance
* @param key the key retrieve the value.
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be non-negative
* and no larger than ("key".length - offset)
* @param opt Read options.
* @return a byte array storing the value associated with the input key if
* any. null if it does not find the specified key.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public byte[] get(final ColumnFamilyHandle columnFamilyHandle,
final ReadOptions opt, final byte[] key, final int offset, final int len)
throws RocksDBException {
CheckBounds(offset, len, key.length);
return get(nativeHandle_, opt.nativeHandle_, key, offset, len,
columnFamilyHandle.nativeHandle_);
}
/**
* Takes a list of keys, and returns a list of values for the given list of
* keys. List will contain null for keys which could not be found.
*
* @param keys List of keys for which values need to be retrieved.
* @return List of values for the given list of keys. List will contain
* null for keys which could not be found.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public List multiGetAsList(final List keys)
throws RocksDBException {
assert (!keys.isEmpty());
final byte[][] keysArray = keys.toArray(new byte[keys.size()][]);
final int[] keyOffsets = new int[keysArray.length];
final int[] keyLengths = new int[keysArray.length];
for(int i = 0; i < keyLengths.length; i++) {
keyLengths[i] = keysArray[i].length;
}
return Arrays.asList(multiGet(nativeHandle_, keysArray, keyOffsets,
keyLengths));
}
/**
* Returns a list of values for the given list of keys. List will contain
* null for keys which could not be found.
*
* Note: Every key needs to have a related column family name in
* {@code columnFamilyHandleList}.
*
*
* @param columnFamilyHandleList {@link java.util.List} containing
* {@link org.forstdb.ColumnFamilyHandle} instances.
* @param keys List of keys for which values need to be retrieved.
* @return List of values for the given list of keys. List will contain
* null for keys which could not be found.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
* @throws IllegalArgumentException thrown if the size of passed keys is not
* equal to the amount of passed column family handles.
*/
public List multiGetAsList(
final List columnFamilyHandleList,
final List keys) throws RocksDBException,
IllegalArgumentException {
assert (!keys.isEmpty());
// Check if key size equals cfList size. If not a exception must be
// thrown. If not a Segmentation fault happens.
if (keys.size() != columnFamilyHandleList.size()) {
throw new IllegalArgumentException(
"For each key there must be a ColumnFamilyHandle.");
}
final long[] cfHandles = new long[columnFamilyHandleList.size()];
for (int i = 0; i < columnFamilyHandleList.size(); i++) {
cfHandles[i] = columnFamilyHandleList.get(i).nativeHandle_;
}
final byte[][] keysArray = keys.toArray(new byte[keys.size()][]);
final int[] keyOffsets = new int[keysArray.length];
final int[] keyLengths = new int[keysArray.length];
for(int i = 0; i < keyLengths.length; i++) {
keyLengths[i] = keysArray[i].length;
}
return Arrays.asList(multiGet(nativeHandle_, keysArray, keyOffsets,
keyLengths, cfHandles));
}
/**
* Returns a list of values for the given list of keys. List will contain
* null for keys which could not be found.
*
* @param opt Read options.
* @param keys of keys for which values need to be retrieved.
* @return List of values for the given list of keys. List will contain
* null for keys which could not be found.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public List multiGetAsList(final ReadOptions opt,
final List keys) throws RocksDBException {
assert (!keys.isEmpty());
final byte[][] keysArray = keys.toArray(new byte[keys.size()][]);
final int[] keyOffsets = new int[keysArray.length];
final int[] keyLengths = new int[keysArray.length];
for(int i = 0; i < keyLengths.length; i++) {
keyLengths[i] = keysArray[i].length;
}
return Arrays.asList(multiGet(nativeHandle_, opt.nativeHandle_,
keysArray, keyOffsets, keyLengths));
}
/**
* Returns a list of values for the given list of keys. List will contain
* null for keys which could not be found.
*
* Note: Every key needs to have a related column family name in
* {@code columnFamilyHandleList}.
*
*
* @param opt Read options.
* @param columnFamilyHandleList {@link java.util.List} containing
* {@link org.forstdb.ColumnFamilyHandle} instances.
* @param keys of keys for which values need to be retrieved.
* @return List of values for the given list of keys. List will contain
* null for keys which could not be found.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
* @throws IllegalArgumentException thrown if the size of passed keys is not
* equal to the amount of passed column family handles.
*/
public List multiGetAsList(final ReadOptions opt,
final List columnFamilyHandleList,
final List keys) throws RocksDBException {
assert (!keys.isEmpty());
// Check if key size equals cfList size. If not a exception must be
// thrown. If not a Segmentation fault happens.
if (keys.size()!=columnFamilyHandleList.size()){
throw new IllegalArgumentException(
"For each key there must be a ColumnFamilyHandle.");
}
final long[] cfHandles = new long[columnFamilyHandleList.size()];
for (int i = 0; i < columnFamilyHandleList.size(); i++) {
cfHandles[i] = columnFamilyHandleList.get(i).nativeHandle_;
}
final byte[][] keysArray = keys.toArray(new byte[keys.size()][]);
final int[] keyOffsets = new int[keysArray.length];
final int[] keyLengths = new int[keysArray.length];
for(int i = 0; i < keyLengths.length; i++) {
keyLengths[i] = keysArray[i].length;
}
return Arrays.asList(multiGet(nativeHandle_, opt.nativeHandle_,
keysArray, keyOffsets, keyLengths, cfHandles));
}
/**
* Fetches a list of values for the given list of keys, all from the default column family.
*
* @param keys list of keys for which values need to be retrieved.
* @param values list of buffers to return retrieved values in
* @return list of number of bytes in DB for each requested key
* this can be more than the size of the corresponding buffer; then the buffer will be filled
* with the appropriate truncation of the database value.
* @throws RocksDBException if error happens in underlying native library.
* @throws IllegalArgumentException thrown if the number of passed keys and passed values
* do not match.
*/
public List multiGetByteBuffers(
final List keys, final List values) throws RocksDBException {
try (ReadOptions readOptions = new ReadOptions()) {
final List columnFamilyHandleList = new ArrayList<>(1);
columnFamilyHandleList.add(getDefaultColumnFamily());
return multiGetByteBuffers(readOptions, columnFamilyHandleList, keys, values);
}
}
/**
* Fetches a list of values for the given list of keys, all from the default column family.
*
* @param readOptions Read options
* @param keys list of keys for which values need to be retrieved.
* @param values list of buffers to return retrieved values in
* @throws RocksDBException if error happens in underlying native library.
* @throws IllegalArgumentException thrown if the number of passed keys and passed values
* do not match.
* @return the list of values for the given list of keys
*/
public List multiGetByteBuffers(final ReadOptions readOptions,
final List keys, final List values) throws RocksDBException {
final List columnFamilyHandleList = new ArrayList<>(1);
columnFamilyHandleList.add(getDefaultColumnFamily());
return multiGetByteBuffers(readOptions, columnFamilyHandleList, keys, values);
}
/**
* Fetches a list of values for the given list of keys.
*
* Note: Every key needs to have a related column family name in
* {@code columnFamilyHandleList}.
*
*
* @param columnFamilyHandleList {@link java.util.List} containing
* {@link org.forstdb.ColumnFamilyHandle} instances.
* @param keys list of keys for which values need to be retrieved.
* @param values list of buffers to return retrieved values in
* @throws RocksDBException if error happens in underlying native library.
* @throws IllegalArgumentException thrown if the number of passed keys, passed values and
* passed column family handles do not match.
* @return the list of values for the given list of keys
*/
public List multiGetByteBuffers(
final List columnFamilyHandleList, final List keys,
final List values) throws RocksDBException {
try (ReadOptions readOptions = new ReadOptions()) {
return multiGetByteBuffers(readOptions, columnFamilyHandleList, keys, values);
}
}
/**
* Fetches a list of values for the given list of keys.
*
* Note: Every key needs to have a related column family name in
* {@code columnFamilyHandleList}.
*
*
* @param readOptions Read options
* @param columnFamilyHandleList {@link java.util.List} containing
* {@link org.forstdb.ColumnFamilyHandle} instances.
* @param keys list of keys for which values need to be retrieved.
* @param values list of buffers to return retrieved values in
* @throws RocksDBException if error happens in underlying native library.
* @throws IllegalArgumentException thrown if the number of passed keys, passed values and
* passed column family handles do not match.
* @return the list of values for the given list of keys
*/
public List multiGetByteBuffers(final ReadOptions readOptions,
final List columnFamilyHandleList, final List keys,
final List values) throws RocksDBException {
assert (!keys.isEmpty());
// Check if key size equals cfList size. If not a exception must be
// thrown. If not a Segmentation fault happens.
if (keys.size() != columnFamilyHandleList.size() && columnFamilyHandleList.size() > 1) {
throw new IllegalArgumentException(
"Wrong number of ColumnFamilyHandle(s) supplied. Provide 0, 1, or as many as there are key/value(s)");
}
// Check if key size equals cfList size. If not a exception must be
// thrown. If not a Segmentation fault happens.
if (values.size() != keys.size()) {
throw new IllegalArgumentException("For each key there must be a corresponding value.");
}
// TODO (AP) support indirect buffers
for (final ByteBuffer key : keys) {
if (!key.isDirect()) {
throw new IllegalArgumentException("All key buffers must be direct byte buffers");
}
}
// TODO (AP) support indirect buffers, though probably via a less efficient code path
for (final ByteBuffer value : values) {
if (!value.isDirect()) {
throw new IllegalArgumentException("All value buffers must be direct byte buffers");
}
}
final int numCFHandles = columnFamilyHandleList.size();
final long[] cfHandles = new long[numCFHandles];
for (int i = 0; i < numCFHandles; i++) {
cfHandles[i] = columnFamilyHandleList.get(i).nativeHandle_;
}
final int numValues = keys.size();
final ByteBuffer[] keysArray = keys.toArray(new ByteBuffer[0]);
final int[] keyOffsets = new int[numValues];
final int[] keyLengths = new int[numValues];
for (int i = 0; i < numValues; i++) {
// TODO (AP) add keysArray[i].arrayOffset() if the buffer is indirect
// TODO (AP) because in that case we have to pass the array directly,
// so that the JNI C++ code will not know to compensate for the array offset
keyOffsets[i] = keysArray[i].position();
keyLengths[i] = keysArray[i].limit();
}
final ByteBuffer[] valuesArray = values.toArray(new ByteBuffer[0]);
final int[] valuesSizeArray = new int[numValues];
final Status[] statusArray = new Status[numValues];
multiGet(nativeHandle_, readOptions.nativeHandle_, cfHandles, keysArray, keyOffsets, keyLengths,
valuesArray, valuesSizeArray, statusArray);
final List results = new ArrayList<>();
for (int i = 0; i < numValues; i++) {
final Status status = statusArray[i];
if (status.getCode() == Status.Code.Ok) {
final ByteBuffer value = valuesArray[i];
value.position(Math.min(valuesSizeArray[i], value.capacity()));
value.flip(); // prepare for read out
results.add(new ByteBufferGetStatus(status, valuesSizeArray[i], value));
} else {
results.add(new ByteBufferGetStatus(status));
}
}
return results;
}
/**
* Check if a key exists in the database.
* This method is not as lightweight as {@code keyMayExist} but it gives a 100% guarantee
* of a correct result, whether the key exists or not.
*
* Internally it checks if the key may exist and then double checks with read operation
* that confirms the key exists. This deals with the case where {@code keyMayExist} may return
* a false positive.
*
* The code crosses the Java/JNI boundary only once.
* @param key byte array of a key to search for*
* @return true if key exist in database, otherwise false.
*/
public boolean keyExists(final byte[] key) {
return keyExists(key, 0, key.length);
}
/**
* Check if a key exists in the database.
* This method is not as lightweight as {@code keyMayExist} but it gives a 100% guarantee
* of a correct result, whether the key exists or not.
*
* Internally it checks if the key may exist and then double checks with read operation
* that confirms the key exists. This deals with the case where {@code keyMayExist} may return
* a false positive.
*
* The code crosses the Java/JNI boundary only once.
* @param key byte array of a key to search for
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be non-negative
* and no larger than "key".length
* @return true if key exist in database, otherwise false.
*/
public boolean keyExists(final byte[] key, final int offset, final int len) {
return keyExists(null, null, key, offset, len);
}
/**
* Check if a key exists in the database.
* This method is not as lightweight as {@code keyMayExist} but it gives a 100% guarantee
* of a correct result, whether the key exists or not.
*
* Internally it checks if the key may exist and then double checks with read operation
* that confirms the key exists. This deals with the case where {@code keyMayExist} may return
* a false positive.
*
* The code crosses the Java/JNI boundary only once.
*
* @param columnFamilyHandle {@link ColumnFamilyHandle} instance
* @param key byte array of a key to search for
* @return true if key exist in database, otherwise false.
*/
public boolean keyExists(final ColumnFamilyHandle columnFamilyHandle, final byte[] key) {
return keyExists(columnFamilyHandle, key, 0, key.length);
}
/**
* Check if a key exists in the database.
* This method is not as lightweight as {@code keyMayExist} but it gives a 100% guarantee
* of a correct result, whether the key exists or not.
*
* Internally it checks if the key may exist and then double checks with read operation
* that confirms the key exists. This deals with the case where {@code keyMayExist} may return
* a false positive.
*
* The code crosses the Java/JNI boundary only once.
*
* @param columnFamilyHandle {@link ColumnFamilyHandle} instance
* @param key byte array of a key to search for
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be non-negative
* and no larger than "key".length
* @return true if key exist in database, otherwise false.
*/
public boolean keyExists(final ColumnFamilyHandle columnFamilyHandle, final byte[] key,
final int offset, final int len) {
return keyExists(columnFamilyHandle, null, key, offset, len);
}
/**
* Check if a key exists in the database.
* This method is not as lightweight as {@code keyMayExist} but it gives a 100% guarantee
* of a correct result, whether the key exists or not.
*
* Internally it checks if the key may exist and then double checks with read operation
* that confirms the key exists. This deals with the case where {@code keyMayExist} may return
* a false positive.
*
* The code crosses the Java/JNI boundary only once.
*
* @param readOptions {@link ReadOptions} instance
* @param key byte array of a key to search for
* @return true if key exist in database, otherwise false.
*/
public boolean keyExists(final ReadOptions readOptions, final byte[] key) {
return keyExists(readOptions, key, 0, key.length);
}
/**
* Check if a key exists in the database.
* This method is not as lightweight as {@code keyMayExist} but it gives a 100% guarantee
* of a correct result, whether the key exists or not.
*
* Internally it checks if the key may exist and then double checks with read operation
* that confirms the key exists. This deals with the case where {@code keyMayExist} may return
* a false positive.
*
* The code crosses the Java/JNI boundary only once.
*
* @param readOptions {@link ReadOptions} instance
* @param key byte array of a key to search for
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be non-negative
* and no larger than "key".length
* @return true if key exist in database, otherwise false.
*/
public boolean keyExists(
final ReadOptions readOptions, final byte[] key, final int offset, final int len) {
return keyExists(null, readOptions, key, offset, len);
}
/**
* Check if a key exists in the database.
* This method is not as lightweight as {@code keyMayExist} but it gives a 100% guarantee
* of a correct result, whether the key exists or not.
*
* Internally it checks if the key may exist and then double checks with read operation
* that confirms the key exists. This deals with the case where {@code keyMayExist} may return
* a false positive.
*
* The code crosses the Java/JNI boundary only once.
*
* @param columnFamilyHandle {@link ColumnFamilyHandle} instance
* @param readOptions {@link ReadOptions} instance
* @param key byte array of a key to search for
* @return true if key exist in database, otherwise false.
*/
public boolean keyExists(final ColumnFamilyHandle columnFamilyHandle,
final ReadOptions readOptions, final byte[] key) {
return keyExists(columnFamilyHandle, readOptions, key, 0, key.length);
}
/**
* Check if a key exists in the database.
* This method is not as lightweight as {@code keyMayExist} but it gives a 100% guarantee
* of a correct result, whether the key exists or not.
*
* Internally it checks if the key may exist and then double checks with read operation
* that confirms the key exists. This deals with the case where {@code keyMayExist} may return
* a false positive.
*
* The code crosses the Java/JNI boundary only once.
*
* @param columnFamilyHandle {@link ColumnFamilyHandle} instance
* @param readOptions {@link ReadOptions} instance
* @param key byte array of a key to search for
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be non-negative
* and no larger than "key".length
* @return true if key exist in database, otherwise false.
*/
public boolean keyExists(final ColumnFamilyHandle columnFamilyHandle,
final ReadOptions readOptions, final byte[] key, final int offset, final int len) {
checkBounds(offset, len, key.length);
return keyExists(nativeHandle_,
columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
readOptions == null ? 0 : readOptions.nativeHandle_, key, offset, len);
}
/**
* Check if a key exists in the database.
* This method is not as lightweight as {@code keyMayExist} but it gives a 100% guarantee
* of a correct result, whether the key exists or not.
*
* Internally it checks if the key may exist and then double checks with read operation
* that confirms the key exists. This deals with the case where {@code keyMayExist} may return
* a false positive.
*
* The code crosses the Java/JNI boundary only once.
*
* @param key ByteBuffer with key. Must be allocated as direct.
* @return true if key exist in database, otherwise false.
*/
public boolean keyExists(final ByteBuffer key) {
return keyExists(null, null, key);
}
/**
* Check if a key exists in the database.
* This method is not as lightweight as {@code keyMayExist} but it gives a 100% guarantee
* of a correct result, whether the key exists or not.
*
* Internally it checks if the key may exist and then double checks with read operation
* that confirms the key exists. This deals with the case where {@code keyMayExist} may return
* a false positive.
*
* The code crosses the Java/JNI boundary only once.
*
* @param columnFamilyHandle {@link ColumnFamilyHandle} instance
* @param key ByteBuffer with key. Must be allocated as direct.
* @return true if key exist in database, otherwise false.
*/
public boolean keyExists(final ColumnFamilyHandle columnFamilyHandle, final ByteBuffer key) {
return keyExists(columnFamilyHandle, null, key);
}
/**
* Check if a key exists in the database.
* This method is not as lightweight as {@code keyMayExist} but it gives a 100% guarantee
* of a correct result, whether the key exists or not.
*
* Internally it checks if the key may exist and then double checks with read operation
* that confirms the key exists. This deals with the case where {@code keyMayExist} may return
* a false positive.
*
* The code crosses the Java/JNI boundary only once.
*
* @param readOptions {@link ReadOptions} instance
* @param key ByteBuffer with key. Must be allocated as direct.
* @return true if key exist in database, otherwise false.
*/
public boolean keyExists(final ReadOptions readOptions, final ByteBuffer key) {
return keyExists(null, readOptions, key);
}
/**
* Check if a key exists in the database.
* This method is not as lightweight as {@code keyMayExist} but it gives a 100% guarantee
* of a correct result, whether the key exists or not.
*
* Internally it checks if the key may exist and then double checks with read operation
* that confirms the key exists. This deals with the case where {@code keyMayExist} may return
* a false positive.
*
* The code crosses the Java/JNI boundary only once.
*
* @param columnFamilyHandle {@link ColumnFamilyHandle} instance
* @param readOptions {@link ReadOptions} instance
* @param key ByteBuffer with key. Must be allocated as direct.
* @return true if key exist in database, otherwise false.
*/
public boolean keyExists(final ColumnFamilyHandle columnFamilyHandle,
final ReadOptions readOptions, final ByteBuffer key) {
assert key != null : "key ByteBuffer parameter cannot be null";
assert key.isDirect() : "key parameter must be a direct ByteBuffer";
return keyExistsDirect(nativeHandle_,
columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
readOptions == null ? 0 : readOptions.nativeHandle_, key, key.position(), key.limit());
}
/**
* If the key definitely does not exist in the database, then this method
* returns false, otherwise it returns true if the key might exist.
* That is to say that this method is probabilistic and may return false
* positives, but never a false negative.
*
* If the caller wants to obtain value when the key
* is found in memory, then {@code valueHolder} must be set.
*
* This check is potentially lighter-weight than invoking
* {@link #get(byte[])}. One way to make this lighter weight is to avoid
* doing any IOs.
*
* @param key byte array of a key to search for
* @param valueHolder non-null to retrieve the value if it is found, or null
* if the value is not needed. If non-null, upon return of the function,
* the {@code value} will be set if it could be retrieved.
*
* @return false if the key definitely does not exist in the database,
* otherwise true.
*/
public boolean keyMayExist(final byte[] key,
/* @Nullable */ final Holder valueHolder) {
return keyMayExist(key, 0, key.length, valueHolder);
}
/**
* If the key definitely does not exist in the database, then this method
* returns false, otherwise it returns true if the key might exist.
* That is to say that this method is probabilistic and may return false
* positives, but never a false negative.
*
* If the caller wants to obtain value when the key
* is found in memory, then {@code valueHolder} must be set.
*
* This check is potentially lighter-weight than invoking
* {@link #get(byte[], int, int)}. One way to make this lighter weight is to
* avoid doing any IOs.
*
* @param key byte array of a key to search for
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be non-negative
* and no larger than "key".length
* @param valueHolder non-null to retrieve the value if it is found, or null
* if the value is not needed. If non-null, upon return of the function,
* the {@code value} will be set if it could be retrieved.
*
* @return false if the key definitely does not exist in the database,
* otherwise true.
*/
public boolean keyMayExist(final byte[] key,
final int offset, final int len,
/* @Nullable */ final Holder valueHolder) {
return keyMayExist((ColumnFamilyHandle)null, key, offset, len, valueHolder);
}
/**
* If the key definitely does not exist in the database, then this method
* returns false, otherwise it returns true if the key might exist.
* That is to say that this method is probabilistic and may return false
* positives, but never a false negative.
*
* If the caller wants to obtain value when the key
* is found in memory, then {@code valueHolder} must be set.
*
* This check is potentially lighter-weight than invoking
* {@link #get(ColumnFamilyHandle,byte[])}. One way to make this lighter
* weight is to avoid doing any IOs.
*
* @param columnFamilyHandle {@link ColumnFamilyHandle} instance
* @param key byte array of a key to search for
* @param valueHolder non-null to retrieve the value if it is found, or null
* if the value is not needed. If non-null, upon return of the function,
* the {@code value} will be set if it could be retrieved.
*
* @return false if the key definitely does not exist in the database,
* otherwise true.
*/
public boolean keyMayExist(
final ColumnFamilyHandle columnFamilyHandle, final byte[] key,
/* @Nullable */ final Holder valueHolder) {
return keyMayExist(columnFamilyHandle, key, 0, key.length,
valueHolder);
}
/**
* If the key definitely does not exist in the database, then this method
* returns false, otherwise it returns true if the key might exist.
* That is to say that this method is probabilistic and may return false
* positives, but never a false negative.
*
* If the caller wants to obtain value when the key
* is found in memory, then {@code valueHolder} must be set.
*
* This check is potentially lighter-weight than invoking
* {@link #get(ColumnFamilyHandle, byte[], int, int)}. One way to make this
* lighter weight is to avoid doing any IOs.
*
* @param columnFamilyHandle {@link ColumnFamilyHandle} instance
* @param key byte array of a key to search for
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be non-negative
* and no larger than "key".length
* @param valueHolder non-null to retrieve the value if it is found, or null
* if the value is not needed. If non-null, upon return of the function,
* the {@code value} will be set if it could be retrieved.
*
* @return false if the key definitely does not exist in the database,
* otherwise true.
*/
public boolean keyMayExist(final ColumnFamilyHandle columnFamilyHandle, final byte[] key,
final int offset, final int len,
/* @Nullable */ final Holder valueHolder) {
return keyMayExist(columnFamilyHandle, null, key, offset, len,
valueHolder);
}
/**
* If the key definitely does not exist in the database, then this method
* returns false, otherwise it returns true if the key might exist.
* That is to say that this method is probabilistic and may return false
* positives, but never a true negative.
*
* If the caller wants to obtain value when the key
* is found in memory, then {@code valueHolder} must be set.
*
* This check is potentially lighter-weight than invoking
* {@link #get(ReadOptions, byte[])}. One way to make this
* lighter weight is to avoid doing any IOs.
*
* @param readOptions {@link ReadOptions} instance
* @param key byte array of a key to search for
* @param valueHolder non-null to retrieve the value if it is found, or null
* if the value is not needed. If non-null, upon return of the function,
* the {@code value} will be set if it could be retrieved.
*
* @return false if the key definitely does not exist in the database,
* otherwise true.
*/
public boolean keyMayExist(
final ReadOptions readOptions, final byte[] key,
/* @Nullable */ final Holder valueHolder) {
return keyMayExist(readOptions, key, 0, key.length,
valueHolder);
}
/**
* If the key definitely does not exist in the database, then this method
* returns false, otherwise it returns true if the key might exist.
* That is to say that this method is probabilistic and may return false
* positives, but never a true negative.
*
* If the caller wants to obtain value when the key
* is found in memory, then {@code valueHolder} must be set.
*
* This check is potentially lighter-weight than invoking
* {@link #get(ReadOptions, byte[], int, int)}. One way to make this
* lighter weight is to avoid doing any IOs.
*
* @param readOptions {@link ReadOptions} instance
* @param key byte array of a key to search for
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be non-negative
* and no larger than "key".length
* @param valueHolder non-null to retrieve the value if it is found, or null
* if the value is not needed. If non-null, upon return of the function,
* the {@code value} will be set if it could be retrieved.
*
* @return false if the key definitely does not exist in the database,
* otherwise true.
*/
public boolean keyMayExist(
final ReadOptions readOptions,
final byte[] key, final int offset, final int len,
/* @Nullable */ final Holder valueHolder) {
return keyMayExist(null, readOptions,
key, offset, len, valueHolder);
}
/**
* If the key definitely does not exist in the database, then this method
* returns false, otherwise it returns true if the key might exist.
* That is to say that this method is probabilistic and may return false
* positives, but never a true negative.
*
* If the caller wants to obtain value when the key
* is found in memory, then {@code valueHolder} must be set.
*
* This check is potentially lighter-weight than invoking
* {@link #get(ColumnFamilyHandle, ReadOptions, byte[])}. One way to make this
* lighter weight is to avoid doing any IOs.
*
* @param columnFamilyHandle {@link ColumnFamilyHandle} instance
* @param readOptions {@link ReadOptions} instance
* @param key byte array of a key to search for
* @param valueHolder non-null to retrieve the value if it is found, or null
* if the value is not needed. If non-null, upon return of the function,
* the {@code value} will be set if it could be retrieved.
*
* @return false if the key definitely does not exist in the database,
* otherwise true.
*/
public boolean keyMayExist(
final ColumnFamilyHandle columnFamilyHandle,
final ReadOptions readOptions, final byte[] key,
/* @Nullable */ final Holder valueHolder) {
return keyMayExist(columnFamilyHandle, readOptions,
key, 0, key.length, valueHolder);
}
/**
* If the key definitely does not exist in the database, then this method
* returns false, otherwise it returns true if the key might exist.
* That is to say that this method is probabilistic and may return false
* positives, but never a false negative.
*
* If the caller wants to obtain value when the key
* is found in memory, then {@code valueHolder} must be set.
*
* This check is potentially lighter-weight than invoking
* {@link #get(ColumnFamilyHandle, ReadOptions, byte[], int, int)}.
* One way to make this lighter weight is to avoid doing any IOs.
*
* @param columnFamilyHandle {@link ColumnFamilyHandle} instance
* @param readOptions {@link ReadOptions} instance
* @param key byte array of a key to search for
* @param offset the offset of the "key" array to be used, must be
* non-negative and no larger than "key".length
* @param len the length of the "key" array to be used, must be non-negative
* and no larger than "key".length
* @param valueHolder non-null to retrieve the value if it is found, or null
* if the value is not needed. If non-null, upon return of the function,
* the {@code value} will be set if it could be retrieved.
*
* @return false if the key definitely does not exist in the database,
* otherwise true.
*/
public boolean keyMayExist(
final ColumnFamilyHandle columnFamilyHandle,
final ReadOptions readOptions,
final byte[] key, final int offset, final int len,
/* @Nullable */ final Holder valueHolder) {
CheckBounds(offset, len, key.length);
if (valueHolder == null) {
return keyMayExist(nativeHandle_,
columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
readOptions == null ? 0 : readOptions.nativeHandle_,
key, offset, len);
} else {
final byte[][] result = keyMayExistFoundValue(
nativeHandle_,
columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
readOptions == null ? 0 : readOptions.nativeHandle_,
key, offset, len);
if (result[0][0] == 0x0) {
valueHolder.setValue(null);
return false;
} else if (result[0][0] == 0x1) {
valueHolder.setValue(null);
return true;
} else {
valueHolder.setValue(result[1]);
return true;
}
}
}
/**
* If the key definitely does not exist in the database, then this method
* returns false, otherwise it returns true if the key might exist.
* That is to say that this method is probabilistic and may return false
* positives, but never a false negative.
*
* @param key bytebuffer containing the value of the key
* @return false if the key definitely does not exist in the database,
* otherwise true.
*/
public boolean keyMayExist(final ByteBuffer key) {
return keyMayExist(null, (ReadOptions) null, key);
}
/**
* If the key definitely does not exist in the database, then this method
* returns false, otherwise it returns true if the key might exist.
* That is to say that this method is probabilistic and may return false
* positives, but never a false negative.
*
* @param columnFamilyHandle the {@link ColumnFamilyHandle} to look for the key in
* @param key bytebuffer containing the value of the key
* @return false if the key definitely does not exist in the database,
* otherwise true.
*/
public boolean keyMayExist(final ColumnFamilyHandle columnFamilyHandle, final ByteBuffer key) {
return keyMayExist(columnFamilyHandle, (ReadOptions) null, key);
}
/**
* If the key definitely does not exist in the database, then this method
* returns false, otherwise it returns true if the key might exist.
* That is to say that this method is probabilistic and may return false
* positives, but never a false negative.
*
* @param readOptions the {@link ReadOptions} to use when reading the key/value
* @param key bytebuffer containing the value of the key
* @return false if the key definitely does not exist in the database,
* otherwise true.
*/
public boolean keyMayExist(final ReadOptions readOptions, final ByteBuffer key) {
return keyMayExist(null, readOptions, key);
}
/**
* If the key definitely does not exist in the database, then this method
* returns {@link KeyMayExist.KeyMayExistEnum#kNotExist},
* otherwise if it can with best effort retreive the value, it returns {@link
* KeyMayExist.KeyMayExistEnum#kExistsWithValue} otherwise it returns {@link
* KeyMayExist.KeyMayExistEnum#kExistsWithoutValue}. The choice not to return a value which might
* exist is at the discretion of the implementation; the only guarantee is that {@link
* KeyMayExist.KeyMayExistEnum#kNotExist} is an assurance that the key does not exist.
*
* @param key bytebuffer containing the value of the key
* @param value bytebuffer which will receive a value if the key exists and a value is known
* @return a {@link KeyMayExist} object reporting if key may exist and if a value is provided
*/
public KeyMayExist keyMayExist(final ByteBuffer key, final ByteBuffer value) {
return keyMayExist(null, null, key, value);
}
/**
* If the key definitely does not exist in the database, then this method
* returns {@link KeyMayExist.KeyMayExistEnum#kNotExist},
* otherwise if it can with best effort retreive the value, it returns {@link
* KeyMayExist.KeyMayExistEnum#kExistsWithValue} otherwise it returns {@link
* KeyMayExist.KeyMayExistEnum#kExistsWithoutValue}. The choice not to return a value which might
* exist is at the discretion of the implementation; the only guarantee is that {@link
* KeyMayExist.KeyMayExistEnum#kNotExist} is an assurance that the key does not exist.
*
* @param columnFamilyHandle the {@link ColumnFamilyHandle} to look for the key in
* @param key bytebuffer containing the value of the key
* @param value bytebuffer which will receive a value if the key exists and a value is known
* @return a {@link KeyMayExist} object reporting if key may exist and if a value is provided
*/
public KeyMayExist keyMayExist(
final ColumnFamilyHandle columnFamilyHandle, final ByteBuffer key, final ByteBuffer value) {
return keyMayExist(columnFamilyHandle, null, key, value);
}
/**
* If the key definitely does not exist in the database, then this method
* returns {@link KeyMayExist.KeyMayExistEnum#kNotExist},
* otherwise if it can with best effort retreive the value, it returns {@link
* KeyMayExist.KeyMayExistEnum#kExistsWithValue} otherwise it returns {@link
* KeyMayExist.KeyMayExistEnum#kExistsWithoutValue}. The choice not to return a value which might
* exist is at the discretion of the implementation; the only guarantee is that {@link
* KeyMayExist.KeyMayExistEnum#kNotExist} is an assurance that the key does not exist.
*
* @param readOptions the {@link ReadOptions} to use when reading the key/value
* @param key bytebuffer containing the value of the key
* @param value bytebuffer which will receive a value if the key exists and a value is known
* @return a {@link KeyMayExist} object reporting if key may exist and if a value is provided
*/
public KeyMayExist keyMayExist(
final ReadOptions readOptions, final ByteBuffer key, final ByteBuffer value) {
return keyMayExist(null, readOptions, key, value);
}
/**
* If the key definitely does not exist in the database, then this method
* returns false, otherwise it returns true if the key might exist.
* That is to say that this method is probabilistic and may return false
* positives, but never a false negative.
*
* @param columnFamilyHandle the {@link ColumnFamilyHandle} to look for the key in
* @param readOptions the {@link ReadOptions} to use when reading the key/value
* @param key bytebuffer containing the value of the key
* @return false if the key definitely does not exist in the database,
* otherwise true.
*/
public boolean keyMayExist(final ColumnFamilyHandle columnFamilyHandle,
final ReadOptions readOptions, final ByteBuffer key) {
assert key != null : "key ByteBuffer parameter cannot be null";
assert key.isDirect() : "key parameter must be a direct ByteBuffer";
final boolean result = keyMayExistDirect(nativeHandle_,
columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
readOptions == null ? 0 : readOptions.nativeHandle_, key, key.position(), key.limit());
key.position(key.limit());
return result;
}
/**
* If the key definitely does not exist in the database, then this method
* returns {@link KeyMayExist.KeyMayExistEnum#kNotExist},
* otherwise if it can with best effort retreive the value, it returns {@link
* KeyMayExist.KeyMayExistEnum#kExistsWithValue} otherwise it returns {@link
* KeyMayExist.KeyMayExistEnum#kExistsWithoutValue}. The choice not to return a value which might
* exist is at the discretion of the implementation; the only guarantee is that {@link
* KeyMayExist.KeyMayExistEnum#kNotExist} is an assurance that the key does not exist.
*
* @param columnFamilyHandle the {@link ColumnFamilyHandle} to look for the key in
* @param readOptions the {@link ReadOptions} to use when reading the key/value
* @param key bytebuffer containing the value of the key
* @param value bytebuffer which will receive a value if the key exists and a value is known
* @return a {@link KeyMayExist} object reporting if key may exist and if a value is provided
*/
public KeyMayExist keyMayExist(final ColumnFamilyHandle columnFamilyHandle,
final ReadOptions readOptions, final ByteBuffer key, final ByteBuffer value) {
assert key != null : "key ByteBuffer parameter cannot be null";
assert key.isDirect() : "key parameter must be a direct ByteBuffer";
assert value
!= null
: "value ByteBuffer parameter cannot be null. If you do not need the value, use a different version of the method";
assert value.isDirect() : "value parameter must be a direct ByteBuffer";
final int[] result = keyMayExistDirectFoundValue(nativeHandle_,
columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
readOptions == null ? 0 : readOptions.nativeHandle_, key, key.position(), key.remaining(),
value, value.position(), value.remaining());
final int valueLength = result[1];
value.limit(value.position() + Math.min(valueLength, value.remaining()));
key.position(key.limit());
return new KeyMayExist(KeyMayExist.KeyMayExistEnum.values()[result[0]], valueLength);
}
/**
* Return a heap-allocated iterator over the contents of the
* database. The result of newIterator() is initially invalid
* (caller must call one of the Seek methods on the iterator
* before using it).
*
* Caller should close the iterator when it is no longer needed.
* The returned iterator should be closed before this db is closed.
*
*
* @return instance of iterator object.
*/
public RocksIterator newIterator() {
return new RocksIterator(this,
iterator(nativeHandle_, defaultColumnFamilyHandle_.nativeHandle_,
defaultReadOptions_.nativeHandle_));
}
/**
* Return a heap-allocated iterator over the contents of the
* database. The result of newIterator() is initially invalid
* (caller must call one of the Seek methods on the iterator
* before using it).
*
* Caller should close the iterator when it is no longer needed.
* The returned iterator should be closed before this db is closed.
*
*
* @param readOptions {@link ReadOptions} instance.
* @return instance of iterator object.
*/
public RocksIterator newIterator(final ReadOptions readOptions) {
return new RocksIterator(this,
iterator(
nativeHandle_, defaultColumnFamilyHandle_.nativeHandle_, readOptions.nativeHandle_));
}
/**
* Return a heap-allocated iterator over the contents of a
* ColumnFamily. The result of newIterator() is initially invalid
* (caller must call one of the Seek methods on the iterator
* before using it).
*
* Caller should close the iterator when it is no longer needed.
* The returned iterator should be closed before this db is closed.
*
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance
* @return instance of iterator object.
*/
public RocksIterator newIterator(
final ColumnFamilyHandle columnFamilyHandle) {
return new RocksIterator(this,
iterator(
nativeHandle_, columnFamilyHandle.nativeHandle_, defaultReadOptions_.nativeHandle_));
}
/**
* Return a heap-allocated iterator over the contents of a
* ColumnFamily. The result of newIterator() is initially invalid
* (caller must call one of the Seek methods on the iterator
* before using it).
*
* Caller should close the iterator when it is no longer needed.
* The returned iterator should be closed before this db is closed.
*
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance
* @param readOptions {@link ReadOptions} instance.
* @return instance of iterator object.
*/
public RocksIterator newIterator(final ColumnFamilyHandle columnFamilyHandle,
final ReadOptions readOptions) {
return new RocksIterator(
this, iterator(nativeHandle_, columnFamilyHandle.nativeHandle_, readOptions.nativeHandle_));
}
/**
* Returns iterators from a consistent database state across multiple
* column families. Iterators are heap allocated and need to be deleted
* before the db is deleted
*
* @param columnFamilyHandleList {@link java.util.List} containing
* {@link org.forstdb.ColumnFamilyHandle} instances.
* @return {@link java.util.List} containing {@link org.forstdb.RocksIterator}
* instances
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public List newIterators(
final List columnFamilyHandleList)
throws RocksDBException {
return newIterators(columnFamilyHandleList, new ReadOptions());
}
/**
* Returns iterators from a consistent database state across multiple
* column families. Iterators are heap allocated and need to be deleted
* before the db is deleted
*
* @param columnFamilyHandleList {@link java.util.List} containing
* {@link org.forstdb.ColumnFamilyHandle} instances.
* @param readOptions {@link ReadOptions} instance.
* @return {@link java.util.List} containing {@link org.forstdb.RocksIterator}
* instances
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public List newIterators(
final List columnFamilyHandleList,
final ReadOptions readOptions) throws RocksDBException {
final long[] columnFamilyHandles = new long[columnFamilyHandleList.size()];
for (int i = 0; i < columnFamilyHandleList.size(); i++) {
columnFamilyHandles[i] = columnFamilyHandleList.get(i).nativeHandle_;
}
final long[] iteratorRefs = iterators(nativeHandle_, columnFamilyHandles,
readOptions.nativeHandle_);
final List iterators = new ArrayList<>(
columnFamilyHandleList.size());
for (int i=0; iReturn a handle to the current DB state. Iterators created with
* this handle will all observe a stable snapshot of the current DB
* state. The caller must call ReleaseSnapshot(result) when the
* snapshot is no longer needed.
*
* nullptr will be returned if the DB fails to take a snapshot or does
* not support snapshot.
*
* @return Snapshot {@link Snapshot} instance
*/
public Snapshot getSnapshot() {
final long snapshotHandle = getSnapshot(nativeHandle_);
if (snapshotHandle != 0) {
return new Snapshot(snapshotHandle);
}
return null;
}
/**
* Release a previously acquired snapshot.
*
* The caller must not use "snapshot" after this call.
*
* @param snapshot {@link Snapshot} instance
*/
public void releaseSnapshot(final Snapshot snapshot) {
if (snapshot != null) {
releaseSnapshot(nativeHandle_, snapshot.nativeHandle_);
}
}
/**
* DB implements can export properties about their state
* via this method on a per column family level.
*
*
If {@code property} is a valid property understood by this DB
* implementation, fills {@code value} with its current value and
* returns true. Otherwise returns false.
*
* Valid property names include:
*
* - "rocksdb.num-files-at-level<N>" - return the number of files at
* level <N>, where <N> is an ASCII representation of a level
* number (e.g. "0").
* - "rocksdb.stats" - returns a multi-line string that describes statistics
* about the internal operation of the DB.
* - "rocksdb.sstables" - returns a multi-line string that describes all
* of the sstables that make up the db contents.
*
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance, or null for the default column family.
* @param property to be fetched. See above for examples
* @return property value
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public String getProperty(
/* @Nullable */ final ColumnFamilyHandle columnFamilyHandle,
final String property) throws RocksDBException {
return getProperty(nativeHandle_,
columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
property, property.length());
}
/**
* DB implementations can export properties about their state
* via this method. If "property" is a valid property understood by this
* DB implementation, fills "*value" with its current value and returns
* true. Otherwise returns false.
*
* Valid property names include:
*
* - "rocksdb.num-files-at-level<N>" - return the number of files at
* level <N>, where <N> is an ASCII representation of a level
* number (e.g. "0").
* - "rocksdb.stats" - returns a multi-line string that describes statistics
* about the internal operation of the DB.
* - "rocksdb.sstables" - returns a multi-line string that describes all
* of the sstables that make up the db contents.
*
*
* @param property to be fetched. See above for examples
* @return property value
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public String getProperty(final String property) throws RocksDBException {
return getProperty(null, property);
}
/**
* Gets a property map.
*
* @param property to be fetched.
*
* @return the property map
*
* @throws RocksDBException if an error happens in the underlying native code.
*/
public Map getMapProperty(final String property)
throws RocksDBException {
return getMapProperty(null, property);
}
/**
* Gets a property map.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance, or null for the default column family.
* @param property to be fetched.
*
* @return the property map
*
* @throws RocksDBException if an error happens in the underlying native code.
*/
public Map getMapProperty(
/* @Nullable */ final ColumnFamilyHandle columnFamilyHandle,
final String property) throws RocksDBException {
return getMapProperty(nativeHandle_,
columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
property, property.length());
}
/**
* Similar to GetProperty(), but only works for a subset of properties
* whose return value is a numerical value. Return the value as long.
*
* Note: As the returned property is of type
* {@code uint64_t} on C++ side the returning value can be negative
* because Java supports in Java 7 only signed long values.
*
* Java 7: To mitigate the problem of the non
* existent unsigned long tpye, values should be encapsulated using
* {@link java.math.BigInteger} to reflect the correct value. The correct
* behavior is guaranteed if {@code 2^64} is added to negative values.
*
* Java 8: In Java 8 the value should be treated as
* unsigned long using provided methods of type {@link Long}.
*
* @param property to be fetched.
*
* @return numerical property value.
*
* @throws RocksDBException if an error happens in the underlying native code.
*/
public long getLongProperty(final String property) throws RocksDBException {
return getLongProperty(null, property);
}
/**
* Similar to GetProperty(), but only works for a subset of properties
* whose return value is a numerical value. Return the value as long.
*
* Note: As the returned property is of type
* {@code uint64_t} on C++ side the returning value can be negative
* because Java supports in Java 7 only signed long values.
*
* Java 7: To mitigate the problem of the non
* existent unsigned long tpye, values should be encapsulated using
* {@link java.math.BigInteger} to reflect the correct value. The correct
* behavior is guaranteed if {@code 2^64} is added to negative values.
*
* Java 8: In Java 8 the value should be treated as
* unsigned long using provided methods of type {@link Long}.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance, or null for the default column family
* @param property to be fetched.
*
* @return numerical property value
*
* @throws RocksDBException if an error happens in the underlying native code.
*/
public long getLongProperty(
/* @Nullable */ final ColumnFamilyHandle columnFamilyHandle,
final String property) throws RocksDBException {
return getLongProperty(nativeHandle_,
columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
property, property.length());
}
/**
* Reset internal stats for DB and all column families.
*
* Note this doesn't reset {@link Options#statistics()} as it is not
* owned by DB.
*
* @throws RocksDBException if an error occurs whilst reseting the stats
*/
public void resetStats() throws RocksDBException {
resetStats(nativeHandle_);
}
/**
*
Return sum of the getLongProperty of all the column families
*
* Note: As the returned property is of type
* {@code uint64_t} on C++ side the returning value can be negative
* because Java supports in Java 7 only signed long values.
*
* Java 7: To mitigate the problem of the non
* existent unsigned long tpye, values should be encapsulated using
* {@link java.math.BigInteger} to reflect the correct value. The correct
* behavior is guaranteed if {@code 2^64} is added to negative values.
*
* Java 8: In Java 8 the value should be treated as
* unsigned long using provided methods of type {@link Long}.
*
* @param property to be fetched.
*
* @return numerical property value
*
* @throws RocksDBException if an error happens in the underlying native code.
*/
public long getAggregatedLongProperty(final String property)
throws RocksDBException {
return getAggregatedLongProperty(nativeHandle_, property,
property.length());
}
/**
* Get the approximate file system space used by keys in each range.
*
* Note that the returned sizes measure file system space usage, so
* if the user data compresses by a factor of ten, the returned
* sizes will be one-tenth the size of the corresponding user data size.
*
* If {@code sizeApproximationFlags} defines whether the returned size
* should include the recently written data in the mem-tables (if
* the mem-table type supports it), data serialized to disk, or both.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance, or null for the default column family
* @param ranges the ranges over which to approximate sizes
* @param sizeApproximationFlags flags to determine what to include in the
* approximation.
*
* @return the sizes
*/
public long[] getApproximateSizes(
/*@Nullable*/ final ColumnFamilyHandle columnFamilyHandle,
final List ranges,
final SizeApproximationFlag... sizeApproximationFlags) {
byte flags = 0x0;
for (final SizeApproximationFlag sizeApproximationFlag
: sizeApproximationFlags) {
flags |= sizeApproximationFlag.getValue();
}
return getApproximateSizes(nativeHandle_,
columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
toRangeSliceHandles(ranges), flags);
}
/**
* Get the approximate file system space used by keys in each range for
* the default column family.
*
* Note that the returned sizes measure file system space usage, so
* if the user data compresses by a factor of ten, the returned
* sizes will be one-tenth the size of the corresponding user data size.
*
* If {@code sizeApproximationFlags} defines whether the returned size
* should include the recently written data in the mem-tables (if
* the mem-table type supports it), data serialized to disk, or both.
*
* @param ranges the ranges over which to approximate sizes
* @param sizeApproximationFlags flags to determine what to include in the
* approximation.
*
* @return the sizes.
*/
public long[] getApproximateSizes(final List ranges,
final SizeApproximationFlag... sizeApproximationFlags) {
return getApproximateSizes(null, ranges, sizeApproximationFlags);
}
public static class CountAndSize {
public final long count;
public final long size;
public CountAndSize(final long count, final long size) {
this.count = count;
this.size = size;
}
}
/**
* This method is similar to
* {@link #getApproximateSizes(ColumnFamilyHandle, List, SizeApproximationFlag...)},
* except that it returns approximate number of records and size in memtables.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance, or null for the default column family
* @param range the ranges over which to get the memtable stats
*
* @return the count and size for the range
*/
public CountAndSize getApproximateMemTableStats(
/*@Nullable*/ final ColumnFamilyHandle columnFamilyHandle,
final Range range) {
final long[] result = getApproximateMemTableStats(nativeHandle_,
columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
range.start.getNativeHandle(),
range.limit.getNativeHandle());
return new CountAndSize(result[0], result[1]);
}
/**
* This method is similar to
* {@link #getApproximateSizes(ColumnFamilyHandle, List, SizeApproximationFlag...)},
* except that it returns approximate number of records and size in memtables.
*
* @param range the ranges over which to get the memtable stats
*
* @return the count and size for the range
*/
public CountAndSize getApproximateMemTableStats(
final Range range) {
return getApproximateMemTableStats(null, range);
}
/**
* Range compaction of database.
* Note: After the database has been compacted,
* all data will have been pushed down to the last level containing
* any data.
*
* See also
*
* - {@link #compactRange(byte[], byte[])}
*
*
* @throws RocksDBException thrown if an error occurs within the native
* part of the library.
*/
public void compactRange() throws RocksDBException {
compactRange(null);
}
/**
* Range compaction of column family.
* Note: After the database has been compacted,
* all data will have been pushed down to the last level containing
* any data.
*
* See also
*
* -
* {@link #compactRange(ColumnFamilyHandle, byte[], byte[])}
*
*
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance, or null for the default column family.
*
* @throws RocksDBException thrown if an error occurs within the native
* part of the library.
*/
public void compactRange(
/* @Nullable */ final ColumnFamilyHandle columnFamilyHandle)
throws RocksDBException {
compactRange(nativeHandle_, null, -1, null, -1, 0,
columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_);
}
/**
* Range compaction of database.
* Note: After the database has been compacted,
* all data will have been pushed down to the last level containing
* any data.
*
* See also
*
* - {@link #compactRange()}
*
*
* @param begin start of key range (included in range)
* @param end end of key range (excluded from range)
*
* @throws RocksDBException thrown if an error occurs within the native
* part of the library.
*/
public void compactRange(final byte[] begin, final byte[] end)
throws RocksDBException {
compactRange(null, begin, end);
}
/**
* Range compaction of column family.
* Note: After the database has been compacted,
* all data will have been pushed down to the last level containing
* any data.
*
* See also
*
* - {@link #compactRange(ColumnFamilyHandle)}
*
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance, or null for the default column family.
* @param begin start of key range (included in range)
* @param end end of key range (excluded from range)
*
* @throws RocksDBException thrown if an error occurs within the native
* part of the library.
*/
public void compactRange(
/* @Nullable */ final ColumnFamilyHandle columnFamilyHandle,
final byte[] begin, final byte[] end) throws RocksDBException {
compactRange(nativeHandle_,
begin, begin == null ? -1 : begin.length,
end, end == null ? -1 : end.length,
0, columnFamilyHandle == null ? 0: columnFamilyHandle.nativeHandle_);
}
/**
* Range compaction of column family.
* Note: After the database has been compacted,
* all data will have been pushed down to the last level containing
* any data.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle} instance.
* @param begin start of key range (included in range)
* @param end end of key range (excluded from range)
* @param compactRangeOptions options for the compaction
*
* @throws RocksDBException thrown if an error occurs within the native
* part of the library.
*/
public void compactRange(
/* @Nullable */ final ColumnFamilyHandle columnFamilyHandle,
final byte[] begin, final byte[] end,
final CompactRangeOptions compactRangeOptions) throws RocksDBException {
compactRange(nativeHandle_,
begin, begin == null ? -1 : begin.length,
end, end == null ? -1 : end.length,
compactRangeOptions.nativeHandle_,
columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_);
}
/**
* ClipColumnFamily() will clip the entries in the CF according to the range
* [begin_key, end_key). Returns OK on success, and a non-OK status on error.
* Any entries outside this range will be completely deleted (including
* tombstones).
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle} instance
* @param beginKey First key to clip within database (inclusive)
* @param endKey Last key to clip within database (exclusive)
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void clipColumnFamily(final ColumnFamilyHandle columnFamilyHandle, final byte[] beginKey,
final byte[] endKey) throws RocksDBException {
clipColumnFamily(nativeHandle_,
columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_, beginKey, 0,
beginKey.length, endKey, 0, endKey.length);
}
/**
* Change the options for the column family handle.
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance, or null for the default column family.
* @param mutableColumnFamilyOptions the options.
*
* @throws RocksDBException if an error occurs whilst setting the options
*/
public void setOptions(
/* @Nullable */final ColumnFamilyHandle columnFamilyHandle,
final MutableColumnFamilyOptions mutableColumnFamilyOptions)
throws RocksDBException {
setOptions(nativeHandle_, columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
mutableColumnFamilyOptions.getKeys(), mutableColumnFamilyOptions.getValues());
}
/**
* Set performance level for rocksdb performance measurement.
* @param level
* @throws IllegalArgumentException for UNINITIALIZED and OUT_OF_BOUNDS values
* as they can't be used for settings.
*/
public void setPerfLevel(final PerfLevel level) {
if (level == PerfLevel.UNINITIALIZED) {
throw new IllegalArgumentException("Unable to set UNINITIALIZED level");
} else if (level == PerfLevel.OUT_OF_BOUNDS) {
throw new IllegalArgumentException("Unable to set OUT_OF_BOUNDS level");
} else {
setPerfLevel(level.getValue());
}
}
/**
* Return current performance level measurement settings.
* @return
*/
public PerfLevel getPerfLevel() {
byte level = getPerfLevelNative();
return PerfLevel.getPerfLevel(level);
}
/**
* Return perf context bound to this thread.
* @return
*/
public PerfContext getPerfContext() {
long native_handle = getPerfContextNative();
return new PerfContext(native_handle);
}
/**
* Get the options for the column family handle
*
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle}
* instance, or null for the default column family.
*
* @return the options parsed from the options string return by RocksDB
*
* @throws RocksDBException if an error occurs while getting the options string, or parsing the
* resulting options string into options
*/
public MutableColumnFamilyOptions.MutableColumnFamilyOptionsBuilder getOptions(
/* @Nullable */ final ColumnFamilyHandle columnFamilyHandle) throws RocksDBException {
final String optionsString = getOptions(
nativeHandle_, columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_);
return MutableColumnFamilyOptions.parse(optionsString, true);
}
/**
* Default column family options
*
* @return the options parsed from the options string return by RocksDB
*
* @throws RocksDBException if an error occurs while getting the options string, or parsing the
* resulting options string into options
*/
public MutableColumnFamilyOptions.MutableColumnFamilyOptionsBuilder getOptions()
throws RocksDBException {
return getOptions(null);
}
/**
* Get the database options
*
* @return the DB options parsed from the options string return by RocksDB
*
* @throws RocksDBException if an error occurs while getting the options string, or parsing the
* resulting options string into options
*/
public MutableDBOptions.MutableDBOptionsBuilder getDBOptions() throws RocksDBException {
final String optionsString = getDBOptions(nativeHandle_);
return MutableDBOptions.parse(optionsString, true);
}
/**
* Change the options for the default column family handle.
*
* @param mutableColumnFamilyOptions the options.
*
* @throws RocksDBException if an error occurs whilst setting the options
*/
public void setOptions(
final MutableColumnFamilyOptions mutableColumnFamilyOptions)
throws RocksDBException {
setOptions(null, mutableColumnFamilyOptions);
}
/**
* Set the options for the column family handle.
*
* @param mutableDBoptions the options.
*
* @throws RocksDBException if an error occurs whilst setting the options
*/
public void setDBOptions(final MutableDBOptions mutableDBoptions)
throws RocksDBException {
setDBOptions(nativeHandle_,
mutableDBoptions.getKeys(),
mutableDBoptions.getValues());
}
/**
* Takes a list of files specified by file names and
* compacts them to the specified level.
*
* Note that the behavior is different from
* {@link #compactRange(ColumnFamilyHandle, byte[], byte[])}
* in that CompactFiles() performs the compaction job using the CURRENT
* thread.
*
* @param compactionOptions compaction options
* @param inputFileNames the name of the files to compact
* @param outputLevel the level to which they should be compacted
* @param outputPathId the id of the output path, or -1
* @param compactionJobInfo the compaction job info, this parameter
* will be updated with the info from compacting the files,
* can just be null if you don't need it.
*
* @return the list of compacted files
*
* @throws RocksDBException if an error occurs during compaction
*/
public List compactFiles(
final CompactionOptions compactionOptions,
final List inputFileNames,
final int outputLevel,
final int outputPathId,
/* @Nullable */ final CompactionJobInfo compactionJobInfo)
throws RocksDBException {
return compactFiles(compactionOptions, null, inputFileNames, outputLevel,
outputPathId, compactionJobInfo);
}
/**
* Takes a list of files specified by file names and
* compacts them to the specified level.
*
* Note that the behavior is different from
* {@link #compactRange(ColumnFamilyHandle, byte[], byte[])}
* in that CompactFiles() performs the compaction job using the CURRENT
* thread.
*
* @param compactionOptions compaction options
* @param columnFamilyHandle columnFamilyHandle, or null for the
* default column family
* @param inputFileNames the name of the files to compact
* @param outputLevel the level to which they should be compacted
* @param outputPathId the id of the output path, or -1
* @param compactionJobInfo the compaction job info, this parameter
* will be updated with the info from compacting the files,
* can just be null if you don't need it.
*
* @return the list of compacted files
*
* @throws RocksDBException if an error occurs during compaction
*/
public List compactFiles(
final CompactionOptions compactionOptions,
/* @Nullable */ final ColumnFamilyHandle columnFamilyHandle,
final List inputFileNames,
final int outputLevel,
final int outputPathId,
/* @Nullable */ final CompactionJobInfo compactionJobInfo)
throws RocksDBException {
return Arrays.asList(compactFiles(nativeHandle_, compactionOptions.nativeHandle_,
columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
inputFileNames.toArray(new String[0]),
outputLevel,
outputPathId,
compactionJobInfo == null ? 0 : compactionJobInfo.nativeHandle_));
}
/**
* This function will cancel all currently running background processes.
*
* @param wait if true, wait for all background work to be cancelled before
* returning.
*
*/
public void cancelAllBackgroundWork(final boolean wait) {
cancelAllBackgroundWork(nativeHandle_, wait);
}
/**
* This function will wait until all currently running background processes
* finish. After it returns, no background process will be run until
* {@link #continueBackgroundWork()} is called
*
* @throws RocksDBException if an error occurs when pausing background work
*/
public void pauseBackgroundWork() throws RocksDBException {
pauseBackgroundWork(nativeHandle_);
}
/**
* Resumes background work which was suspended by
* previously calling {@link #pauseBackgroundWork()}
*
* @throws RocksDBException if an error occurs when resuming background work
*/
public void continueBackgroundWork() throws RocksDBException {
continueBackgroundWork(nativeHandle_);
}
/**
* Enable automatic compactions for the given column
* families if they were previously disabled.
*
* The function will first set the
* {@link ColumnFamilyOptions#disableAutoCompactions()} option for each
* column family to false, after which it will schedule a flush/compaction.
*
* NOTE: Setting disableAutoCompactions to 'false' through
* {@link #setOptions(ColumnFamilyHandle, MutableColumnFamilyOptions)}
* does NOT schedule a flush/compaction afterwards, and only changes the
* parameter itself within the column family option.
*
* @param columnFamilyHandles the column family handles
*
* @throws RocksDBException if an error occurs whilst enabling auto-compaction
*/
public void enableAutoCompaction(
final List columnFamilyHandles)
throws RocksDBException {
enableAutoCompaction(nativeHandle_,
toNativeHandleList(columnFamilyHandles));
}
/**
* Number of levels used for this DB.
*
* @return the number of levels
*/
public int numberLevels() {
return numberLevels(null);
}
/**
* Number of levels used for a column family in this DB.
*
* @param columnFamilyHandle the column family handle, or null
* for the default column family
*
* @return the number of levels
*/
public int numberLevels(/* @Nullable */final ColumnFamilyHandle columnFamilyHandle) {
return numberLevels(nativeHandle_,
columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_);
}
/**
* Maximum level to which a new compacted memtable is pushed if it
* does not create overlap.
*
* @return the maximum level
*/
public int maxMemCompactionLevel() {
return maxMemCompactionLevel(null);
}
/**
* Maximum level to which a new compacted memtable is pushed if it
* does not create overlap.
*
* @param columnFamilyHandle the column family handle
*
* @return the maximum level
*/
public int maxMemCompactionLevel(
/* @Nullable */ final ColumnFamilyHandle columnFamilyHandle) {
return maxMemCompactionLevel(nativeHandle_,
columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_);
}
/**
* Number of files in level-0 that would stop writes.
*
* @return the number of files
*/
public int level0StopWriteTrigger() {
return level0StopWriteTrigger(null);
}
/**
* Number of files in level-0 that would stop writes.
*
* @param columnFamilyHandle the column family handle
*
* @return the number of files
*/
public int level0StopWriteTrigger(
/* @Nullable */final ColumnFamilyHandle columnFamilyHandle) {
return level0StopWriteTrigger(nativeHandle_,
columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_);
}
/**
* Get DB name -- the exact same name that was provided as an argument to
* as path to {@link #open(Options, String)}.
*
* @return the DB name
*/
public String getName() {
return getName(nativeHandle_);
}
/**
* Get the Env object from the DB
*
* @return the env
*/
public Env getEnv() {
final long envHandle = getEnv(nativeHandle_);
if (envHandle == Env.getDefault().nativeHandle_) {
return Env.getDefault();
} else {
final Env env = new RocksEnv(envHandle);
env.disOwnNativeHandle(); // we do not own the Env!
return env;
}
}
/**
* Flush all memory table data.
*
* Note: it must be ensured that the FlushOptions instance
* is not GC'ed before this method finishes. If the wait parameter is
* set to false, flush processing is asynchronous.
*
* @param flushOptions {@link org.forstdb.FlushOptions} instance.
* @throws RocksDBException thrown if an error occurs within the native
* part of the library.
*/
public void flush(final FlushOptions flushOptions)
throws RocksDBException {
flush(flushOptions, Collections.singletonList(getDefaultColumnFamily()));
}
/**
* Flush all memory table data.
*
* Note: it must be ensured that the FlushOptions instance
* is not GC'ed before this method finishes. If the wait parameter is
* set to false, flush processing is asynchronous.
*
* @param flushOptions {@link org.forstdb.FlushOptions} instance.
* @param columnFamilyHandle {@link org.forstdb.ColumnFamilyHandle} instance.
* @throws RocksDBException thrown if an error occurs within the native
* part of the library.
*/
public void flush(final FlushOptions flushOptions,
/* @Nullable */ final ColumnFamilyHandle columnFamilyHandle)
throws RocksDBException {
flush(flushOptions,
columnFamilyHandle == null ? null : Collections.singletonList(columnFamilyHandle));
}
/**
* Flushes multiple column families.
*
* If atomic flush is not enabled, this is equivalent to calling
* {@link #flush(FlushOptions, ColumnFamilyHandle)} multiple times.
*
* If atomic flush is enabled, this will flush all column families
* specified up to the latest sequence number at the time when flush is
* requested.
*
* @param flushOptions {@link org.forstdb.FlushOptions} instance.
* @param columnFamilyHandles column family handles.
* @throws RocksDBException thrown if an error occurs within the native
* part of the library.
*/
public void flush(final FlushOptions flushOptions,
/* @Nullable */ final List columnFamilyHandles)
throws RocksDBException {
flush(nativeHandle_, flushOptions.nativeHandle_,
toNativeHandleList(columnFamilyHandles));
}
/**
* Flush the WAL memory buffer to the file. If {@code sync} is true,
* it calls {@link #syncWal()} afterwards.
*
* @param sync true to also fsync to disk.
*
* @throws RocksDBException if an error occurs whilst flushing
*/
public void flushWal(final boolean sync) throws RocksDBException {
flushWal(nativeHandle_, sync);
}
/**
* Sync the WAL.
*
* Note that {@link #write(WriteOptions, WriteBatch)} followed by
* {@code #syncWal()} is not exactly the same as
* {@link #write(WriteOptions, WriteBatch)} with
* {@link WriteOptions#sync()} set to true; In the latter case the changes
* won't be visible until the sync is done.
*
* Currently only works if {@link Options#allowMmapWrites()} is set to false.
*
* @throws RocksDBException if an error occurs whilst syncing
*/
public void syncWal() throws RocksDBException {
syncWal(nativeHandle_);
}
/**
*
The sequence number of the most recent transaction.
*
* @return sequence number of the most
* recent transaction.
*/
public long getLatestSequenceNumber() {
return getLatestSequenceNumber(nativeHandle_);
}
/**
* Prevent file deletions. Compactions will continue to occur,
* but no obsolete files will be deleted. Calling this multiple
* times have the same effect as calling it once.
*
* @throws RocksDBException thrown if operation was not performed
* successfully.
*/
public void disableFileDeletions() throws RocksDBException {
disableFileDeletions(nativeHandle_);
}
/**
* Enable deleting obsolete files.
* If force == true, the call to EnableFileDeletions()
* will guarantee that file deletions are enabled after
* the call, even if DisableFileDeletions() was called
* multiple times before.
*
* If force == false, EnableFileDeletions will only
* enable file deletion after it's been called at least
* as many times as DisableFileDeletions(), enabling
* the two methods to be called by two threads
* concurrently without synchronization
* -- i.e., file deletions will be enabled only after both
* threads call EnableFileDeletions()
*
* @param force boolean value described above.
*
* @throws RocksDBException thrown if operation was not performed
* successfully.
*/
public void enableFileDeletions(final boolean force)
throws RocksDBException {
enableFileDeletions(nativeHandle_, force);
}
public static class LiveFiles {
/**
* The valid size of the manifest file. The manifest file is an ever growing
* file, but only the portion specified here is valid for this snapshot.
*/
public final long manifestFileSize;
/**
* The files are relative to the {@link #getName()} and are not
* absolute paths. Despite being relative paths, the file names begin
* with "/".
*/
public final List files;
LiveFiles(final long manifestFileSize, final List files) {
this.manifestFileSize = manifestFileSize;
this.files = files;
}
}
/**
* Retrieve the list of all files in the database after flushing the memtable.
*
* See {@link #getLiveFiles(boolean)}.
*
* @return the live files
*
* @throws RocksDBException if an error occurs whilst retrieving the list
* of live files
*/
public LiveFiles getLiveFiles() throws RocksDBException {
return getLiveFiles(true);
}
/**
* Retrieve the list of all files in the database.
*
* In case you have multiple column families, even if {@code flushMemtable}
* is true, you still need to call {@link #getSortedWalFiles()}
* after {@code #getLiveFiles(boolean)} to compensate for new data that
* arrived to already-flushed column families while other column families
* were flushing.
*
* NOTE: Calling {@code #getLiveFiles(boolean)} followed by
* {@link #getSortedWalFiles()} can generate a lossless backup.
*
* @param flushMemtable set to true to flush before recoding the live
* files. Setting to false is useful when we don't want to wait for flush
* which may have to wait for compaction to complete taking an
* indeterminate time.
*
* @return the live files
*
* @throws RocksDBException if an error occurs whilst retrieving the list
* of live files
*/
public LiveFiles getLiveFiles(final boolean flushMemtable)
throws RocksDBException {
final String[] result = getLiveFiles(nativeHandle_, flushMemtable);
if (result == null) {
return null;
}
final String[] files = Arrays.copyOf(result, result.length - 1);
final long manifestFileSize = Long.parseLong(result[result.length - 1]);
return new LiveFiles(manifestFileSize, Arrays.asList(files));
}
/**
* Retrieve the sorted list of all wal files with earliest file first.
*
* @return the log files
*
* @throws RocksDBException if an error occurs whilst retrieving the list
* of sorted WAL files
*/
public List getSortedWalFiles() throws RocksDBException {
final LogFile[] logFiles = getSortedWalFiles(nativeHandle_);
return Arrays.asList(logFiles);
}
/**
* Returns an iterator that is positioned at a write-batch containing
* seq_number. If the sequence number is non existent, it returns an iterator
* at the first available seq_no after the requested seq_no.
*
* Must set WAL_ttl_seconds or WAL_size_limit_MB to large values to
* use this api, else the WAL files will get
* cleared aggressively and the iterator might keep getting invalid before
* an update is read.
*
* @param sequenceNumber sequence number offset
*
* @return {@link org.forstdb.TransactionLogIterator} instance.
*
* @throws org.forstdb.RocksDBException if iterator cannot be retrieved
* from native-side.
*/
public TransactionLogIterator getUpdatesSince(final long sequenceNumber)
throws RocksDBException {
return new TransactionLogIterator(
getUpdatesSince(nativeHandle_, sequenceNumber));
}
/**
* Delete the file name from the db directory and update the internal state to
* reflect that. Supports deletion of sst and log files only. 'name' must be
* path relative to the db directory. eg. 000001.sst, /archive/000003.log
*
* @param name the file name
*
* @throws RocksDBException if an error occurs whilst deleting the file
*/
public void deleteFile(final String name) throws RocksDBException {
deleteFile(nativeHandle_, name);
}
/**
* Gets a list of all table files metadata.
*
* @return table files metadata.
*/
public List getLiveFilesMetaData() {
return Arrays.asList(getLiveFilesMetaData(nativeHandle_));
}
/**
* Obtains the meta data of the specified column family of the DB.
*
* @param columnFamilyHandle the column family
*
* @return the column family metadata
*/
public ColumnFamilyMetaData getColumnFamilyMetaData(
/* @Nullable */ final ColumnFamilyHandle columnFamilyHandle) {
return getColumnFamilyMetaData(nativeHandle_,
columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_);
}
/**
* Obtains the meta data of the default column family of the DB.
*
* @return the column family metadata
*/
public ColumnFamilyMetaData getColumnFamilyMetaData() {
return getColumnFamilyMetaData(null);
}
/**
* ingestExternalFile will load a list of external SST files (1) into the DB
* We will try to find the lowest possible level that the file can fit in, and
* ingest the file into this level (2). A file that have a key range that
* overlap with the memtable key range will require us to Flush the memtable
* first before ingesting the file.
*
* (1) External SST files can be created using {@link SstFileWriter}
* (2) We will try to ingest the files to the lowest possible level
* even if the file compression doesn't match the level compression
*
* @param filePathList The list of files to ingest
* @param ingestExternalFileOptions the options for the ingestion
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void ingestExternalFile(final List filePathList,
final IngestExternalFileOptions ingestExternalFileOptions)
throws RocksDBException {
ingestExternalFile(nativeHandle_, getDefaultColumnFamily().nativeHandle_,
filePathList.toArray(new String[0]),
filePathList.size(), ingestExternalFileOptions.nativeHandle_);
}
/**
* ingestExternalFile will load a list of external SST files (1) into the DB
* We will try to find the lowest possible level that the file can fit in, and
* ingest the file into this level (2). A file that have a key range that
* overlap with the memtable key range will require us to Flush the memtable
* first before ingesting the file.
*
* (1) External SST files can be created using {@link SstFileWriter}
* (2) We will try to ingest the files to the lowest possible level
* even if the file compression doesn't match the level compression
*
* @param columnFamilyHandle The column family for the ingested files
* @param filePathList The list of files to ingest
* @param ingestExternalFileOptions the options for the ingestion
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void ingestExternalFile(final ColumnFamilyHandle columnFamilyHandle,
final List filePathList,
final IngestExternalFileOptions ingestExternalFileOptions)
throws RocksDBException {
ingestExternalFile(nativeHandle_, columnFamilyHandle.nativeHandle_,
filePathList.toArray(new String[0]),
filePathList.size(), ingestExternalFileOptions.nativeHandle_);
}
/**
* Verify checksum
*
* @throws RocksDBException if the checksum is not valid
*/
public void verifyChecksum() throws RocksDBException {
verifyChecksum(nativeHandle_);
}
/**
* Gets the handle for the default column family
*
* @return The handle of the default column family
*/
public ColumnFamilyHandle getDefaultColumnFamily() {
return defaultColumnFamilyHandle_;
}
/**
* Create a handle for the default CF on open
*
* @return the default family handle
*/
protected ColumnFamilyHandle makeDefaultColumnFamilyHandle() {
final ColumnFamilyHandle cfHandle =
new ColumnFamilyHandle(this, getDefaultColumnFamily(nativeHandle_));
cfHandle.disOwnNativeHandle();
return cfHandle;
}
/**
* Get the properties of all tables.
*
* @param columnFamilyHandle the column family handle, or null for the default
* column family.
*
* @return the properties
*
* @throws RocksDBException if an error occurs whilst getting the properties
*/
public Map getPropertiesOfAllTables(
/* @Nullable */final ColumnFamilyHandle columnFamilyHandle)
throws RocksDBException {
return getPropertiesOfAllTables(nativeHandle_,
columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_);
}
/**
* Get the properties of all tables in the default column family.
*
* @return the properties
*
* @throws RocksDBException if an error occurs whilst getting the properties
*/
public Map getPropertiesOfAllTables()
throws RocksDBException {
return getPropertiesOfAllTables(null);
}
/**
* Get the properties of tables in range.
*
* @param columnFamilyHandle the column family handle, or null for the default
* column family.
* @param ranges the ranges over which to get the table properties
*
* @return the properties
*
* @throws RocksDBException if an error occurs whilst getting the properties
*/
public Map getPropertiesOfTablesInRange(
/* @Nullable */final ColumnFamilyHandle columnFamilyHandle,
final List ranges) throws RocksDBException {
return getPropertiesOfTablesInRange(nativeHandle_,
columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
toRangeSliceHandles(ranges));
}
/**
* Get the properties of tables in range for the default column family.
*
* @param ranges the ranges over which to get the table properties
*
* @return the properties
*
* @throws RocksDBException if an error occurs whilst getting the properties
*/
public Map getPropertiesOfTablesInRange(
final List ranges) throws RocksDBException {
return getPropertiesOfTablesInRange(null, ranges);
}
/**
* Suggest the range to compact.
*
* @param columnFamilyHandle the column family handle, or null for the default
* column family.
*
* @return the suggested range.
*
* @throws RocksDBException if an error occurs whilst suggesting the range
*/
public Range suggestCompactRange(
/* @Nullable */final ColumnFamilyHandle columnFamilyHandle)
throws RocksDBException {
final long[] rangeSliceHandles = suggestCompactRange(nativeHandle_,
columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_);
return new Range(new Slice(rangeSliceHandles[0]),
new Slice(rangeSliceHandles[1]));
}
/**
* Suggest the range to compact for the default column family.
*
* @return the suggested range.
*
* @throws RocksDBException if an error occurs whilst suggesting the range
*/
public Range suggestCompactRange()
throws RocksDBException {
return suggestCompactRange(null);
}
/**
* Promote L0.
*
* @param columnFamilyHandle the column family handle,
* or null for the default column family.
* @param targetLevel the target level for L0
*
* @throws RocksDBException if an error occurs whilst promoting L0
*/
public void promoteL0(
/* @Nullable */final ColumnFamilyHandle columnFamilyHandle,
final int targetLevel) throws RocksDBException {
promoteL0(nativeHandle_,
columnFamilyHandle == null ? 0 : columnFamilyHandle.nativeHandle_,
targetLevel);
}
/**
* Promote L0 for the default column family.
*
* @param targetLevel the target level for L0
*
* @throws RocksDBException if an error occurs whilst promoting L0
*/
public void promoteL0(final int targetLevel)
throws RocksDBException {
promoteL0(null, targetLevel);
}
/**
* Trace DB operations.
*
* Use {@link #endTrace()} to stop tracing.
*
* @param traceOptions the options
* @param traceWriter the trace writer
*
* @throws RocksDBException if an error occurs whilst starting the trace
*/
public void startTrace(final TraceOptions traceOptions,
final AbstractTraceWriter traceWriter) throws RocksDBException {
startTrace(nativeHandle_, traceOptions.getMaxTraceFileSize(),
traceWriter.nativeHandle_);
/*
* NOTE: {@link #startTrace(long, long, long) transfers the ownership
* from Java to C++, so we must disown the native handle here.
*/
traceWriter.disOwnNativeHandle();
}
/**
* Stop tracing DB operations.
*
* See {@link #startTrace(TraceOptions, AbstractTraceWriter)}
*
* @throws RocksDBException if an error occurs whilst ending the trace
*/
public void endTrace() throws RocksDBException {
endTrace(nativeHandle_);
}
/**
* Make the secondary instance catch up with the primary by tailing and
* replaying the MANIFEST and WAL of the primary.
* Column families created by the primary after the secondary instance starts
* will be ignored unless the secondary instance closes and restarts with the
* newly created column families.
* Column families that exist before secondary instance starts and dropped by
* the primary afterwards will be marked as dropped. However, as long as the
* secondary instance does not delete the corresponding column family
* handles, the data of the column family is still accessible to the
* secondary.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void tryCatchUpWithPrimary() throws RocksDBException {
tryCatchUpWithPrimary(nativeHandle_);
}
/**
* Delete files in multiple ranges at once.
* Delete files in a lot of ranges one at a time can be slow, use this API for
* better performance in that case.
*
* @param columnFamily - The column family for operation (null for default)
* @param includeEnd - Whether ranges should include end
* @param ranges - pairs of ranges (from1, to1, from2, to2, ...)
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void deleteFilesInRanges(final ColumnFamilyHandle columnFamily, final List ranges,
final boolean includeEnd) throws RocksDBException {
if (ranges.isEmpty()) {
return;
}
if ((ranges.size() % 2) != 0) {
throw new IllegalArgumentException("Ranges size needs to be multiple of 2 "
+ "(from1, to1, from2, to2, ...), but is " + ranges.size());
}
final byte[][] rangesArray = ranges.toArray(new byte[ranges.size()][]);
deleteFilesInRanges(nativeHandle_, columnFamily == null ? 0 : columnFamily.nativeHandle_,
rangesArray, includeEnd);
}
/**
* Static method to destroy the contents of the specified database.
* Be very careful using this method.
*
* @param path the path to the Rocksdb database.
* @param options {@link org.forstdb.Options} instance.
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public static void destroyDB(final String path, final Options options)
throws RocksDBException {
destroyDB(path, options.nativeHandle_);
}
private /* @Nullable */ long[] toNativeHandleList(
/* @Nullable */ final List extends RocksObject> objectList) {
if (objectList == null) {
return new long[0];
}
final int len = objectList.size();
final long[] handleList = new long[len];
for (int i = 0; i < len; i++) {
handleList[i] = objectList.get(i).nativeHandle_;
}
return handleList;
}
@SuppressWarnings({"PMD.ForLoopVariableCount", "PMD.AvoidReassigningLoopVariables"})
private static long[] toRangeSliceHandles(final List ranges) {
final long[] rangeSliceHandles = new long[ranges.size() * 2];
for (int i = 0, j = 0; i < ranges.size(); i++) {
final Range range = ranges.get(i);
rangeSliceHandles[j++] = range.start.getNativeHandle();
rangeSliceHandles[j++] = range.limit.getNativeHandle();
}
return rangeSliceHandles;
}
protected void storeOptionsInstance(final DBOptionsInterface> options) {
options_ = options;
}
protected void storeDefaultColumnFamilyHandle(ColumnFamilyHandle columnFamilyHandle) {
defaultColumnFamilyHandle_ = columnFamilyHandle;
}
private static void checkBounds(int offset, int len, int size) {
if ((offset | len | (offset + len) | (size - (offset + len))) < 0) {
throw new IndexOutOfBoundsException(String.format("offset(%d), len(%d), size(%d)", offset, len, size));
}
}
// native methods
private static native long open(final long optionsHandle, final String path)
throws RocksDBException;
/**
* @param optionsHandle Native handle pointing to an Options object
* @param path The directory path for the database files
* @param columnFamilyNames An array of column family names
* @param columnFamilyOptions An array of native handles pointing to
* ColumnFamilyOptions objects
*
* @return An array of native handles, [0] is the handle of the RocksDB object
* [1..1+n] are handles of the ColumnFamilyReferences
*
* @throws RocksDBException thrown if the database could not be opened
*/
private static native long[] open(final long optionsHandle, final String path,
final byte[][] columnFamilyNames, final long[] columnFamilyOptions) throws RocksDBException;
private static native long openROnly(final long optionsHandle, final String path,
final boolean errorIfWalFileExists) throws RocksDBException;
/**
* @param optionsHandle Native handle pointing to an Options object
* @param path The directory path for the database files
* @param columnFamilyNames An array of column family names
* @param columnFamilyOptions An array of native handles pointing to
* ColumnFamilyOptions objects
*
* @return An array of native handles, [0] is the handle of the RocksDB object
* [1..1+n] are handles of the ColumnFamilyReferences
*
* @throws RocksDBException thrown if the database could not be opened
*/
private static native long[] openROnly(final long optionsHandle, final String path,
final byte[][] columnFamilyNames, final long[] columnFamilyOptions,
final boolean errorIfWalFileExists) throws RocksDBException;
private static native long openAsSecondary(final long optionsHandle, final String path,
final String secondaryPath) throws RocksDBException;
private static native long[] openAsSecondary(final long optionsHandle, final String path,
final String secondaryPath, final byte[][] columnFamilyNames,
final long[] columnFamilyOptions) throws RocksDBException;
@Override protected native void disposeInternal(final long handle);
private static native void closeDatabase(final long handle) throws RocksDBException;
private static native byte[][] listColumnFamilies(final long optionsHandle, final String path)
throws RocksDBException;
private native long createColumnFamily(final long handle,
final byte[] columnFamilyName, final int columnFamilyNamelen,
final long columnFamilyOptions) throws RocksDBException;
private native long[] createColumnFamilies(final long handle,
final long columnFamilyOptionsHandle, final byte[][] columnFamilyNames)
throws RocksDBException;
private native long[] createColumnFamilies(
final long handle, final long[] columnFamilyOptionsHandles, final byte[][] columnFamilyNames)
throws RocksDBException;
private native long createColumnFamilyWithImport(final long handle, final byte[] columnFamilyName,
final int columnFamilyNamelen, final long columnFamilyOptions,
final long importColumnFamilyOptions, final long[] metadataHandleList)
throws RocksDBException;
private native void dropColumnFamily(
final long handle, final long cfHandle) throws RocksDBException;
private native void dropColumnFamilies(final long handle,
final long[] cfHandles) throws RocksDBException;
private native void put(final long handle, final byte[] key,
final int keyOffset, final int keyLength, final byte[] value,
final int valueOffset, int valueLength) throws RocksDBException;
private native void 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) throws RocksDBException;
private native void 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)
throws RocksDBException;
private native void 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) throws RocksDBException;
private native void delete(final long handle, final byte[] key,
final int keyOffset, final int keyLength) throws RocksDBException;
private native void delete(final long handle, final byte[] key,
final int keyOffset, final int keyLength, final long cfHandle)
throws RocksDBException;
private native void delete(final long handle, final long writeOptHandle,
final byte[] key, final int keyOffset, final int keyLength)
throws RocksDBException;
private native void delete(final long handle, final long writeOptHandle,
final byte[] key, final int keyOffset, final int keyLength,
final long cfHandle) throws RocksDBException;
private native void singleDelete(
final long handle, final byte[] key, final int keyLen)
throws RocksDBException;
private native void singleDelete(
final long handle, final byte[] key, final int keyLen,
final long cfHandle) throws RocksDBException;
private native void singleDelete(
final long handle, final long writeOptHandle, final byte[] key,
final int keyLen) throws RocksDBException;
private native void singleDelete(
final long handle, final long writeOptHandle,
final byte[] key, final int keyLen, final long cfHandle)
throws RocksDBException;
private native void deleteRange(final long handle, final byte[] beginKey,
final int beginKeyOffset, final int beginKeyLength, final byte[] endKey,
final int endKeyOffset, final int endKeyLength) throws RocksDBException;
private native void 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)
throws RocksDBException;
private native void 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)
throws RocksDBException;
private native void 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)
throws RocksDBException;
private native void clipColumnFamily(final long handle, final long cfHandle,
final byte[] beginKey, final int beginKeyOffset, final int beginKeyLength,
final byte[] endKey, final int endKeyOffset, final int endKeyLength) throws RocksDBException;
private native void merge(final long handle, final byte[] key,
final int keyOffset, final int keyLength, final byte[] value,
final int valueOffset, final int valueLength) throws RocksDBException;
private native void 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)
throws RocksDBException;
private native void 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)
throws RocksDBException;
private native void 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) throws RocksDBException;
private native void mergeDirect(long handle, long writeOptHandle, ByteBuffer key, int keyOffset,
int keyLength, ByteBuffer value, int valueOffset, int valueLength, long cfHandle)
throws RocksDBException;
private native void write0(final long handle, final long writeOptHandle,
final long wbHandle) throws RocksDBException;
private native void write1(final long handle, final long writeOptHandle,
final long wbwiHandle) throws RocksDBException;
private native int get(final long handle, final byte[] key,
final int keyOffset, final int keyLength, final byte[] value,
final int valueOffset, final int valueLength) throws RocksDBException;
private native int get(final long handle, final byte[] key,
final int keyOffset, final int keyLength, byte[] value,
final int valueOffset, final int valueLength, final long cfHandle)
throws RocksDBException;
private native int 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)
throws RocksDBException;
private native int 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) throws RocksDBException;
private native byte[] get(final long handle, byte[] key, final int keyOffset,
final int keyLength) throws RocksDBException;
private native byte[] get(final long handle, final byte[] key,
final int keyOffset, final int keyLength, final long cfHandle)
throws RocksDBException;
private native byte[] get(final long handle, final long readOptHandle,
final byte[] key, final int keyOffset, final int keyLength)
throws RocksDBException;
private native byte[] get(final long handle,
final long readOptHandle, final byte[] key, final int keyOffset,
final int keyLength, final long cfHandle) throws RocksDBException;
private native byte[][] multiGet(final long dbHandle, final byte[][] keys,
final int[] keyOffsets, final int[] keyLengths);
private native byte[][] multiGet(final long dbHandle, final byte[][] keys,
final int[] keyOffsets, final int[] keyLengths,
final long[] columnFamilyHandles);
private native byte[][] multiGet(final long dbHandle, final long rOptHandle,
final byte[][] keys, final int[] keyOffsets, final int[] keyLengths);
private native byte[][] multiGet(final long dbHandle, final long rOptHandle,
final byte[][] keys, final int[] keyOffsets, final int[] keyLengths,
final long[] columnFamilyHandles);
private native void multiGet(final long dbHandle, final long rOptHandle,
final long[] columnFamilyHandles, final ByteBuffer[] keysArray, final int[] keyOffsets,
final int[] keyLengths, final ByteBuffer[] valuesArray, final int[] valuesSizeArray,
final Status[] statusArray);
private native boolean keyExists(final long handle, final long cfHandle, final long readOptHandle,
final byte[] key, final int keyOffset, final int keyLength);
private native boolean keyExistsDirect(final long handle, final long cfHandle,
final long readOptHandle, final ByteBuffer key, final int keyOffset, final int keyLength);
private native boolean keyMayExist(
final long handle, final long cfHandle, final long readOptHandle,
final byte[] key, final int keyOffset, final int keyLength);
private native byte[][] keyMayExistFoundValue(
final long handle, final long cfHandle, final long readOptHandle,
final byte[] key, final int keyOffset, final int keyLength);
private native void putDirect(long handle, long writeOptHandle, ByteBuffer key, int keyOffset,
int keyLength, ByteBuffer value, int valueOffset, int valueLength, long cfHandle)
throws RocksDBException;
private native long iterator(final long handle, final long cfHandle, final long readOptHandle);
private native long[] iterators(final long handle,
final long[] columnFamilyHandles, final long readOptHandle)
throws RocksDBException;
private native long getSnapshot(final long nativeHandle);
private native void releaseSnapshot(
final long nativeHandle, final long snapshotHandle);
private native String getProperty(final long nativeHandle,
final long cfHandle, final String property, final int propertyLength)
throws RocksDBException;
private native Map getMapProperty(final long nativeHandle,
final long cfHandle, final String property, final int propertyLength)
throws RocksDBException;
private native int getDirect(long handle, long readOptHandle, ByteBuffer key, int keyOffset,
int keyLength, ByteBuffer value, int valueOffset, int valueLength, long cfHandle)
throws RocksDBException;
private native boolean keyMayExistDirect(final long handle, final long cfHhandle,
final long readOptHandle, final ByteBuffer key, final int keyOffset, final int keyLength);
private native int[] keyMayExistDirectFoundValue(final long handle, final long cfHhandle,
final long readOptHandle, final ByteBuffer key, final int keyOffset, final int keyLength,
final ByteBuffer value, final int valueOffset, final int valueLength);
private native void deleteDirect(long handle, long optHandle, ByteBuffer key, int keyOffset,
int keyLength, long cfHandle) throws RocksDBException;
private native long getLongProperty(final long nativeHandle,
final long cfHandle, final String property, final int propertyLength)
throws RocksDBException;
private native void resetStats(final long nativeHandle)
throws RocksDBException;
private native long getAggregatedLongProperty(final long nativeHandle,
final String property, int propertyLength) throws RocksDBException;
private native long[] getApproximateSizes(final long nativeHandle,
final long columnFamilyHandle, final long[] rangeSliceHandles,
final byte includeFlags);
private native long[] getApproximateMemTableStats(final long nativeHandle,
final long columnFamilyHandle, final long rangeStartSliceHandle,
final long rangeLimitSliceHandle);
private native void compactRange(final long handle,
/* @Nullable */ final byte[] begin, final int beginLen,
/* @Nullable */ final byte[] end, final int endLen,
final long compactRangeOptHandle, final long cfHandle)
throws RocksDBException;
private native void setOptions(final long handle, final long cfHandle,
final String[] keys, final String[] values) throws RocksDBException;
private native String getOptions(final long handle, final long cfHandle);
private native void setDBOptions(final long handle,
final String[] keys, final String[] values) throws RocksDBException;
private native String getDBOptions(final long handle);
private native void setPerfLevel(final byte level);
private native byte getPerfLevelNative();
private native long getPerfContextNative();
private native String[] compactFiles(final long handle,
final long compactionOptionsHandle,
final long columnFamilyHandle,
final String[] inputFileNames,
final int outputLevel,
final int outputPathId,
final long compactionJobInfoHandle) throws RocksDBException;
private native void cancelAllBackgroundWork(final long handle,
final boolean wait);
private native void pauseBackgroundWork(final long handle)
throws RocksDBException;
private native void continueBackgroundWork(final long handle)
throws RocksDBException;
private native void enableAutoCompaction(final long handle,
final long[] columnFamilyHandles) throws RocksDBException;
private native int numberLevels(final long handle,
final long columnFamilyHandle);
private native int maxMemCompactionLevel(final long handle,
final long columnFamilyHandle);
private native int level0StopWriteTrigger(final long handle,
final long columnFamilyHandle);
private native String getName(final long handle);
private native long getEnv(final long handle);
private native void flush(final long handle, final long flushOptHandle,
/* @Nullable */ final long[] cfHandles) throws RocksDBException;
private native void flushWal(final long handle, final boolean sync)
throws RocksDBException;
private native void syncWal(final long handle) throws RocksDBException;
private native long getLatestSequenceNumber(final long handle);
private native void disableFileDeletions(long handle) throws RocksDBException;
private native void enableFileDeletions(long handle, boolean force)
throws RocksDBException;
private native String[] getLiveFiles(final long handle,
final boolean flushMemtable) throws RocksDBException;
private native LogFile[] getSortedWalFiles(final long handle)
throws RocksDBException;
private native long getUpdatesSince(final long handle,
final long sequenceNumber) throws RocksDBException;
private native void deleteFile(final long handle, final String name)
throws RocksDBException;
private native LiveFileMetaData[] getLiveFilesMetaData(final long handle);
private native ColumnFamilyMetaData getColumnFamilyMetaData(
final long handle, final long columnFamilyHandle);
private native void ingestExternalFile(final long handle,
final long columnFamilyHandle, final String[] filePathList,
final int filePathListLen, final long ingestExternalFileOptionsHandle)
throws RocksDBException;
private native void verifyChecksum(final long handle) throws RocksDBException;
private native long getDefaultColumnFamily(final long handle);
private native Map getPropertiesOfAllTables(
final long handle, final long columnFamilyHandle) throws RocksDBException;
private native Map getPropertiesOfTablesInRange(
final long handle, final long columnFamilyHandle,
final long[] rangeSliceHandles);
private native long[] suggestCompactRange(final long handle,
final long columnFamilyHandle) throws RocksDBException;
private native void promoteL0(final long handle,
final long columnFamilyHandle, final int tragetLevel)
throws RocksDBException;
private native void startTrace(final long handle, final long maxTraceFileSize,
final long traceWriterHandle) throws RocksDBException;
private native void endTrace(final long handle) throws RocksDBException;
private native void tryCatchUpWithPrimary(final long handle) throws RocksDBException;
private native void deleteFilesInRanges(long handle, long cfHandle, final byte[][] ranges,
boolean include_end) throws RocksDBException;
private static native void destroyDB(final String path, final long optionsHandle)
throws RocksDBException;
private static native int version();
protected DBOptionsInterface> options_;
private static Version version;
public static class Version {
private final byte major;
private final byte minor;
private final byte patch;
public Version(final byte major, final byte minor, final byte patch) {
this.major = major;
this.minor = minor;
this.patch = patch;
}
public int getMajor() {
return major;
}
public int getMinor() {
return minor;
}
public int getPatch() {
return patch;
}
@Override
public String toString() {
return getMajor() + "." + getMinor() + "." + getPatch();
}
private static Version fromEncodedVersion(final int encodedVersion) {
final byte patch = (byte) (encodedVersion & 0xff);
final byte minor = (byte) (encodedVersion >> 8 & 0xff);
final byte major = (byte) (encodedVersion >> 16 & 0xff);
return new Version(major, minor, patch);
}
}
}