org.rocksdb.Transaction Maven / Gradle / Ivy
Show all versions of rocksdbjni 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.rocksdb;
import static org.rocksdb.RocksDB.PERFORMANCE_OPTIMIZATION_FOR_A_VERY_SPECIFIC_WORKLOAD;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Provides BEGIN/COMMIT/ROLLBACK transactions.
*
* To use transactions, you must first create either an
* {@link OptimisticTransactionDB} or a {@link TransactionDB}
*
* To create a transaction, use
* {@link OptimisticTransactionDB#beginTransaction(org.rocksdb.WriteOptions)} or
* {@link TransactionDB#beginTransaction(org.rocksdb.WriteOptions)}
*
* It is up to the caller to synchronize access to this object.
*
* See samples/src/main/java/OptimisticTransactionSample.java and
* samples/src/main/java/TransactionSample.java for some simple
* examples.
*/
public class Transaction extends RocksObject {
private static final String FOR_EACH_KEY_THERE_MUST_BE_A_COLUMNFAMILYHANDLE =
"For each key there must be a ColumnFamilyHandle.";
private final RocksDB parent;
/**
* Intentionally package private
* as this is called from
* {@link OptimisticTransactionDB#beginTransaction(org.rocksdb.WriteOptions)}
* or {@link TransactionDB#beginTransaction(org.rocksdb.WriteOptions)}
*
* @param parent This must be either {@link TransactionDB} or
* {@link OptimisticTransactionDB}
* @param transactionHandle The native handle to the underlying C++
* transaction object
*/
Transaction(final RocksDB parent, final long transactionHandle) {
super(transactionHandle);
this.parent = parent;
}
/**
* If a transaction has a snapshot set, the transaction will ensure that
* any keys successfully written (or fetched via {@link #getForUpdate}) have
* not been modified outside of this transaction since the time the snapshot
* was set.
*
* If a snapshot has not been set, the transaction guarantees that keys have
* not been modified since the time each key was first written (or fetched via
* {@link #getForUpdate}).
*
* Using {@code #setSnapshot()} will provide stricter isolation guarantees
* at the expense of potentially more transaction failures due to conflicts
* with other writes.
*
* Calling {@code #setSnapshot()} has no effect on keys written before this
* function has been called.
*
* {@code #setSnapshot()} may be called multiple times if you would like to
* change the snapshot used for different operations in this transaction.
*
* Calling {@code #setSnapshot()} will not affect the version of Data returned
* by get(...) methods. See {@link #get} for more details.
*/
public void setSnapshot() {
assert(isOwningHandle());
setSnapshot(nativeHandle_);
}
/**
* Similar to {@link #setSnapshot()}, but will not change the current snapshot
* until put/merge/delete/getForUpdate/multiGetForUpdate is called.
* By calling this function, the transaction will essentially call
* {@link #setSnapshot()} for you right before performing the next
* write/getForUpdate.
*
* Calling {@code #setSnapshotOnNextOperation()} will not affect what
* snapshot is returned by {@link #getSnapshot} until the next
* write/getForUpdate is executed.
*
* When the snapshot is created the notifier's snapshotCreated method will
* be called so that the caller can get access to the snapshot.
*
* This is an optimization to reduce the likelihood of conflicts that
* could occur in between the time {@link #setSnapshot()} is called and the
* first write/getForUpdate operation. i.e. this prevents the following
* race-condition:
*
* txn1->setSnapshot();
* txn2->put("A", ...);
* txn2->commit();
* txn1->getForUpdate(opts, "A", ...); * FAIL!
*/
public void setSnapshotOnNextOperation() {
assert(isOwningHandle());
setSnapshotOnNextOperation(nativeHandle_);
}
/**
* Similar to {@link #setSnapshot()}, but will not change the current snapshot
* until put/merge/delete/getForUpdate/multiGetForUpdate is called.
* By calling this function, the transaction will essentially call
* {@link #setSnapshot()} for you right before performing the next
* write/getForUpdate.
*
* Calling {@link #setSnapshotOnNextOperation()} will not affect what
* snapshot is returned by {@link #getSnapshot} until the next
* write/getForUpdate is executed.
*
* When the snapshot is created the
* {@link AbstractTransactionNotifier#snapshotCreated(Snapshot)} method will
* be called so that the caller can get access to the snapshot.
*
* This is an optimization to reduce the likelihood of conflicts that
* could occur in between the time {@link #setSnapshot()} is called and the
* first write/getForUpdate operation. i.e. this prevents the following
* race-condition:
*
* txn1->setSnapshot();
* txn2->put("A", ...);
* txn2->commit();
* txn1->getForUpdate(opts, "A", ...); * FAIL!
*
* @param transactionNotifier A handler for receiving snapshot notifications
* for the transaction
*
*/
public void setSnapshotOnNextOperation(
final AbstractTransactionNotifier transactionNotifier) {
assert(isOwningHandle());
setSnapshotOnNextOperation(nativeHandle_, transactionNotifier.nativeHandle_);
}
/**
* Returns the Snapshot created by the last call to {@link #setSnapshot()}.
*
* REQUIRED: The returned Snapshot is only valid up until the next time
* {@link #setSnapshot()}/{@link #setSnapshotOnNextOperation()} is called,
* {@link #clearSnapshot()} is called, or the Transaction is deleted.
*
* @return The snapshot or null if there is no snapshot
*/
public Snapshot getSnapshot() {
assert(isOwningHandle());
final long snapshotNativeHandle = getSnapshot(nativeHandle_);
if(snapshotNativeHandle == 0) {
return null;
} else {
return new Snapshot(snapshotNativeHandle);
}
}
/**
* Clears the current snapshot (i.e. no snapshot will be 'set')
*
* This removes any snapshot that currently exists or is set to be created
* on the next update operation ({@link #setSnapshotOnNextOperation()}).
*
* Calling {@code #clearSnapshot()} has no effect on keys written before this
* function has been called.
*
* If a reference to a snapshot was retrieved via {@link #getSnapshot()}, it
* will no longer be valid and should be discarded after a call to
* {@code #clearSnapshot()}.
*/
public void clearSnapshot() {
assert(isOwningHandle());
clearSnapshot(nativeHandle_);
}
/**
* Prepare the current transaction for 2PC
*/
public void prepare() throws RocksDBException {
//TODO(AR) consider a Java'ish version of this function, which returns an AutoCloseable (commit)
assert(isOwningHandle());
prepare(nativeHandle_);
}
/**
* Write all batched keys to the db atomically.
*
* Returns OK on success.
*
* May return any error status that could be returned by DB:Write().
*
* If this transaction was created by an {@link OptimisticTransactionDB}
* Status::Busy() may be returned if the transaction could not guarantee
* that there are no write conflicts. Status::TryAgain() may be returned
* if the memtable history size is not large enough
* (See max_write_buffer_number_to_maintain).
*
* If this transaction was created by a {@link TransactionDB},
* Status::Expired() may be returned if this transaction has lived for
* longer than {@link TransactionOptions#getExpiration()}.
*
* @throws RocksDBException if an error occurs when committing the transaction
*/
public void commit() throws RocksDBException {
assert(isOwningHandle());
commit(nativeHandle_);
}
/**
* Discard all batched writes in this transaction.
*
* @throws RocksDBException if an error occurs when rolling back the transaction
*/
public void rollback() throws RocksDBException {
assert(isOwningHandle());
rollback(nativeHandle_);
}
/**
* Records the state of the transaction for future calls to
* {@link #rollbackToSavePoint()}.
*
* May be called multiple times to set multiple save points.
*
* @throws RocksDBException if an error occurs whilst setting a save point
*/
public void setSavePoint() throws RocksDBException {
assert(isOwningHandle());
setSavePoint(nativeHandle_);
}
/**
* Undo all operations in this transaction (put, merge, delete, putLogData)
* since the most recent call to {@link #setSavePoint()} and removes the most
* recent {@link #setSavePoint()}.
*
* If there is no previous call to {@link #setSavePoint()},
* returns Status::NotFound()
*
* @throws RocksDBException if an error occurs when rolling back to a save point
*/
public void rollbackToSavePoint() throws RocksDBException {
assert(isOwningHandle());
rollbackToSavePoint(nativeHandle_);
}
/**
* This function is similar to
* {@link RocksDB#get(ColumnFamilyHandle, ReadOptions, byte[])} except it will
* also read pending changes in this transaction.
* Currently, this function will return Status::MergeInProgress if the most
* recent write to the queried key in this batch is a Merge.
*
* If {@link ReadOptions#snapshot()} is not set, the current version of the
* key will be read. Calling {@link #setSnapshot()} does not affect the
* version of the data returned.
*
* Note that setting {@link ReadOptions#setSnapshot(Snapshot)} will affect
* what is read from the DB but will NOT change which keys are read from this
* transaction (the keys in this transaction do not yet belong to any snapshot
* and will be fetched regardless).
*
* @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle} instance
* @param readOptions Read options.
* @param key the key to retrieve the value for.
*
* @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 readOptions, final byte[] key) throws RocksDBException {
assert(isOwningHandle());
return get(nativeHandle_, readOptions.nativeHandle_, key, key.length,
columnFamilyHandle.nativeHandle_);
}
/**
* This function is similar to
* {@link RocksDB#get(ReadOptions, byte[])} except it will
* also read pending changes in this transaction.
* Currently, this function will return Status::MergeInProgress if the most
* recent write to the queried key in this batch is a Merge.
*
* If {@link ReadOptions#snapshot()} is not set, the current version of the
* key will be read. Calling {@link #setSnapshot()} does not affect the
* version of the data returned.
*
* Note that setting {@link ReadOptions#setSnapshot(Snapshot)} will affect
* what is read from the DB but will NOT change which keys are read from this
* transaction (the keys in this transaction do not yet belong to any snapshot
* and will be fetched regardless).
*
* @param readOptions Read options.
* @param key the key to retrieve the value for.
*
* @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 readOptions, final byte[] key)
throws RocksDBException {
assert(isOwningHandle());
return get(nativeHandle_, readOptions.nativeHandle_, key, key.length);
}
/**
* This function is similar to
* {@link RocksDB#multiGetAsList} except it will
* also read pending changes in this transaction.
* Currently, this function will return Status::MergeInProgress if the most
* recent write to the queried key in this batch is a Merge.
*
* If {@link ReadOptions#snapshot()} is not set, the current version of the
* key will be read. Calling {@link #setSnapshot()} does not affect the
* version of the data returned.
*
* Note that setting {@link ReadOptions#setSnapshot(Snapshot)} will affect
* what is read from the DB but will NOT change which keys are read from this
* transaction (the keys in this transaction do not yet belong to any snapshot
* and will be fetched regardless).
*
* @param readOptions Read options.
* @param columnFamilyHandles {@link java.util.List} containing
* {@link org.rocksdb.ColumnFamilyHandle} instances.
* @param keys of keys for which values need to be retrieved.
*
* @return Array of values, one for each key
*
* @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.
*/
@Deprecated
public byte[][] multiGet(final ReadOptions readOptions,
final List columnFamilyHandles, final byte[][] keys)
throws RocksDBException {
assert(isOwningHandle());
// Check if key size equals cfList size. If not a exception must be
// thrown. If not a Segmentation fault happens.
if (keys.length != columnFamilyHandles.size()) {
throw new IllegalArgumentException(FOR_EACH_KEY_THERE_MUST_BE_A_COLUMNFAMILYHANDLE);
}
if(keys.length == 0) {
return new byte[0][0];
}
final long[] cfHandles = new long[columnFamilyHandles.size()];
for (int i = 0; i < columnFamilyHandles.size(); i++) {
cfHandles[i] = columnFamilyHandles.get(i).nativeHandle_;
}
return multiGet(nativeHandle_, readOptions.nativeHandle_,
keys, cfHandles);
}
/**
* This function is similar to
* {@link RocksDB#multiGetAsList(ReadOptions, List, List)} except it will
* also read pending changes in this transaction.
* Currently, this function will return Status::MergeInProgress if the most
* recent write to the queried key in this batch is a Merge.
*
* If {@link ReadOptions#snapshot()} is not set, the current version of the
* key will be read. Calling {@link #setSnapshot()} does not affect the
* version of the data returned.
*
* Note that setting {@link ReadOptions#setSnapshot(Snapshot)} will affect
* what is read from the DB but will NOT change which keys are read from this
* transaction (the keys in this transaction do not yet belong to any snapshot
* and will be fetched regardless).
*
* @param readOptions Read options.
* @param columnFamilyHandles {@link java.util.List} containing
* {@link org.rocksdb.ColumnFamilyHandle} instances.
* @param keys of keys for which values need to be retrieved.
*
* @return Array of values, one for each key
*
* @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 readOptions,
final List columnFamilyHandles, final List keys)
throws RocksDBException {
assert (isOwningHandle());
// Check if key size equals cfList size. If not a exception must be
// thrown. If not a Segmentation fault happens.
if (keys.size() != columnFamilyHandles.size()) {
throw new IllegalArgumentException(FOR_EACH_KEY_THERE_MUST_BE_A_COLUMNFAMILYHANDLE);
}
if (keys.isEmpty()) {
return new ArrayList<>(0);
}
final byte[][] keysArray = keys.toArray(new byte[keys.size()][]);
final long[] cfHandles = new long[columnFamilyHandles.size()];
for (int i = 0; i < columnFamilyHandles.size(); i++) {
cfHandles[i] = columnFamilyHandles.get(i).nativeHandle_;
}
return Arrays.asList(multiGet(nativeHandle_, readOptions.nativeHandle_, keysArray, cfHandles));
}
/**
* This function is similar to
* {@link RocksDB#multiGetAsList} except it will
* also read pending changes in this transaction.
* Currently, this function will return Status::MergeInProgress if the most
* recent write to the queried key in this batch is a Merge.
*
* If {@link ReadOptions#snapshot()} is not set, the current version of the
* key will be read. Calling {@link #setSnapshot()} does not affect the
* version of the data returned.
*
* Note that setting {@link ReadOptions#setSnapshot(Snapshot)} will affect
* what is read from the DB but will NOT change which keys are read from this
* transaction (the keys in this transaction do not yet belong to any snapshot
* and will be fetched regardless).
*
* @param readOptions Read options.=
* {@link org.rocksdb.ColumnFamilyHandle} instances.
* @param keys of keys for which values need to be retrieved.
*
* @return Array of values, one for each key
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
@Deprecated
public byte[][] multiGet(final ReadOptions readOptions, final byte[][] keys)
throws RocksDBException {
assert(isOwningHandle());
if(keys.length == 0) {
return new byte[0][0];
}
return multiGet(nativeHandle_, readOptions.nativeHandle_,
keys);
}
/**
* This function is similar to
* {@link RocksDB#multiGetAsList} except it will
* also read pending changes in this transaction.
* Currently, this function will return Status::MergeInProgress if the most
* recent write to the queried key in this batch is a Merge.
*
* If {@link ReadOptions#snapshot()} is not set, the current version of the
* key will be read. Calling {@link #setSnapshot()} does not affect the
* version of the data returned.
*
* Note that setting {@link ReadOptions#setSnapshot(Snapshot)} will affect
* what is read from the DB but will NOT change which keys are read from this
* transaction (the keys in this transaction do not yet belong to any snapshot
* and will be fetched regardless).
*
* @param readOptions Read options.=
* {@link org.rocksdb.ColumnFamilyHandle} instances.
* @param keys of keys for which values need to be retrieved.
*
* @return Array of values, one for each key
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public List multiGetAsList(final ReadOptions readOptions, final List keys)
throws RocksDBException {
if (keys.isEmpty()) {
return new ArrayList<>(0);
}
final byte[][] keysArray = keys.toArray(new byte[keys.size()][]);
return Arrays.asList(multiGet(nativeHandle_, readOptions.nativeHandle_, keysArray));
}
/**
* Read this key and ensure that this transaction will only
* be able to be committed if this key is not written outside this
* transaction after it has first been read (or after the snapshot if a
* snapshot is set in this transaction). The transaction behavior is the
* same regardless of whether the key exists or not.
*
* Note: Currently, this function will return Status::MergeInProgress
* if the most recent write to the queried key in this batch is a Merge.
*
* The values returned by this function are similar to
* {@link RocksDB#get(ColumnFamilyHandle, ReadOptions, byte[])}.
* If value==nullptr, then this function will not read any data, but will
* still ensure that this key cannot be written to by outside of this
* transaction.
*
* If this transaction was created by an {@link OptimisticTransactionDB},
* {@link #getForUpdate(ReadOptions, ColumnFamilyHandle, byte[], boolean)}
* could cause {@link #commit()} to fail. Otherwise, it could return any error
* that could be returned by
* {@link RocksDB#get(ColumnFamilyHandle, ReadOptions, byte[])}.
*
* If this transaction was created on a {@link TransactionDB}, an
* {@link RocksDBException} may be thrown with an accompanying {@link Status}
* when:
* {@link Status.Code#Busy} if there is a write conflict,
* {@link Status.Code#TimedOut} if a lock could not be acquired,
* {@link Status.Code#TryAgain} if the memtable history size is not large
* enough. See
* {@link ColumnFamilyOptions#maxWriteBufferNumberToMaintain()}
* {@link Status.Code#MergeInProgress} if merge operations cannot be
* resolved.
*
* @param readOptions Read options.
* @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
* instance
* @param key the key to retrieve the value for.
* @param exclusive true if the transaction should have exclusive access to
* the key, otherwise false for shared access.
* @param doValidate true if it should validate the snapshot before doing the read
*
* @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[] getForUpdate(final ReadOptions readOptions,
final ColumnFamilyHandle columnFamilyHandle, final byte[] key, final boolean exclusive,
final boolean doValidate) throws RocksDBException {
assert (isOwningHandle());
return getForUpdate(nativeHandle_, readOptions.nativeHandle_, key, key.length,
columnFamilyHandle.nativeHandle_, exclusive, doValidate);
}
/**
* Same as
* {@link #getForUpdate(ReadOptions, ColumnFamilyHandle, byte[], boolean, boolean)}
* with doValidate=true.
*
* @param readOptions Read options.
* @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
* instance
* @param key the key to retrieve the value for.
* @param exclusive true if the transaction should have exclusive access to
* the key, otherwise false for shared access.
*
* @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[] getForUpdate(final ReadOptions readOptions,
final ColumnFamilyHandle columnFamilyHandle, final byte[] key,
final boolean exclusive) throws RocksDBException {
assert(isOwningHandle());
return getForUpdate(nativeHandle_, readOptions.nativeHandle_, key, key.length,
columnFamilyHandle.nativeHandle_, exclusive, true /*doValidate*/);
}
/**
* Read this key and ensure that this transaction will only
* be able to be committed if this key is not written outside this
* transaction after it has first been read (or after the snapshot if a
* snapshot is set in this transaction). The transaction behavior is the
* same regardless of whether the key exists or not.
*
* Note: Currently, this function will return Status::MergeInProgress
* if the most recent write to the queried key in this batch is a Merge.
*
* The values returned by this function are similar to
* {@link RocksDB#get(ReadOptions, byte[])}.
* If value==nullptr, then this function will not read any data, but will
* still ensure that this key cannot be written to by outside of this
* transaction.
*
* If this transaction was created on an {@link OptimisticTransactionDB},
* {@link #getForUpdate(ReadOptions, ColumnFamilyHandle, byte[], boolean)}
* could cause {@link #commit()} to fail. Otherwise, it could return any error
* that could be returned by
* {@link RocksDB#get(ReadOptions, byte[])}.
*
* If this transaction was created on a {@link TransactionDB}, an
* {@link RocksDBException} may be thrown with an accompanying {@link Status}
* when:
* {@link Status.Code#Busy} if there is a write conflict,
* {@link Status.Code#TimedOut} if a lock could not be acquired,
* {@link Status.Code#TryAgain} if the memtable history size is not large
* enough. See
* {@link ColumnFamilyOptions#maxWriteBufferNumberToMaintain()}
* {@link Status.Code#MergeInProgress} if merge operations cannot be
* resolved.
*
* @param readOptions Read options.
* @param key the key to retrieve the value for.
* @param exclusive true if the transaction should have exclusive access to
* the key, otherwise false for shared access.
*
* @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[] getForUpdate(final ReadOptions readOptions, final byte[] key,
final boolean exclusive) throws RocksDBException {
assert(isOwningHandle());
return getForUpdate(
nativeHandle_, readOptions.nativeHandle_, key, key.length, exclusive, true /*doValidate*/);
}
/**
* A multi-key version of
* {@link #getForUpdate(ReadOptions, ColumnFamilyHandle, byte[], boolean)}.
*
*
* @param readOptions Read options.
* @param columnFamilyHandles {@link org.rocksdb.ColumnFamilyHandle}
* instances
* @param keys the keys to retrieve the values for.
*
* @return Array of values, one for each key
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
@Deprecated
public byte[][] multiGetForUpdate(final ReadOptions readOptions,
final List columnFamilyHandles, final byte[][] keys)
throws RocksDBException {
assert(isOwningHandle());
// Check if key size equals cfList size. If not a exception must be
// thrown. If not a Segmentation fault happens.
if (keys.length != columnFamilyHandles.size()){
throw new IllegalArgumentException(FOR_EACH_KEY_THERE_MUST_BE_A_COLUMNFAMILYHANDLE);
}
if(keys.length == 0) {
return new byte[0][0];
}
final long[] cfHandles = new long[columnFamilyHandles.size()];
for (int i = 0; i < columnFamilyHandles.size(); i++) {
cfHandles[i] = columnFamilyHandles.get(i).nativeHandle_;
}
return multiGetForUpdate(nativeHandle_, readOptions.nativeHandle_,
keys, cfHandles);
}
/**
* A multi-key version of
* {@link #getForUpdate(ReadOptions, ColumnFamilyHandle, byte[], boolean)}.
*
*
* @param readOptions Read options.
* @param columnFamilyHandles {@link org.rocksdb.ColumnFamilyHandle}
* instances
* @param keys the keys to retrieve the values for.
*
* @return Array of values, one for each key
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public List multiGetForUpdateAsList(final ReadOptions readOptions,
final List columnFamilyHandles, final List keys)
throws RocksDBException {
assert (isOwningHandle());
// Check if key size equals cfList size. If not a exception must be
// thrown. If not a Segmentation fault happens.
if (keys.size() != columnFamilyHandles.size()) {
throw new IllegalArgumentException(FOR_EACH_KEY_THERE_MUST_BE_A_COLUMNFAMILYHANDLE);
}
if (keys.isEmpty()) {
return new ArrayList<>();
}
final byte[][] keysArray = keys.toArray(new byte[keys.size()][]);
final long[] cfHandles = new long[columnFamilyHandles.size()];
for (int i = 0; i < columnFamilyHandles.size(); i++) {
cfHandles[i] = columnFamilyHandles.get(i).nativeHandle_;
}
return Arrays.asList(
multiGetForUpdate(nativeHandle_, readOptions.nativeHandle_, keysArray, cfHandles));
}
/**
* A multi-key version of {@link #getForUpdate(ReadOptions, byte[], boolean)}.
*
*
* @param readOptions Read options.
* @param keys the keys to retrieve the values for.
*
* @return Array of values, one for each key
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
@Deprecated
public byte[][] multiGetForUpdate(final ReadOptions readOptions, final byte[][] keys)
throws RocksDBException {
assert(isOwningHandle());
if(keys.length == 0) {
return new byte[0][0];
}
return multiGetForUpdate(nativeHandle_,
readOptions.nativeHandle_, keys);
}
/**
* A multi-key version of {@link #getForUpdate(ReadOptions, byte[], boolean)}.
*
*
* @param readOptions Read options.
* @param keys the keys to retrieve the values for.
*
* @return List of values, one for each key
*
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public List multiGetForUpdateAsList(
final ReadOptions readOptions, final List keys) throws RocksDBException {
assert (isOwningHandle());
if (keys.isEmpty()) {
return new ArrayList<>(0);
}
final byte[][] keysArray = keys.toArray(new byte[keys.size()][]);
return Arrays.asList(multiGetForUpdate(nativeHandle_, readOptions.nativeHandle_, keysArray));
}
/**
* Returns an iterator that will iterate on all keys in the default
* column family including both keys in the DB and uncommitted keys in this
* transaction.
*
* Setting {@link ReadOptions#setSnapshot(Snapshot)} will affect what is read
* from the DB but will NOT change which keys are read from this transaction
* (the keys in this transaction do not yet belong to any snapshot and will be
* fetched regardless).
*
* Caller is responsible for deleting the returned Iterator.
*
* The returned iterator is only valid until {@link #commit()},
* {@link #rollback()}, or {@link #rollbackToSavePoint()} is called.
*
* @param readOptions Read options.
*
* @return instance of iterator object.
*/
public RocksIterator getIterator(final ReadOptions readOptions) {
assert(isOwningHandle());
return new RocksIterator(parent, getIterator(nativeHandle_,
readOptions.nativeHandle_));
}
/**
* Returns an iterator that will iterate on all keys in the column family
* specified by {@code columnFamilyHandle} including both keys in the DB
* and uncommitted keys in this transaction.
*
* Setting {@link ReadOptions#setSnapshot(Snapshot)} will affect what is read
* from the DB but will NOT change which keys are read from this transaction
* (the keys in this transaction do not yet belong to any snapshot and will be
* fetched regardless).
*
* Caller is responsible for calling {@link RocksIterator#close()} on
* the returned Iterator.
*
* The returned iterator is only valid until {@link #commit()},
* {@link #rollback()}, or {@link #rollbackToSavePoint()} is called.
*
* @param readOptions Read options.
* @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
* instance
*
* @return instance of iterator object.
*/
public RocksIterator getIterator(final ReadOptions readOptions,
final ColumnFamilyHandle columnFamilyHandle) {
assert(isOwningHandle());
return new RocksIterator(parent, getIterator(nativeHandle_,
readOptions.nativeHandle_, columnFamilyHandle.nativeHandle_));
}
/**
* Similar to {@link RocksDB#put(ColumnFamilyHandle, byte[], byte[])}, but
* will also perform conflict checking on the keys be written.
*
* If this Transaction was created on an {@link OptimisticTransactionDB},
* these functions should always succeed.
*
* If this Transaction was created on a {@link TransactionDB}, an
* {@link RocksDBException} may be thrown with an accompanying {@link Status}
* when:
* {@link Status.Code#Busy} if there is a write conflict,
* {@link Status.Code#TimedOut} if a lock could not be acquired,
* {@link Status.Code#TryAgain} if the memtable history size is not large
* enough. See
* {@link ColumnFamilyOptions#maxWriteBufferNumberToMaintain()}
*
* @param columnFamilyHandle The column family to put the key/value into
* @param key the specified key to be inserted.
* @param value the value associated with the specified key.
* @param assumeTracked true when it is expected that the key is already
* tracked. More specifically, it means the the key was previous tracked
* in the same savepoint, with the same exclusive flag, and at a lower
* sequence number. If valid then it skips ValidateSnapshot,
* throws an error otherwise.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void put(final ColumnFamilyHandle columnFamilyHandle, final byte[] key,
final byte[] value, final boolean assumeTracked) throws RocksDBException {
assert (isOwningHandle());
put(nativeHandle_, key, key.length, value, value.length,
columnFamilyHandle.nativeHandle_, assumeTracked);
}
/**
* Similar to {@link #put(ColumnFamilyHandle, byte[], byte[], boolean)}
* but with {@code assumeTracked = false}.
*
* Will also perform conflict checking on the keys be written.
*
* If this Transaction was created on an {@link OptimisticTransactionDB},
* these functions should always succeed.
*
* If this Transaction was created on a {@link TransactionDB}, an
* {@link RocksDBException} may be thrown with an accompanying {@link Status}
* when:
* {@link Status.Code#Busy} if there is a write conflict,
* {@link Status.Code#TimedOut} if a lock could not be acquired,
* {@link Status.Code#TryAgain} if the memtable history size is not large
* enough. See
* {@link ColumnFamilyOptions#maxWriteBufferNumberToMaintain()}
*
* @param columnFamilyHandle The column family to put the key/value into
* @param key the specified key to be inserted.
* @param value the value associated with the specified key.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void put(final ColumnFamilyHandle columnFamilyHandle, final byte[] key,
final byte[] value) throws RocksDBException {
assert(isOwningHandle());
put(nativeHandle_, key, key.length, value, value.length,
columnFamilyHandle.nativeHandle_, false);
}
/**
* Similar to {@link RocksDB#put(byte[], byte[])}, but
* will also perform conflict checking on the keys be written.
*
* If this Transaction was created on an {@link OptimisticTransactionDB},
* these functions should always succeed.
*
* If this Transaction was created on a {@link TransactionDB}, an
* {@link RocksDBException} may be thrown with an accompanying {@link Status}
* when:
* {@link Status.Code#Busy} if there is a write conflict,
* {@link Status.Code#TimedOut} if a lock could not be acquired,
* {@link Status.Code#TryAgain} if the memtable history size is not large
* enough. See
* {@link ColumnFamilyOptions#maxWriteBufferNumberToMaintain()}
*
* @param key the specified key to be inserted.
* @param value the value associated with the specified key.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void put(final byte[] key, final byte[] value)
throws RocksDBException {
assert(isOwningHandle());
put(nativeHandle_, key, key.length, value, value.length);
}
//TODO(AR) refactor if we implement org.rocksdb.SliceParts in future
/**
* Similar to {@link #put(ColumnFamilyHandle, byte[], byte[])} but allows
* you to specify the key and value in several parts that will be
* concatenated together.
*
* @param columnFamilyHandle The column family to put the key/value into
* @param keyParts the specified key to be inserted.
* @param valueParts the value associated with the specified key.
* @param assumeTracked true when it is expected that the key is already
* tracked. More specifically, it means the the key was previous tracked
* in the same savepoint, with the same exclusive flag, and at a lower
* sequence number. If valid then it skips ValidateSnapshot,
* throws an error otherwise.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void put(final ColumnFamilyHandle columnFamilyHandle,
final byte[][] keyParts, final byte[][] valueParts,
final boolean assumeTracked) throws RocksDBException {
assert (isOwningHandle());
put(nativeHandle_, keyParts, keyParts.length, valueParts, valueParts.length,
columnFamilyHandle.nativeHandle_, assumeTracked);
}
/**
* Similar to {@link #put(ColumnFamilyHandle, byte[][], byte[][], boolean)}
* but with with {@code assumeTracked = false}.
*
* Allows you to specify the key and value in several parts that will be
* concatenated together.
*
* @param columnFamilyHandle The column family to put the key/value into
* @param keyParts the specified key to be inserted.
* @param valueParts the value associated with the specified key.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void put(final ColumnFamilyHandle columnFamilyHandle,
final byte[][] keyParts, final byte[][] valueParts)
throws RocksDBException {
assert(isOwningHandle());
put(nativeHandle_, keyParts, keyParts.length, valueParts, valueParts.length,
columnFamilyHandle.nativeHandle_, false);
}
//TODO(AR) refactor if we implement org.rocksdb.SliceParts in future
/**
* Similar to {@link #put(byte[], byte[])} but allows
* you to specify the key and value in several parts that will be
* concatenated together
*
* @param keyParts the specified key to be inserted.
* @param valueParts the value associated with the specified key.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void put(final byte[][] keyParts, final byte[][] valueParts)
throws RocksDBException {
assert(isOwningHandle());
put(nativeHandle_, keyParts, keyParts.length, valueParts,
valueParts.length);
}
/**
* Similar to {@link RocksDB#merge(ColumnFamilyHandle, byte[], byte[])}, but
* will also perform conflict checking on the keys be written.
*
* If this Transaction was created on an {@link OptimisticTransactionDB},
* these functions should always succeed.
*
* If this Transaction was created on a {@link TransactionDB}, an
* {@link RocksDBException} may be thrown with an accompanying {@link Status}
* when:
* {@link Status.Code#Busy} if there is a write conflict,
* {@link Status.Code#TimedOut} if a lock could not be acquired,
* {@link Status.Code#TryAgain} if the memtable history size is not large
* enough. See
* {@link ColumnFamilyOptions#maxWriteBufferNumberToMaintain()}
*
* @param columnFamilyHandle The column family to merge the key/value into
* @param key the specified key to be merged.
* @param value the value associated with the specified key.
* @param assumeTracked true when it is expected that the key is already
* tracked. More specifically, it means the the key was previous tracked
* in the same savepoint, with the same exclusive flag, and at a lower
* sequence number. If valid then it skips ValidateSnapshot,
* throws an error otherwise.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void merge(final ColumnFamilyHandle columnFamilyHandle,
final byte[] key, final byte[] value, final boolean assumeTracked)
throws RocksDBException {
assert (isOwningHandle());
merge(nativeHandle_, key, key.length, value, value.length,
columnFamilyHandle.nativeHandle_, assumeTracked);
}
/**
* Similar to {@link #merge(ColumnFamilyHandle, byte[], byte[], boolean)}
* but with {@code assumeTracked = false}.
*
* Will also perform conflict checking on the keys be written.
*
* If this Transaction was created on an {@link OptimisticTransactionDB},
* these functions should always succeed.
*
* If this Transaction was created on a {@link TransactionDB}, an
* {@link RocksDBException} may be thrown with an accompanying {@link Status}
* when:
* {@link Status.Code#Busy} if there is a write conflict,
* {@link Status.Code#TimedOut} if a lock could not be acquired,
* {@link Status.Code#TryAgain} if the memtable history size is not large
* enough. See
* {@link ColumnFamilyOptions#maxWriteBufferNumberToMaintain()}
*
* @param columnFamilyHandle The column family to merge the key/value into
* @param key the specified key to be merged.
* @param value the value associated with the specified key.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void merge(final ColumnFamilyHandle columnFamilyHandle,
final byte[] key, final byte[] value) throws RocksDBException {
assert(isOwningHandle());
merge(nativeHandle_, key, key.length, value, value.length,
columnFamilyHandle.nativeHandle_, false);
}
/**
* Similar to {@link RocksDB#merge(byte[], byte[])}, but
* will also perform conflict checking on the keys be written.
*
* If this Transaction was created on an {@link OptimisticTransactionDB},
* these functions should always succeed.
*
* If this Transaction was created on a {@link TransactionDB}, an
* {@link RocksDBException} may be thrown with an accompanying {@link Status}
* when:
* {@link Status.Code#Busy} if there is a write conflict,
* {@link Status.Code#TimedOut} if a lock could not be acquired,
* {@link Status.Code#TryAgain} if the memtable history size is not large
* enough. See
* {@link ColumnFamilyOptions#maxWriteBufferNumberToMaintain()}
*
* @param key the specified key to be merged.
* @param value the value associated with the specified key.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void merge(final byte[] key, final byte[] value)
throws RocksDBException {
assert(isOwningHandle());
merge(nativeHandle_, key, key.length, value, value.length);
}
/**
* Similar to {@link RocksDB#delete(ColumnFamilyHandle, byte[])}, but
* will also perform conflict checking on the keys be written.
*
* If this Transaction was created on an {@link OptimisticTransactionDB},
* these functions should always succeed.
*
* If this Transaction was created on a {@link TransactionDB}, an
* {@link RocksDBException} may be thrown with an accompanying {@link Status}
* when:
* {@link Status.Code#Busy} if there is a write conflict,
* {@link Status.Code#TimedOut} if a lock could not be acquired,
* {@link Status.Code#TryAgain} if the memtable history size is not large
* enough. See
* {@link ColumnFamilyOptions#maxWriteBufferNumberToMaintain()}
*
* @param columnFamilyHandle The column family to delete the key/value from
* @param key the specified key to be deleted.
* @param assumeTracked true when it is expected that the key is already
* tracked. More specifically, it means the the key was previous tracked
* in the same savepoint, with the same exclusive flag, and at a lower
* sequence number. If valid then it skips ValidateSnapshot,
* throws an error otherwise.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void delete(final ColumnFamilyHandle columnFamilyHandle,
final byte[] key, final boolean assumeTracked) throws RocksDBException {
assert (isOwningHandle());
delete(nativeHandle_, key, key.length, columnFamilyHandle.nativeHandle_,
assumeTracked);
}
/**
* Similar to {@link #delete(ColumnFamilyHandle, byte[], boolean)}
* but with {@code assumeTracked = false}.
*
* Will also perform conflict checking on the keys be written.
*
* If this Transaction was created on an {@link OptimisticTransactionDB},
* these functions should always succeed.
*
* If this Transaction was created on a {@link TransactionDB}, an
* {@link RocksDBException} may be thrown with an accompanying {@link Status}
* when:
* {@link Status.Code#Busy} if there is a write conflict,
* {@link Status.Code#TimedOut} if a lock could not be acquired,
* {@link Status.Code#TryAgain} if the memtable history size is not large
* enough. See
* {@link ColumnFamilyOptions#maxWriteBufferNumberToMaintain()}
*
* @param columnFamilyHandle The column family to delete the key/value from
* @param key the specified key to be deleted.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void delete(final ColumnFamilyHandle columnFamilyHandle,
final byte[] key) throws RocksDBException {
assert(isOwningHandle());
delete(nativeHandle_, key, key.length, columnFamilyHandle.nativeHandle_,
/*assumeTracked*/ false);
}
/**
* Similar to {@link RocksDB#delete(byte[])}, but
* will also perform conflict checking on the keys be written.
*
* If this Transaction was created on an {@link OptimisticTransactionDB},
* these functions should always succeed.
*
* If this Transaction was created on a {@link TransactionDB}, an
* {@link RocksDBException} may be thrown with an accompanying {@link Status}
* when:
* {@link Status.Code#Busy} if there is a write conflict,
* {@link Status.Code#TimedOut} if a lock could not be acquired,
* {@link Status.Code#TryAgain} if the memtable history size is not large
* enough. See
* {@link ColumnFamilyOptions#maxWriteBufferNumberToMaintain()}
*
* @param key the specified key to be deleted.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void delete(final byte[] key) throws RocksDBException {
assert(isOwningHandle());
delete(nativeHandle_, key, key.length);
}
//TODO(AR) refactor if we implement org.rocksdb.SliceParts in future
/**
* Similar to {@link #delete(ColumnFamilyHandle, byte[])} but allows
* you to specify the key in several parts that will be
* concatenated together.
*
* @param columnFamilyHandle The column family to delete the key/value from
* @param keyParts the specified key to be deleted.
* @param assumeTracked true when it is expected that the key is already
* tracked. More specifically, it means the the key was previous tracked
* in the same savepoint, with the same exclusive flag, and at a lower
* sequence number. If valid then it skips ValidateSnapshot,
* throws an error otherwise.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void delete(final ColumnFamilyHandle columnFamilyHandle,
final byte[][] keyParts, final boolean assumeTracked)
throws RocksDBException {
assert (isOwningHandle());
delete(nativeHandle_, keyParts, keyParts.length,
columnFamilyHandle.nativeHandle_, assumeTracked);
}
/**
* Similar to{@link #delete(ColumnFamilyHandle, byte[][], boolean)}
* but with {@code assumeTracked = false}.
*
* Allows you to specify the key in several parts that will be
* concatenated together.
*
* @param columnFamilyHandle The column family to delete the key/value from
* @param keyParts the specified key to be deleted.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void delete(final ColumnFamilyHandle columnFamilyHandle,
final byte[][] keyParts) throws RocksDBException {
assert(isOwningHandle());
delete(nativeHandle_, keyParts, keyParts.length,
columnFamilyHandle.nativeHandle_, false);
}
//TODO(AR) refactor if we implement org.rocksdb.SliceParts in future
/**
* Similar to {@link #delete(byte[])} but allows
* you to specify key the in several parts that will be
* concatenated together.
*
* @param keyParts the specified key to be deleted
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void delete(final byte[][] keyParts) throws RocksDBException {
assert(isOwningHandle());
delete(nativeHandle_, keyParts, keyParts.length);
}
/**
* Similar to {@link RocksDB#singleDelete(ColumnFamilyHandle, byte[])}, but
* will also perform conflict checking on the keys be written.
*
* If this Transaction was created on an {@link OptimisticTransactionDB},
* these functions should always succeed.
*
* If this Transaction was created on a {@link TransactionDB}, an
* {@link RocksDBException} may be thrown with an accompanying {@link Status}
* when:
* {@link Status.Code#Busy} if there is a write conflict,
* {@link Status.Code#TimedOut} if a lock could not be acquired,
* {@link Status.Code#TryAgain} if the memtable history size is not large
* enough. See
* {@link ColumnFamilyOptions#maxWriteBufferNumberToMaintain()}
*
* @param columnFamilyHandle The column family to delete the key/value from
* @param key the specified key to be deleted.
* @param assumeTracked true when it is expected that the key is already
* tracked. More specifically, it means the key was previously tracked
* in the same savepoint, with the same exclusive flag, and at a lower
* sequence number. If valid then it skips ValidateSnapshot,
* throws an error otherwise.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
@Experimental(PERFORMANCE_OPTIMIZATION_FOR_A_VERY_SPECIFIC_WORKLOAD)
public void singleDelete(final ColumnFamilyHandle columnFamilyHandle, final byte[] key,
final boolean assumeTracked) throws RocksDBException {
assert (isOwningHandle());
singleDelete(nativeHandle_, key, key.length,
columnFamilyHandle.nativeHandle_, assumeTracked);
}
/**
* Similar to {@link #singleDelete(ColumnFamilyHandle, byte[], boolean)}
* but with {@code assumeTracked = false}.
*
* will also perform conflict checking on the keys be written.
*
* If this Transaction was created on an {@link OptimisticTransactionDB},
* these functions should always succeed.
*
* If this Transaction was created on a {@link TransactionDB}, an
* {@link RocksDBException} may be thrown with an accompanying {@link Status}
* when:
* {@link Status.Code#Busy} if there is a write conflict,
* {@link Status.Code#TimedOut} if a lock could not be acquired,
* {@link Status.Code#TryAgain} if the memtable history size is not large
* enough. See
* {@link ColumnFamilyOptions#maxWriteBufferNumberToMaintain()}
*
* @param columnFamilyHandle The column family to delete the key/value from
* @param key the specified key to be deleted.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
@Experimental(PERFORMANCE_OPTIMIZATION_FOR_A_VERY_SPECIFIC_WORKLOAD)
public void singleDelete(final ColumnFamilyHandle columnFamilyHandle, final byte[] key)
throws RocksDBException {
assert(isOwningHandle());
singleDelete(nativeHandle_, key, key.length,
columnFamilyHandle.nativeHandle_, false);
}
/**
* Similar to {@link RocksDB#singleDelete(byte[])}, but
* will also perform conflict checking on the keys be written.
*
* If this Transaction was created on an {@link OptimisticTransactionDB},
* these functions should always succeed.
*
* If this Transaction was created on a {@link TransactionDB}, an
* {@link RocksDBException} may be thrown with an accompanying {@link Status}
* when:
* {@link Status.Code#Busy} if there is a write conflict,
* {@link Status.Code#TimedOut} if a lock could not be acquired,
* {@link Status.Code#TryAgain} if the memtable history size is not large
* enough. See
* {@link ColumnFamilyOptions#maxWriteBufferNumberToMaintain()}
*
* @param key the specified key to be deleted.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
@Experimental(PERFORMANCE_OPTIMIZATION_FOR_A_VERY_SPECIFIC_WORKLOAD)
public void singleDelete(final byte[] key) throws RocksDBException {
assert(isOwningHandle());
singleDelete(nativeHandle_, key, key.length);
}
//TODO(AR) refactor if we implement org.rocksdb.SliceParts in future
/**
* Similar to {@link #singleDelete(ColumnFamilyHandle, byte[])} but allows
* you to specify the key in several parts that will be
* concatenated together.
*
* @param columnFamilyHandle The column family to delete the key/value from
* @param keyParts the specified key to be deleted.
* @param assumeTracked true when it is expected that the key is already
* tracked. More specifically, it means the key was previously tracked
* in the same savepoint, with the same exclusive flag, and at a lower
* sequence number. If valid then it skips ValidateSnapshot,
* throws an error otherwise.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
@Experimental(PERFORMANCE_OPTIMIZATION_FOR_A_VERY_SPECIFIC_WORKLOAD)
public void singleDelete(final ColumnFamilyHandle columnFamilyHandle, final byte[][] keyParts,
final boolean assumeTracked) throws RocksDBException {
assert (isOwningHandle());
singleDelete(nativeHandle_, keyParts, keyParts.length,
columnFamilyHandle.nativeHandle_, assumeTracked);
}
/**
* Similar to{@link #singleDelete(ColumnFamilyHandle, byte[][], boolean)}
* but with {@code assumeTracked = false}.
*
* Allows you to specify the key in several parts that will be
* concatenated together.
*
* @param columnFamilyHandle The column family to delete the key/value from
* @param keyParts the specified key to be deleted.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
@Experimental(PERFORMANCE_OPTIMIZATION_FOR_A_VERY_SPECIFIC_WORKLOAD)
public void singleDelete(final ColumnFamilyHandle columnFamilyHandle, final byte[][] keyParts)
throws RocksDBException {
assert(isOwningHandle());
singleDelete(nativeHandle_, keyParts, keyParts.length,
columnFamilyHandle.nativeHandle_, false);
}
//TODO(AR) refactor if we implement org.rocksdb.SliceParts in future
/**
* Similar to {@link #singleDelete(byte[])} but allows
* you to specify the key in several parts that will be
* concatenated together.
*
* @param keyParts the specified key to be deleted.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
@Experimental(PERFORMANCE_OPTIMIZATION_FOR_A_VERY_SPECIFIC_WORKLOAD)
public void singleDelete(final byte[][] keyParts) throws RocksDBException {
assert(isOwningHandle());
singleDelete(nativeHandle_, keyParts, keyParts.length);
}
/**
* Similar to {@link RocksDB#put(ColumnFamilyHandle, byte[], byte[])},
* but operates on the transactions write batch. This write will only happen
* if this transaction gets committed successfully.
*
* Unlike {@link #put(ColumnFamilyHandle, byte[], byte[])} no conflict
* checking will be performed for this key.
*
* If this Transaction was created on a {@link TransactionDB}, this function
* will still acquire locks necessary to make sure this write doesn't cause
* conflicts in other transactions; This may cause a {@link RocksDBException}
* with associated {@link Status.Code#Busy}.
*
* @param columnFamilyHandle The column family to put the key/value into
* @param key the specified key to be inserted.
* @param value the value associated with the specified key.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void putUntracked(final ColumnFamilyHandle columnFamilyHandle,
final byte[] key, final byte[] value) throws RocksDBException {
assert(isOwningHandle());
putUntracked(nativeHandle_, key, key.length, value, value.length,
columnFamilyHandle.nativeHandle_);
}
/**
* Similar to {@link RocksDB#put(byte[], byte[])},
* but operates on the transactions write batch. This write will only happen
* if this transaction gets committed successfully.
*
* Unlike {@link #put(byte[], byte[])} no conflict
* checking will be performed for this key.
*
* If this Transaction was created on a {@link TransactionDB}, this function
* will still acquire locks necessary to make sure this write doesn't cause
* conflicts in other transactions; This may cause a {@link RocksDBException}
* with associated {@link Status.Code#Busy}.
*
* @param key the specified key to be inserted.
* @param value the value associated with the specified key.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void putUntracked(final byte[] key, final byte[] value)
throws RocksDBException {
assert(isOwningHandle());
putUntracked(nativeHandle_, key, key.length, value, value.length);
}
//TODO(AR) refactor if we implement org.rocksdb.SliceParts in future
/**
* Similar to {@link #putUntracked(ColumnFamilyHandle, byte[], byte[])} but
* allows you to specify the key and value in several parts that will be
* concatenated together.
*
* @param columnFamilyHandle The column family to put the key/value into
* @param keyParts the specified key to be inserted.
* @param valueParts the value associated with the specified key.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void putUntracked(final ColumnFamilyHandle columnFamilyHandle,
final byte[][] keyParts, final byte[][] valueParts)
throws RocksDBException {
assert(isOwningHandle());
putUntracked(nativeHandle_, keyParts, keyParts.length, valueParts,
valueParts.length, columnFamilyHandle.nativeHandle_);
}
//TODO(AR) refactor if we implement org.rocksdb.SliceParts in future
/**
* Similar to {@link #putUntracked(byte[], byte[])} but
* allows you to specify the key and value in several parts that will be
* concatenated together.
*
* @param keyParts the specified key to be inserted.
* @param valueParts the value associated with the specified key.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void putUntracked(final byte[][] keyParts, final byte[][] valueParts)
throws RocksDBException {
assert(isOwningHandle());
putUntracked(nativeHandle_, keyParts, keyParts.length, valueParts,
valueParts.length);
}
/**
* Similar to {@link RocksDB#merge(ColumnFamilyHandle, byte[], byte[])},
* but operates on the transactions write batch. This write will only happen
* if this transaction gets committed successfully.
*
* Unlike {@link #merge(ColumnFamilyHandle, byte[], byte[])} no conflict
* checking will be performed for this key.
*
* If this Transaction was created on a {@link TransactionDB}, this function
* will still acquire locks necessary to make sure this write doesn't cause
* conflicts in other transactions; This may cause a {@link RocksDBException}
* with associated {@link Status.Code#Busy}.
*
* @param columnFamilyHandle The column family to merge the key/value into
* @param key the specified key to be merged.
* @param value the value associated with the specified key.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void mergeUntracked(final ColumnFamilyHandle columnFamilyHandle,
final byte[] key, final byte[] value) throws RocksDBException {
mergeUntracked(nativeHandle_, key, key.length, value, value.length,
columnFamilyHandle.nativeHandle_);
}
/**
* Similar to {@link RocksDB#merge(byte[], byte[])},
* but operates on the transactions write batch. This write will only happen
* if this transaction gets committed successfully.
*
* Unlike {@link #merge(byte[], byte[])} no conflict
* checking will be performed for this key.
*
* If this Transaction was created on a {@link TransactionDB}, this function
* will still acquire locks necessary to make sure this write doesn't cause
* conflicts in other transactions; This may cause a {@link RocksDBException}
* with associated {@link Status.Code#Busy}.
*
* @param key the specified key to be merged.
* @param value the value associated with the specified key.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void mergeUntracked(final byte[] key, final byte[] value)
throws RocksDBException {
assert(isOwningHandle());
mergeUntracked(nativeHandle_, key, key.length, value, value.length);
}
/**
* Similar to {@link RocksDB#delete(ColumnFamilyHandle, byte[])},
* but operates on the transactions write batch. This write will only happen
* if this transaction gets committed successfully.
*
* Unlike {@link #delete(ColumnFamilyHandle, byte[])} no conflict
* checking will be performed for this key.
*
* If this Transaction was created on a {@link TransactionDB}, this function
* will still acquire locks necessary to make sure this write doesn't cause
* conflicts in other transactions; This may cause a {@link RocksDBException}
* with associated {@link Status.Code#Busy}.
*
* @param columnFamilyHandle The column family to delete the key/value from
* @param key the specified key to be deleted.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void deleteUntracked(final ColumnFamilyHandle columnFamilyHandle,
final byte[] key) throws RocksDBException {
assert(isOwningHandle());
deleteUntracked(nativeHandle_, key, key.length,
columnFamilyHandle.nativeHandle_);
}
/**
* Similar to {@link RocksDB#delete(byte[])},
* but operates on the transactions write batch. This write will only happen
* if this transaction gets committed successfully.
*
* Unlike {@link #delete(byte[])} no conflict
* checking will be performed for this key.
*
* If this Transaction was created on a {@link TransactionDB}, this function
* will still acquire locks necessary to make sure this write doesn't cause
* conflicts in other transactions; This may cause a {@link RocksDBException}
* with associated {@link Status.Code#Busy}.
*
* @param key the specified key to be deleted.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void deleteUntracked(final byte[] key) throws RocksDBException {
assert(isOwningHandle());
deleteUntracked(nativeHandle_, key, key.length);
}
//TODO(AR) refactor if we implement org.rocksdb.SliceParts in future
/**
* Similar to {@link #deleteUntracked(ColumnFamilyHandle, byte[])} but allows
* you to specify the key in several parts that will be
* concatenated together.
*
* @param columnFamilyHandle The column family to delete the key/value from
* @param keyParts the specified key to be deleted.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void deleteUntracked(final ColumnFamilyHandle columnFamilyHandle,
final byte[][] keyParts) throws RocksDBException {
assert(isOwningHandle());
deleteUntracked(nativeHandle_, keyParts, keyParts.length,
columnFamilyHandle.nativeHandle_);
}
//TODO(AR) refactor if we implement org.rocksdb.SliceParts in future
/**
* Similar to {@link #deleteUntracked(byte[])} but allows
* you to specify the key in several parts that will be
* concatenated together.
*
* @param keyParts the specified key to be deleted.
*
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
public void deleteUntracked(final byte[][] keyParts) throws RocksDBException {
assert(isOwningHandle());
deleteUntracked(nativeHandle_, keyParts, keyParts.length);
}
/**
* Similar to {@link WriteBatch#putLogData(byte[])}
*
* @param blob binary object to be inserted
*/
public void putLogData(final byte[] blob) {
assert(isOwningHandle());
putLogData(nativeHandle_, blob, blob.length);
}
/**
* By default, all put/merge/delete operations will be indexed in the
* transaction so that get/getForUpdate/getIterator can search for these
* keys.
*
* If the caller does not want to fetch the keys about to be written,
* they may want to avoid indexing as a performance optimization.
* Calling {@code #disableIndexing()} will turn off indexing for all future
* put/merge/delete operations until {@link #enableIndexing()} is called.
*
* If a key is put/merge/deleted after {@code #disableIndexing()} is called
* and then is fetched via get/getForUpdate/getIterator, the result of the
* fetch is undefined.
*/
public void disableIndexing() {
assert(isOwningHandle());
disableIndexing(nativeHandle_);
}
/**
* Re-enables indexing after a previous call to {@link #disableIndexing()}
*/
public void enableIndexing() {
assert(isOwningHandle());
enableIndexing(nativeHandle_);
}
/**
* Returns the number of distinct Keys being tracked by this transaction.
* If this transaction was created by a {@link TransactionDB}, this is the
* number of keys that are currently locked by this transaction.
* If this transaction was created by an {@link OptimisticTransactionDB},
* this is the number of keys that need to be checked for conflicts at commit
* time.
*
* @return the number of distinct Keys being tracked by this transaction
*/
public long getNumKeys() {
assert(isOwningHandle());
return getNumKeys(nativeHandle_);
}
/**
* Returns the number of puts that have been applied to this
* transaction so far.
*
* @return the number of puts that have been applied to this transaction
*/
public long getNumPuts() {
assert(isOwningHandle());
return getNumPuts(nativeHandle_);
}
/**
* Returns the number of deletes that have been applied to this
* transaction so far.
*
* @return the number of deletes that have been applied to this transaction
*/
public long getNumDeletes() {
assert(isOwningHandle());
return getNumDeletes(nativeHandle_);
}
/**
* Returns the number of merges that have been applied to this
* transaction so far.
*
* @return the number of merges that have been applied to this transaction
*/
public long getNumMerges() {
assert(isOwningHandle());
return getNumMerges(nativeHandle_);
}
/**
* Returns the elapsed time in milliseconds since this Transaction began.
*
* @return the elapsed time in milliseconds since this transaction began.
*/
public long getElapsedTime() {
assert(isOwningHandle());
return getElapsedTime(nativeHandle_);
}
/**
* Fetch the underlying write batch that contains all pending changes to be
* committed.
*
* Note: You should not write or delete anything from the batch directly and
* should only use the functions in the {@link Transaction} class to
* write to this transaction.
*
* @return The write batch
*/
public WriteBatchWithIndex getWriteBatch() {
assert(isOwningHandle());
return new WriteBatchWithIndex(getWriteBatch(nativeHandle_));
}
/**
* Change the value of {@link TransactionOptions#getLockTimeout()}
* (in milliseconds) for this transaction.
*
* Has no effect on OptimisticTransactions.
*
* @param lockTimeout the timeout (in milliseconds) for locks used by this
* transaction.
*/
public void setLockTimeout(final long lockTimeout) {
assert(isOwningHandle());
setLockTimeout(nativeHandle_, lockTimeout);
}
/**
* Return the WriteOptions that will be used during {@link #commit()}.
*
* @return the WriteOptions that will be used
*/
public WriteOptions getWriteOptions() {
assert(isOwningHandle());
return new WriteOptions(getWriteOptions(nativeHandle_));
}
/**
* Reset the WriteOptions that will be used during {@link #commit()}.
*
* @param writeOptions The new WriteOptions
*/
public void setWriteOptions(final WriteOptions writeOptions) {
assert(isOwningHandle());
setWriteOptions(nativeHandle_, writeOptions.nativeHandle_);
}
/**
* If this key was previously fetched in this transaction using
* {@link #getForUpdate(ReadOptions, ColumnFamilyHandle, byte[], boolean)}/
* {@link #multiGetForUpdate(ReadOptions, List, byte[][])}, calling
* {@code #undoGetForUpdate(ColumnFamilyHandle, byte[])} will tell
* the transaction that it no longer needs to do any conflict checking
* for this key.
*
* If a key has been fetched N times via
* {@link #getForUpdate(ReadOptions, ColumnFamilyHandle, byte[], boolean)}/
* {@link #multiGetForUpdate(ReadOptions, List, byte[][])}, then
* {@code #undoGetForUpdate(ColumnFamilyHandle, byte[])} will only have an
* effect if it is also called N times. If this key has been written to in
* this transaction, {@code #undoGetForUpdate(ColumnFamilyHandle, byte[])}
* will have no effect.
*
* If {@link #setSavePoint()} has been called after the
* {@link #getForUpdate(ReadOptions, ColumnFamilyHandle, byte[], boolean)},
* {@code #undoGetForUpdate(ColumnFamilyHandle, byte[])} will not have any
* effect.
*
* If this Transaction was created by an {@link OptimisticTransactionDB},
* calling {@code #undoGetForUpdate(ColumnFamilyHandle, byte[])} can affect
* whether this key is conflict checked at commit time.
* If this Transaction was created by a {@link TransactionDB},
* calling {@code #undoGetForUpdate(ColumnFamilyHandle, byte[])} may release
* any held locks for this key.
*
* @param columnFamilyHandle {@link org.rocksdb.ColumnFamilyHandle}
* instance
* @param key the key to retrieve the value for.
*/
public void undoGetForUpdate(final ColumnFamilyHandle columnFamilyHandle,
final byte[] key) {
assert(isOwningHandle());
undoGetForUpdate(nativeHandle_, key, key.length, columnFamilyHandle.nativeHandle_);
}
/**
* If this key was previously fetched in this transaction using
* {@link #getForUpdate(ReadOptions, byte[], boolean)}/
* {@link #multiGetForUpdate(ReadOptions, List, byte[][])}, calling
* {@code #undoGetForUpdate(byte[])} will tell
* the transaction that it no longer needs to do any conflict checking
* for this key.
*
* If a key has been fetched N times via
* {@link #getForUpdate(ReadOptions, byte[], boolean)}/
* {@link #multiGetForUpdate(ReadOptions, List, byte[][])}, then
* {@code #undoGetForUpdate(byte[])} will only have an
* effect if it is also called N times. If this key has been written to in
* this transaction, {@code #undoGetForUpdate(byte[])}
* will have no effect.
*
* If {@link #setSavePoint()} has been called after the
* {@link #getForUpdate(ReadOptions, byte[], boolean)},
* {@code #undoGetForUpdate(byte[])} will not have any
* effect.
*
* If this Transaction was created by an {@link OptimisticTransactionDB},
* calling {@code #undoGetForUpdate(byte[])} can affect
* whether this key is conflict checked at commit time.
* If this Transaction was created by a {@link TransactionDB},
* calling {@code #undoGetForUpdate(byte[])} may release
* any held locks for this key.
*
* @param key the key to retrieve the value for.
*/
public void undoGetForUpdate(final byte[] key) {
assert(isOwningHandle());
undoGetForUpdate(nativeHandle_, key, key.length);
}
/**
* Adds the keys from the WriteBatch to the transaction
*
* @param writeBatch The write batch to read from
*
* @throws RocksDBException if an error occurs whilst rebuilding from the
* write batch.
*/
public void rebuildFromWriteBatch(final WriteBatch writeBatch)
throws RocksDBException {
assert(isOwningHandle());
rebuildFromWriteBatch(nativeHandle_, writeBatch.nativeHandle_);
}
/**
* Get the Commit time Write Batch.
*
* @return the commit time write batch.
*/
public WriteBatch getCommitTimeWriteBatch() {
assert(isOwningHandle());
return new WriteBatch(getCommitTimeWriteBatch(nativeHandle_));
}
/**
* Set the log number.
*
* @param logNumber the log number
*/
public void setLogNumber(final long logNumber) {
assert(isOwningHandle());
setLogNumber(nativeHandle_, logNumber);
}
/**
* Get the log number.
*
* @return the log number
*/
public long getLogNumber() {
assert(isOwningHandle());
return getLogNumber(nativeHandle_);
}
/**
* Set the name of the transaction.
*
* @param transactionName the name of the transaction
*
* @throws RocksDBException if an error occurs when setting the transaction
* name.
*/
public void setName(final String transactionName) throws RocksDBException {
assert(isOwningHandle());
setName(nativeHandle_, transactionName);
}
/**
* Get the name of the transaction.
*
* @return the name of the transaction
*/
public String getName() {
assert(isOwningHandle());
return getName(nativeHandle_);
}
/**
* Get the ID of the transaction.
*
* @return the ID of the transaction.
*/
public long getID() {
assert(isOwningHandle());
return getID(nativeHandle_);
}
/**
* Determine if a deadlock has been detected.
*
* @return true if a deadlock has been detected.
*/
public boolean isDeadlockDetect() {
assert(isOwningHandle());
return isDeadlockDetect(nativeHandle_);
}
/**
* Get the list of waiting transactions.
*
* @return The list of waiting transactions.
*/
public WaitingTransactions getWaitingTxns() {
assert(isOwningHandle());
return getWaitingTxns(nativeHandle_);
}
/**
* Get the execution status of the transaction.
*
* NOTE: The execution status of an Optimistic Transaction
* never changes. This is only useful for non-optimistic transactions!
*
* @return The execution status of the transaction
*/
public TransactionState getState() {
assert(isOwningHandle());
return TransactionState.getTransactionState(
getState(nativeHandle_));
}
/**
* The globally unique id with which the transaction is identified. This id
* might or might not be set depending on the implementation. Similarly the
* implementation decides the point in lifetime of a transaction at which it
* assigns the id. Although currently it is the case, the id is not guaranteed
* to remain the same across restarts.
*
* @return the transaction id.
*/
@Experimental("NOTE: Experimental feature")
public long getId() {
assert(isOwningHandle());
return getId(nativeHandle_);
}
public enum TransactionState {
STARTED((byte)0),
AWAITING_PREPARE((byte)1),
PREPARED((byte)2),
AWAITING_COMMIT((byte)3),
COMMITTED((byte)4),
AWAITING_ROLLBACK((byte)5),
ROLLEDBACK((byte)6),
LOCKS_STOLEN((byte)7);
/*
* Keep old misspelled variable as alias
* Tip from https://stackoverflow.com/a/37092410/454544
*/
public static final TransactionState COMMITED = COMMITTED;
private final byte value;
TransactionState(final byte value) {
this.value = value;
}
/**
* Get TransactionState by byte value.
*
* @param value byte representation of TransactionState.
*
* @return {@link org.rocksdb.Transaction.TransactionState} instance or null.
* @throws java.lang.IllegalArgumentException if an invalid
* value is provided.
*/
public static TransactionState getTransactionState(final byte value) {
for (final TransactionState transactionState : TransactionState.values()) {
if (transactionState.value == value){
return transactionState;
}
}
throw new IllegalArgumentException(
"Illegal value provided for TransactionState.");
}
}
/**
* Called from C++ native method {@link #getWaitingTxns(long)}
* to construct a WaitingTransactions object.
*
* @param columnFamilyId The id of the {@link ColumnFamilyHandle}
* @param key The key
* @param transactionIds The transaction ids
*
* @return The waiting transactions
*/
@SuppressWarnings("PMD.UnusedPrivateMethod")
private WaitingTransactions newWaitingTransactions(
final long columnFamilyId, final String key, final long[] transactionIds) {
return new WaitingTransactions(columnFamilyId, key, transactionIds);
}
public static class WaitingTransactions {
private final long columnFamilyId;
private final String key;
private final long[] transactionIds;
private WaitingTransactions(final long columnFamilyId, final String key,
final long[] transactionIds) {
this.columnFamilyId = columnFamilyId;
this.key = key;
this.transactionIds = transactionIds;
}
/**
* Get the Column Family ID.
*
* @return The column family ID
*/
public long getColumnFamilyId() {
return columnFamilyId;
}
/**
* Get the key on which the transactions are waiting.
*
* @return The key
*/
public String getKey() {
return key;
}
/**
* Get the IDs of the waiting transactions.
*
* @return The IDs of the waiting transactions
*/
@SuppressWarnings("PMD.MethodReturnsInternalArray")
public long[] getTransactionIds() {
return transactionIds;
}
}
private native void setSnapshot(final long handle);
private native void setSnapshotOnNextOperation(final long handle);
private native void setSnapshotOnNextOperation(final long handle,
final long transactionNotifierHandle);
private native long getSnapshot(final long handle);
private native void clearSnapshot(final long handle);
private native void prepare(final long handle) throws RocksDBException;
private native void commit(final long handle) throws RocksDBException;
private native void rollback(final long handle) throws RocksDBException;
private native void setSavePoint(final long handle) throws RocksDBException;
private native void rollbackToSavePoint(final long handle)
throws RocksDBException;
private native byte[] get(final long handle, final long readOptionsHandle, final byte[] key,
final int keyLength, final long columnFamilyHandle) throws RocksDBException;
private native byte[] get(final long handle, final long readOptionsHandle, final byte[] key,
final int keyLen) throws RocksDBException;
private native byte[][] multiGet(final long handle,
final long readOptionsHandle, final byte[][] keys,
final long[] columnFamilyHandles) throws RocksDBException;
private native byte[][] multiGet(final long handle,
final long readOptionsHandle, final byte[][] keys)
throws RocksDBException;
private native byte[] getForUpdate(final long handle, final long readOptionsHandle,
final byte[] key, final int keyLength, final long columnFamilyHandle, final boolean exclusive,
final boolean doValidate) throws RocksDBException;
private native byte[] getForUpdate(final long handle, final long readOptionsHandle,
final byte[] key, final int keyLen, final boolean exclusive, final boolean doValidate)
throws RocksDBException;
private native byte[][] multiGetForUpdate(final long handle,
final long readOptionsHandle, final byte[][] keys,
final long[] columnFamilyHandles) throws RocksDBException;
private native byte[][] multiGetForUpdate(final long handle,
final long readOptionsHandle, final byte[][] keys)
throws RocksDBException;
private native long getIterator(final long handle,
final long readOptionsHandle);
private native long getIterator(final long handle,
final long readOptionsHandle, final long columnFamilyHandle);
private native void put(final long handle, final byte[] key, final int keyLength,
final byte[] value, final int valueLength, final long columnFamilyHandle,
final boolean assumeTracked) throws RocksDBException;
private native void put(final long handle, final byte[] key,
final int keyLength, final byte[] value, final int valueLength)
throws RocksDBException;
private native void put(final long handle, final byte[][] keys, final int keysLength,
final byte[][] values, final int valuesLength, final long columnFamilyHandle,
final boolean assumeTracked) throws RocksDBException;
private native void put(final long handle, final byte[][] keys,
final int keysLength, final byte[][] values, final int valuesLength)
throws RocksDBException;
private native void merge(final long handle, final byte[] key, final int keyLength,
final byte[] value, final int valueLength, final long columnFamilyHandle,
final boolean assumeTracked) throws RocksDBException;
private native void merge(final long handle, final byte[] key,
final int keyLength, final byte[] value, final int valueLength)
throws RocksDBException;
private native void delete(final long handle, final byte[] key, final int keyLength,
final long columnFamilyHandle, final boolean assumeTracked) throws RocksDBException;
private native void delete(final long handle, final byte[] key,
final int keyLength) throws RocksDBException;
private native void delete(final long handle, final byte[][] keys, final int keysLength,
final long columnFamilyHandle, final boolean assumeTracked) throws RocksDBException;
private native void delete(final long handle, final byte[][] keys,
final int keysLength) throws RocksDBException;
private native void singleDelete(final long handle, final byte[] key, final int keyLength,
final long columnFamilyHandle, final boolean assumeTracked) throws RocksDBException;
private native void singleDelete(final long handle, final byte[] key,
final int keyLength) throws RocksDBException;
private native void singleDelete(final long handle, final byte[][] keys, final int keysLength,
final long columnFamilyHandle, final boolean assumeTracked) throws RocksDBException;
private native void singleDelete(final long handle, final byte[][] keys,
final int keysLength) throws RocksDBException;
private native void putUntracked(final long handle, final byte[] key,
final int keyLength, final byte[] value, final int valueLength,
final long columnFamilyHandle) throws RocksDBException;
private native void putUntracked(final long handle, final byte[] key,
final int keyLength, final byte[] value, final int valueLength)
throws RocksDBException;
private native void putUntracked(final long handle, final byte[][] keys,
final int keysLength, final byte[][] values, final int valuesLength,
final long columnFamilyHandle) throws RocksDBException;
private native void putUntracked(final long handle, final byte[][] keys,
final int keysLength, final byte[][] values, final int valuesLength)
throws RocksDBException;
private native void mergeUntracked(final long handle, final byte[] key,
final int keyLength, final byte[] value, final int valueLength,
final long columnFamilyHandle) throws RocksDBException;
private native void mergeUntracked(final long handle, final byte[] key,
final int keyLength, final byte[] value, final int valueLength)
throws RocksDBException;
private native void deleteUntracked(final long handle, final byte[] key,
final int keyLength, final long columnFamilyHandle)
throws RocksDBException;
private native void deleteUntracked(final long handle, final byte[] key,
final int keyLength) throws RocksDBException;
private native void deleteUntracked(final long handle, final byte[][] keys,
final int keysLength, final long columnFamilyHandle)
throws RocksDBException;
private native void deleteUntracked(final long handle, final byte[][] keys,
final int keysLength) throws RocksDBException;
private native void putLogData(final long handle, final byte[] blob,
final int blobLength);
private native void disableIndexing(final long handle);
private native void enableIndexing(final long handle);
private native long getNumKeys(final long handle);
private native long getNumPuts(final long handle);
private native long getNumDeletes(final long handle);
private native long getNumMerges(final long handle);
private native long getElapsedTime(final long handle);
private native long getWriteBatch(final long handle);
private native void setLockTimeout(final long handle, final long lockTimeout);
private native long getWriteOptions(final long handle);
private native void setWriteOptions(final long handle,
final long writeOptionsHandle);
private native void undoGetForUpdate(final long handle, final byte[] key,
final int keyLength, final long columnFamilyHandle);
private native void undoGetForUpdate(final long handle, final byte[] key,
final int keyLength);
private native void rebuildFromWriteBatch(final long handle,
final long writeBatchHandle) throws RocksDBException;
private native long getCommitTimeWriteBatch(final long handle);
private native void setLogNumber(final long handle, final long logNumber);
private native long getLogNumber(final long handle);
private native void setName(final long handle, final String name)
throws RocksDBException;
private native String getName(final long handle);
private native long getID(final long handle);
private native boolean isDeadlockDetect(final long handle);
private native WaitingTransactions getWaitingTxns(final long handle);
private native byte getState(final long handle);
private native long getId(final long handle);
@Override protected final native void disposeInternal(final long handle);
}