Make RocksDB instance responsible for closing associated ColumnFamilyHandle instances (#7428)
Summary: - Takes the burden off developer to close ColumnFamilyHandle instances before closing RocksDB instance - The change is backward-compatible ---- Previously the pattern for working with Column Families was: ```java try (final ColumnFamilyOptions cfOpts = new ColumnFamilyOptions().optimizeUniversalStyleCompaction()) { // list of column family descriptors, first entry must always be default column family final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList( new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, cfOpts), new ColumnFamilyDescriptor("my-first-columnfamily".getBytes(), cfOpts) ); // a list which will hold the handles for the column families once the db is opened final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>(); try (final DBOptions options = new DBOptions() .setCreateIfMissing(true) .setCreateMissingColumnFamilies(true); final RocksDB db = RocksDB.open(options, "path/to/do", cfDescriptors, columnFamilyHandleList)) { try { // do something } finally { // NOTE user must explicitly frees the column family handles before freeing the db for (final ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) { columnFamilyHandle.close(); } } // frees the column family options } } // frees the db and the db options ``` With the changes in this PR, the Java user no longer has to worry about manually closing the Column Families, which allows them to write simpler symmetrical create/free oriented code like this: ```java try (final ColumnFamilyOptions cfOpts = new ColumnFamilyOptions().optimizeUniversalStyleCompaction()) { // list of column family descriptors, first entry must always be default column family final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList( new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, cfOpts), new ColumnFamilyDescriptor("my-first-columnfamily".getBytes(), cfOpts) ); // a list which will hold the handles for the column families once the db is opened final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>(); try (final DBOptions options = new DBOptions() .setCreateIfMissing(true) .setCreateMissingColumnFamilies(true); final RocksDB db = RocksDB.open(options, "path/to/do", cfDescriptors, columnFamilyHandleList)) { // do something } // frees the column family options, then frees the db and the db options } } ``` **NOTE**: The changes in this PR are backwards API compatible, which means existing code using the original approach will also continue to function correctly. Pull Request resolved: https://github.com/facebook/rocksdb/pull/7428 Reviewed By: cheng-chang Differential Revision: D24063348 Pulled By: jay-zhuang fbshipit-source-id: 648d7526669923128c863ead94516bf4d50ac658
This commit is contained in:
parent
850cc0dbed
commit
05fba96927
@ -13,6 +13,12 @@ import java.util.Objects;
|
||||
* ColumnFamily Pointers.
|
||||
*/
|
||||
public class ColumnFamilyHandle extends RocksObject {
|
||||
/**
|
||||
* Constructs column family Java object, which operates on underlying native object.
|
||||
*
|
||||
* @param rocksDB db instance associated with this column family
|
||||
* @param nativeHandle native handle to underlying native ColumnFamily object
|
||||
*/
|
||||
ColumnFamilyHandle(final RocksDB rocksDB,
|
||||
final long nativeHandle) {
|
||||
super(nativeHandle);
|
||||
|
@ -38,6 +38,8 @@ public class RocksDB extends RocksObject {
|
||||
RocksDB.loadLibrary();
|
||||
}
|
||||
|
||||
private List<ColumnFamilyHandle> ownedColumnFamilyHandles = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Loads the necessary library files.
|
||||
* Calling this method twice will have no effect.
|
||||
@ -307,9 +309,12 @@ public class RocksDB extends RocksObject {
|
||||
db.storeOptionsInstance(options);
|
||||
|
||||
for (int i = 1; i < handles.length; i++) {
|
||||
columnFamilyHandles.add(new ColumnFamilyHandle(db, handles[i]));
|
||||
final ColumnFamilyHandle columnFamilyHandle = new ColumnFamilyHandle(db, handles[i]);
|
||||
columnFamilyHandles.add(columnFamilyHandle);
|
||||
}
|
||||
|
||||
db.ownedColumnFamilyHandles.addAll(columnFamilyHandles);
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
@ -484,9 +489,12 @@ public class RocksDB extends RocksObject {
|
||||
db.storeOptionsInstance(options);
|
||||
|
||||
for (int i = 1; i < handles.length; i++) {
|
||||
columnFamilyHandles.add(new ColumnFamilyHandle(db, handles[i]));
|
||||
final ColumnFamilyHandle columnFamilyHandle = new ColumnFamilyHandle(db, handles[i]);
|
||||
columnFamilyHandles.add(columnFamilyHandle);
|
||||
}
|
||||
|
||||
db.ownedColumnFamilyHandles.addAll(columnFamilyHandles);
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
@ -577,9 +585,12 @@ public class RocksDB extends RocksObject {
|
||||
db.storeOptionsInstance(options);
|
||||
|
||||
for (int i = 1; i < handles.length; i++) {
|
||||
columnFamilyHandles.add(new ColumnFamilyHandle(db, handles[i]));
|
||||
final ColumnFamilyHandle columnFamilyHandle = new ColumnFamilyHandle(db, handles[i]);
|
||||
columnFamilyHandles.add(columnFamilyHandle);
|
||||
}
|
||||
|
||||
db.ownedColumnFamilyHandles.addAll(columnFamilyHandles);
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
@ -597,6 +608,11 @@ public class RocksDB extends RocksObject {
|
||||
* @throws RocksDBException if an error occurs whilst closing.
|
||||
*/
|
||||
public void closeE() throws RocksDBException {
|
||||
for (final ColumnFamilyHandle columnFamilyHandle : ownedColumnFamilyHandles) {
|
||||
columnFamilyHandle.close();
|
||||
}
|
||||
ownedColumnFamilyHandles.clear();
|
||||
|
||||
if (owningHandle_.compareAndSet(true, false)) {
|
||||
try {
|
||||
closeDatabase(nativeHandle_);
|
||||
@ -619,6 +635,11 @@ public class RocksDB extends RocksObject {
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
for (final ColumnFamilyHandle columnFamilyHandle : ownedColumnFamilyHandles) {
|
||||
columnFamilyHandle.close();
|
||||
}
|
||||
ownedColumnFamilyHandles.clear();
|
||||
|
||||
if (owningHandle_.compareAndSet(true, false)) {
|
||||
try {
|
||||
closeDatabase(nativeHandle_);
|
||||
@ -661,10 +682,12 @@ public class RocksDB extends RocksObject {
|
||||
public ColumnFamilyHandle createColumnFamily(
|
||||
final ColumnFamilyDescriptor columnFamilyDescriptor)
|
||||
throws RocksDBException {
|
||||
return new ColumnFamilyHandle(this, createColumnFamily(nativeHandle_,
|
||||
columnFamilyDescriptor.getName(),
|
||||
final ColumnFamilyHandle columnFamilyHandle = new ColumnFamilyHandle(this,
|
||||
createColumnFamily(nativeHandle_, columnFamilyDescriptor.getName(),
|
||||
columnFamilyDescriptor.getName().length,
|
||||
columnFamilyDescriptor.getOptions().nativeHandle_));
|
||||
ownedColumnFamilyHandles.add(columnFamilyHandle);
|
||||
return columnFamilyHandle;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -688,8 +711,10 @@ public class RocksDB extends RocksObject {
|
||||
final List<ColumnFamilyHandle> columnFamilyHandles =
|
||||
new ArrayList<>(cfHandles.length);
|
||||
for (int i = 0; i < cfHandles.length; i++) {
|
||||
columnFamilyHandles.add(new ColumnFamilyHandle(this, cfHandles[i]));
|
||||
final ColumnFamilyHandle columnFamilyHandle = new ColumnFamilyHandle(this, cfHandles[i]);
|
||||
columnFamilyHandles.add(columnFamilyHandle);
|
||||
}
|
||||
ownedColumnFamilyHandles.addAll(columnFamilyHandles);
|
||||
return columnFamilyHandles;
|
||||
}
|
||||
|
||||
@ -719,8 +744,10 @@ public class RocksDB extends RocksObject {
|
||||
final List<ColumnFamilyHandle> columnFamilyHandles =
|
||||
new ArrayList<>(cfHandles.length);
|
||||
for (int i = 0; i < cfHandles.length; i++) {
|
||||
columnFamilyHandles.add(new ColumnFamilyHandle(this, cfHandles[i]));
|
||||
final ColumnFamilyHandle columnFamilyHandle = new ColumnFamilyHandle(this, cfHandles[i]);
|
||||
columnFamilyHandles.add(columnFamilyHandle);
|
||||
}
|
||||
ownedColumnFamilyHandles.addAll(columnFamilyHandles);
|
||||
return columnFamilyHandles;
|
||||
}
|
||||
|
||||
@ -753,7 +780,22 @@ public class RocksDB extends RocksObject {
|
||||
dropColumnFamilies(nativeHandle_, cfHandles);
|
||||
}
|
||||
|
||||
//TODO(AR) what about DestroyColumnFamilyHandle
|
||||
/**
|
||||
* 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);
|
||||
if (ownedHandle.equals(columnFamilyHandle)) {
|
||||
columnFamilyHandle.close();
|
||||
ownedColumnFamilyHandles.remove(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the database entry for "key" to "value".
|
||||
@ -4479,7 +4521,6 @@ public class RocksDB extends RocksObject {
|
||||
final long handle, final long cfHandle) throws RocksDBException;
|
||||
private native void dropColumnFamilies(final long handle,
|
||||
final long[] cfHandles) throws RocksDBException;
|
||||
//TODO(AR) best way to express DestroyColumnFamilyHandle? ...maybe in ColumnFamilyHandle?
|
||||
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;
|
||||
|
@ -5,16 +5,17 @@
|
||||
|
||||
package org.rocksdb;
|
||||
|
||||
import java.util.*;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.*;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class ColumnFamilyTest {
|
||||
|
||||
@ClassRule
|
||||
@ -141,33 +142,19 @@ public class ColumnFamilyTest {
|
||||
final RocksDB db = RocksDB.open(options,
|
||||
dbFolder.getRoot().getAbsolutePath(), cfNames,
|
||||
columnFamilyHandleList)) {
|
||||
|
||||
try {
|
||||
assertThat(columnFamilyHandleList.size()).isEqualTo(2);
|
||||
db.put("dfkey1".getBytes(), "dfvalue".getBytes());
|
||||
db.put(columnFamilyHandleList.get(0), "dfkey2".getBytes(),
|
||||
"dfvalue".getBytes());
|
||||
db.put(columnFamilyHandleList.get(1), "newcfkey1".getBytes(),
|
||||
"newcfvalue".getBytes());
|
||||
db.put(columnFamilyHandleList.get(0), "dfkey2".getBytes(), "dfvalue".getBytes());
|
||||
db.put(columnFamilyHandleList.get(1), "newcfkey1".getBytes(), "newcfvalue".getBytes());
|
||||
|
||||
String retVal = new String(db.get(columnFamilyHandleList.get(1),
|
||||
"newcfkey1".getBytes()));
|
||||
String retVal = new String(db.get(columnFamilyHandleList.get(1), "newcfkey1".getBytes()));
|
||||
assertThat(retVal).isEqualTo("newcfvalue");
|
||||
assertThat((db.get(columnFamilyHandleList.get(1),
|
||||
"dfkey1".getBytes()))).isNull();
|
||||
assertThat((db.get(columnFamilyHandleList.get(1), "dfkey1".getBytes()))).isNull();
|
||||
db.delete(columnFamilyHandleList.get(1), "newcfkey1".getBytes());
|
||||
assertThat((db.get(columnFamilyHandleList.get(1),
|
||||
"newcfkey1".getBytes()))).isNull();
|
||||
db.delete(columnFamilyHandleList.get(0), new WriteOptions(),
|
||||
"dfkey2".getBytes());
|
||||
assertThat(db.get(columnFamilyHandleList.get(0), new ReadOptions(),
|
||||
"dfkey2".getBytes())).isNull();
|
||||
} finally {
|
||||
for (final ColumnFamilyHandle columnFamilyHandle :
|
||||
columnFamilyHandleList) {
|
||||
columnFamilyHandle.close();
|
||||
}
|
||||
}
|
||||
assertThat((db.get(columnFamilyHandleList.get(1), "newcfkey1".getBytes()))).isNull();
|
||||
db.delete(columnFamilyHandleList.get(0), new WriteOptions(), "dfkey2".getBytes());
|
||||
assertThat(db.get(columnFamilyHandleList.get(0), new ReadOptions(), "dfkey2".getBytes()))
|
||||
.isNull();
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,30 +171,22 @@ public class ColumnFamilyTest {
|
||||
final RocksDB db = RocksDB.open(options,
|
||||
dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
|
||||
columnFamilyHandleList)) {
|
||||
try {
|
||||
db.put(columnFamilyHandleList.get(0), new WriteOptions(),
|
||||
"key1".getBytes(), "value".getBytes());
|
||||
db.put(
|
||||
columnFamilyHandleList.get(0), new WriteOptions(), "key1".getBytes(), "value".getBytes());
|
||||
db.put("key2".getBytes(), "12345678".getBytes());
|
||||
final byte[] outValue = new byte[5];
|
||||
// not found value
|
||||
int getResult = db.get("keyNotFound".getBytes(), outValue);
|
||||
assertThat(getResult).isEqualTo(RocksDB.NOT_FOUND);
|
||||
// found value which fits in outValue
|
||||
getResult = db.get(columnFamilyHandleList.get(0), "key1".getBytes(),
|
||||
outValue);
|
||||
getResult = db.get(columnFamilyHandleList.get(0), "key1".getBytes(), outValue);
|
||||
assertThat(getResult).isNotEqualTo(RocksDB.NOT_FOUND);
|
||||
assertThat(outValue).isEqualTo("value".getBytes());
|
||||
// found value which fits partially
|
||||
getResult = db.get(columnFamilyHandleList.get(0), new ReadOptions(),
|
||||
"key2".getBytes(), outValue);
|
||||
getResult =
|
||||
db.get(columnFamilyHandleList.get(0), new ReadOptions(), "key2".getBytes(), outValue);
|
||||
assertThat(getResult).isNotEqualTo(RocksDB.NOT_FOUND);
|
||||
assertThat(outValue).isEqualTo("12345".getBytes());
|
||||
} finally {
|
||||
for (final ColumnFamilyHandle columnFamilyHandle :
|
||||
columnFamilyHandleList) {
|
||||
columnFamilyHandle.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,22 +202,12 @@ public class ColumnFamilyTest {
|
||||
final RocksDB db = RocksDB.open(options,
|
||||
dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
|
||||
columnFamilyHandleList)) {
|
||||
ColumnFamilyHandle tmpColumnFamilyHandle = null;
|
||||
try {
|
||||
ColumnFamilyHandle tmpColumnFamilyHandle;
|
||||
tmpColumnFamilyHandle = db.createColumnFamily(
|
||||
new ColumnFamilyDescriptor("tmpCF".getBytes(),
|
||||
new ColumnFamilyOptions()));
|
||||
new ColumnFamilyDescriptor("tmpCF".getBytes(), new ColumnFamilyOptions()));
|
||||
db.put(tmpColumnFamilyHandle, "key".getBytes(), "value".getBytes());
|
||||
db.dropColumnFamily(tmpColumnFamilyHandle);
|
||||
assertThat(tmpColumnFamilyHandle.isOwningHandle()).isTrue();
|
||||
} finally {
|
||||
if (tmpColumnFamilyHandle != null) {
|
||||
tmpColumnFamilyHandle.close();
|
||||
}
|
||||
for (ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) {
|
||||
columnFamilyHandle.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -256,29 +225,15 @@ public class ColumnFamilyTest {
|
||||
columnFamilyHandleList)) {
|
||||
ColumnFamilyHandle tmpColumnFamilyHandle = null;
|
||||
ColumnFamilyHandle tmpColumnFamilyHandle2 = null;
|
||||
try {
|
||||
tmpColumnFamilyHandle = db.createColumnFamily(
|
||||
new ColumnFamilyDescriptor("tmpCF".getBytes(),
|
||||
new ColumnFamilyOptions()));
|
||||
new ColumnFamilyDescriptor("tmpCF".getBytes(), new ColumnFamilyOptions()));
|
||||
tmpColumnFamilyHandle2 = db.createColumnFamily(
|
||||
new ColumnFamilyDescriptor("tmpCF2".getBytes(),
|
||||
new ColumnFamilyOptions()));
|
||||
new ColumnFamilyDescriptor("tmpCF2".getBytes(), new ColumnFamilyOptions()));
|
||||
db.put(tmpColumnFamilyHandle, "key".getBytes(), "value".getBytes());
|
||||
db.put(tmpColumnFamilyHandle2, "key".getBytes(), "value".getBytes());
|
||||
db.dropColumnFamilies(Arrays.asList(tmpColumnFamilyHandle, tmpColumnFamilyHandle2));
|
||||
assertThat(tmpColumnFamilyHandle.isOwningHandle()).isTrue();
|
||||
assertThat(tmpColumnFamilyHandle2.isOwningHandle()).isTrue();
|
||||
} finally {
|
||||
if (tmpColumnFamilyHandle != null) {
|
||||
tmpColumnFamilyHandle.close();
|
||||
}
|
||||
if (tmpColumnFamilyHandle2 != null) {
|
||||
tmpColumnFamilyHandle2.close();
|
||||
}
|
||||
for (ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) {
|
||||
columnFamilyHandle.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -300,36 +255,24 @@ public class ColumnFamilyTest {
|
||||
cfDescriptors, columnFamilyHandleList);
|
||||
final WriteBatch writeBatch = new WriteBatch();
|
||||
final WriteOptions writeOpt = new WriteOptions()) {
|
||||
try {
|
||||
writeBatch.put("key".getBytes(), "value".getBytes());
|
||||
writeBatch.put(db.getDefaultColumnFamily(),
|
||||
"mergeKey".getBytes(), "merge".getBytes());
|
||||
writeBatch.merge(db.getDefaultColumnFamily(), "mergeKey".getBytes(),
|
||||
"merge".getBytes());
|
||||
writeBatch.put(columnFamilyHandleList.get(1), "newcfkey".getBytes(),
|
||||
"value".getBytes());
|
||||
writeBatch.put(columnFamilyHandleList.get(1), "newcfkey2".getBytes(),
|
||||
"value2".getBytes());
|
||||
writeBatch.put(db.getDefaultColumnFamily(), "mergeKey".getBytes(), "merge".getBytes());
|
||||
writeBatch.merge(db.getDefaultColumnFamily(), "mergeKey".getBytes(), "merge".getBytes());
|
||||
writeBatch.put(columnFamilyHandleList.get(1), "newcfkey".getBytes(), "value".getBytes());
|
||||
writeBatch.put(columnFamilyHandleList.get(1), "newcfkey2".getBytes(), "value2".getBytes());
|
||||
writeBatch.delete("xyz".getBytes());
|
||||
writeBatch.delete(columnFamilyHandleList.get(1), "xyz".getBytes());
|
||||
db.write(writeOpt, writeBatch);
|
||||
|
||||
assertThat(db.get(columnFamilyHandleList.get(1),
|
||||
"xyz".getBytes()) == null);
|
||||
assertThat(new String(db.get(columnFamilyHandleList.get(1),
|
||||
"newcfkey".getBytes()))).isEqualTo("value");
|
||||
assertThat(new String(db.get(columnFamilyHandleList.get(1),
|
||||
"newcfkey2".getBytes()))).isEqualTo("value2");
|
||||
assertThat(db.get(columnFamilyHandleList.get(1), "xyz".getBytes()) == null);
|
||||
assertThat(new String(db.get(columnFamilyHandleList.get(1), "newcfkey".getBytes())))
|
||||
.isEqualTo("value");
|
||||
assertThat(new String(db.get(columnFamilyHandleList.get(1), "newcfkey2".getBytes())))
|
||||
.isEqualTo("value2");
|
||||
assertThat(new String(db.get("key".getBytes()))).isEqualTo("value");
|
||||
// check if key is merged
|
||||
assertThat(new String(db.get(db.getDefaultColumnFamily(),
|
||||
"mergeKey".getBytes()))).isEqualTo("merge,merge");
|
||||
} finally {
|
||||
for (final ColumnFamilyHandle columnFamilyHandle :
|
||||
columnFamilyHandleList) {
|
||||
columnFamilyHandle.close();
|
||||
}
|
||||
}
|
||||
assertThat(new String(db.get(db.getDefaultColumnFamily(), "mergeKey".getBytes())))
|
||||
.isEqualTo("merge,merge");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -346,14 +289,9 @@ public class ColumnFamilyTest {
|
||||
final RocksDB db = RocksDB.open(options,
|
||||
dbFolder.getRoot().getAbsolutePath(),
|
||||
cfDescriptors, columnFamilyHandleList)) {
|
||||
try {
|
||||
|
||||
db.put(columnFamilyHandleList.get(1), "newcfkey".getBytes(),
|
||||
"value".getBytes());
|
||||
db.put(columnFamilyHandleList.get(1), "newcfkey2".getBytes(),
|
||||
"value2".getBytes());
|
||||
try (final RocksIterator rocksIterator =
|
||||
db.newIterator(columnFamilyHandleList.get(1))) {
|
||||
db.put(columnFamilyHandleList.get(1), "newcfkey".getBytes(), "value".getBytes());
|
||||
db.put(columnFamilyHandleList.get(1), "newcfkey2".getBytes(), "value2".getBytes());
|
||||
try (final RocksIterator rocksIterator = db.newIterator(columnFamilyHandleList.get(1))) {
|
||||
rocksIterator.seekToFirst();
|
||||
Map<String, String> refMap = new HashMap<>();
|
||||
refMap.put("newcfkey", "value");
|
||||
@ -361,18 +299,12 @@ public class ColumnFamilyTest {
|
||||
int i = 0;
|
||||
while (rocksIterator.isValid()) {
|
||||
i++;
|
||||
assertThat(refMap.get(new String(rocksIterator.key()))).
|
||||
isEqualTo(new String(rocksIterator.value()));
|
||||
assertThat(refMap.get(new String(rocksIterator.key())))
|
||||
.isEqualTo(new String(rocksIterator.value()));
|
||||
rocksIterator.next();
|
||||
}
|
||||
assertThat(i).isEqualTo(2);
|
||||
}
|
||||
} finally {
|
||||
for (final ColumnFamilyHandle columnFamilyHandle :
|
||||
columnFamilyHandleList) {
|
||||
columnFamilyHandle.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -388,35 +320,20 @@ public class ColumnFamilyTest {
|
||||
final RocksDB db = RocksDB.open(options,
|
||||
dbFolder.getRoot().getAbsolutePath(),
|
||||
cfDescriptors, columnFamilyHandleList)) {
|
||||
try {
|
||||
db.put(columnFamilyHandleList.get(0), "key".getBytes(),
|
||||
"value".getBytes());
|
||||
db.put(columnFamilyHandleList.get(1), "newcfkey".getBytes(),
|
||||
"value".getBytes());
|
||||
db.put(columnFamilyHandleList.get(0), "key".getBytes(), "value".getBytes());
|
||||
db.put(columnFamilyHandleList.get(1), "newcfkey".getBytes(), "value".getBytes());
|
||||
|
||||
final List<byte[]> keys = Arrays.asList(new byte[][]{
|
||||
"key".getBytes(), "newcfkey".getBytes()
|
||||
});
|
||||
final List<byte[]> keys =
|
||||
Arrays.asList(new byte[][] {"key".getBytes(), "newcfkey".getBytes()});
|
||||
|
||||
List<byte[]> retValues = db.multiGetAsList(columnFamilyHandleList, keys);
|
||||
assertThat(retValues.size()).isEqualTo(2);
|
||||
assertThat(new String(retValues.get(0)))
|
||||
.isEqualTo("value");
|
||||
assertThat(new String(retValues.get(1)))
|
||||
.isEqualTo("value");
|
||||
retValues = db.multiGetAsList(new ReadOptions(), columnFamilyHandleList,
|
||||
keys);
|
||||
assertThat(new String(retValues.get(0))).isEqualTo("value");
|
||||
assertThat(new String(retValues.get(1))).isEqualTo("value");
|
||||
retValues = db.multiGetAsList(new ReadOptions(), columnFamilyHandleList, keys);
|
||||
assertThat(retValues.size()).isEqualTo(2);
|
||||
assertThat(new String(retValues.get(0)))
|
||||
.isEqualTo("value");
|
||||
assertThat(new String(retValues.get(1)))
|
||||
.isEqualTo("value");
|
||||
} finally {
|
||||
for (final ColumnFamilyHandle columnFamilyHandle :
|
||||
columnFamilyHandleList) {
|
||||
columnFamilyHandle.close();
|
||||
}
|
||||
}
|
||||
assertThat(new String(retValues.get(0))).isEqualTo("value");
|
||||
assertThat(new String(retValues.get(1))).isEqualTo("value");
|
||||
}
|
||||
}
|
||||
|
||||
@ -432,35 +349,19 @@ public class ColumnFamilyTest {
|
||||
final RocksDB db = RocksDB.open(options,
|
||||
dbFolder.getRoot().getAbsolutePath(),
|
||||
cfDescriptors, columnFamilyHandleList)) {
|
||||
try {
|
||||
db.put(columnFamilyHandleList.get(0), "key".getBytes(),
|
||||
"value".getBytes());
|
||||
db.put(columnFamilyHandleList.get(1), "newcfkey".getBytes(),
|
||||
"value".getBytes());
|
||||
db.put(columnFamilyHandleList.get(0), "key".getBytes(), "value".getBytes());
|
||||
db.put(columnFamilyHandleList.get(1), "newcfkey".getBytes(), "value".getBytes());
|
||||
|
||||
final List<byte[]> keys = Arrays.asList(new byte[][]{
|
||||
"key".getBytes(), "newcfkey".getBytes()
|
||||
});
|
||||
List<byte[]> retValues = db.multiGetAsList(columnFamilyHandleList,
|
||||
keys);
|
||||
final List<byte[]> keys =
|
||||
Arrays.asList(new byte[][] {"key".getBytes(), "newcfkey".getBytes()});
|
||||
List<byte[]> retValues = db.multiGetAsList(columnFamilyHandleList, keys);
|
||||
assertThat(retValues.size()).isEqualTo(2);
|
||||
assertThat(new String(retValues.get(0)))
|
||||
.isEqualTo("value");
|
||||
assertThat(new String(retValues.get(1)))
|
||||
.isEqualTo("value");
|
||||
retValues = db.multiGetAsList(new ReadOptions(), columnFamilyHandleList,
|
||||
keys);
|
||||
assertThat(new String(retValues.get(0))).isEqualTo("value");
|
||||
assertThat(new String(retValues.get(1))).isEqualTo("value");
|
||||
retValues = db.multiGetAsList(new ReadOptions(), columnFamilyHandleList, keys);
|
||||
assertThat(retValues.size()).isEqualTo(2);
|
||||
assertThat(new String(retValues.get(0)))
|
||||
.isEqualTo("value");
|
||||
assertThat(new String(retValues.get(1)))
|
||||
.isEqualTo("value");
|
||||
} finally {
|
||||
for (final ColumnFamilyHandle columnFamilyHandle :
|
||||
columnFamilyHandleList) {
|
||||
columnFamilyHandle.close();
|
||||
}
|
||||
}
|
||||
assertThat(new String(retValues.get(0))).isEqualTo("value");
|
||||
assertThat(new String(retValues.get(1))).isEqualTo("value");
|
||||
}
|
||||
}
|
||||
|
||||
@ -476,30 +377,18 @@ public class ColumnFamilyTest {
|
||||
final RocksDB db = RocksDB.open(options,
|
||||
dbFolder.getRoot().getAbsolutePath(),
|
||||
cfDescriptors, columnFamilyHandleList)) {
|
||||
try {
|
||||
assertThat(db.getProperty("rocksdb.estimate-num-keys")).
|
||||
isNotNull();
|
||||
assertThat(db.getLongProperty(columnFamilyHandleList.get(0),
|
||||
"rocksdb.estimate-num-keys")).isGreaterThanOrEqualTo(0);
|
||||
assertThat(db.getProperty("rocksdb.estimate-num-keys")).isNotNull();
|
||||
assertThat(db.getLongProperty(columnFamilyHandleList.get(0), "rocksdb.estimate-num-keys"))
|
||||
.isGreaterThanOrEqualTo(0);
|
||||
assertThat(db.getProperty("rocksdb.stats")).isNotNull();
|
||||
assertThat(db.getProperty(columnFamilyHandleList.get(0),
|
||||
"rocksdb.sstables")).isNotNull();
|
||||
assertThat(db.getProperty(columnFamilyHandleList.get(1),
|
||||
"rocksdb.estimate-num-keys")).isNotNull();
|
||||
assertThat(db.getProperty(columnFamilyHandleList.get(1),
|
||||
"rocksdb.stats")).isNotNull();
|
||||
assertThat(db.getProperty(columnFamilyHandleList.get(1),
|
||||
"rocksdb.sstables")).isNotNull();
|
||||
assertThat(db.getAggregatedLongProperty("rocksdb.estimate-num-keys")).
|
||||
isNotNull();
|
||||
assertThat(db.getAggregatedLongProperty("rocksdb.estimate-num-keys")).
|
||||
isGreaterThanOrEqualTo(0);
|
||||
} finally {
|
||||
for (final ColumnFamilyHandle columnFamilyHandle :
|
||||
columnFamilyHandleList) {
|
||||
columnFamilyHandle.close();
|
||||
}
|
||||
}
|
||||
assertThat(db.getProperty(columnFamilyHandleList.get(0), "rocksdb.sstables")).isNotNull();
|
||||
assertThat(db.getProperty(columnFamilyHandleList.get(1), "rocksdb.estimate-num-keys"))
|
||||
.isNotNull();
|
||||
assertThat(db.getProperty(columnFamilyHandleList.get(1), "rocksdb.stats")).isNotNull();
|
||||
assertThat(db.getProperty(columnFamilyHandleList.get(1), "rocksdb.sstables")).isNotNull();
|
||||
assertThat(db.getAggregatedLongProperty("rocksdb.estimate-num-keys")).isNotNull();
|
||||
assertThat(db.getAggregatedLongProperty("rocksdb.estimate-num-keys"))
|
||||
.isGreaterThanOrEqualTo(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -547,10 +436,6 @@ public class ColumnFamilyTest {
|
||||
rocksIterator.close();
|
||||
}
|
||||
}
|
||||
for (final ColumnFamilyHandle columnFamilyHandle :
|
||||
columnFamilyHandleList) {
|
||||
columnFamilyHandle.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -566,15 +451,8 @@ public class ColumnFamilyTest {
|
||||
final RocksDB db = RocksDB.open(options,
|
||||
dbFolder.getRoot().getAbsolutePath(),
|
||||
cfDescriptors, columnFamilyHandleList)) {
|
||||
try {
|
||||
db.dropColumnFamily(columnFamilyHandleList.get(1));
|
||||
db.put(columnFamilyHandleList.get(1), "key".getBytes(),
|
||||
"value".getBytes());
|
||||
} finally {
|
||||
for (ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) {
|
||||
columnFamilyHandle.close();
|
||||
}
|
||||
}
|
||||
db.put(columnFamilyHandleList.get(1), "key".getBytes(), "value".getBytes());
|
||||
}
|
||||
}
|
||||
|
||||
@ -589,15 +467,8 @@ public class ColumnFamilyTest {
|
||||
final RocksDB db = RocksDB.open(options,
|
||||
dbFolder.getRoot().getAbsolutePath(),
|
||||
cfDescriptors, columnFamilyHandleList)) {
|
||||
try {
|
||||
db.dropColumnFamily(columnFamilyHandleList.get(1));
|
||||
db.delete(columnFamilyHandleList.get(1), "key".getBytes());
|
||||
} finally {
|
||||
for (final ColumnFamilyHandle columnFamilyHandle :
|
||||
columnFamilyHandleList) {
|
||||
columnFamilyHandle.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -612,15 +483,8 @@ public class ColumnFamilyTest {
|
||||
final RocksDB db = RocksDB.open(options,
|
||||
dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
|
||||
columnFamilyHandleList)) {
|
||||
try {
|
||||
db.dropColumnFamily(columnFamilyHandleList.get(1));
|
||||
db.get(columnFamilyHandleList.get(1), "key".getBytes());
|
||||
} finally {
|
||||
for (final ColumnFamilyHandle columnFamilyHandle :
|
||||
columnFamilyHandleList) {
|
||||
columnFamilyHandle.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -635,19 +499,11 @@ public class ColumnFamilyTest {
|
||||
final RocksDB db = RocksDB.open(options,
|
||||
dbFolder.getRoot().getAbsolutePath(), cfDescriptors,
|
||||
columnFamilyHandleList)) {
|
||||
try {
|
||||
final List<byte[]> keys = new ArrayList<>();
|
||||
keys.add("key".getBytes());
|
||||
keys.add("newcfkey".getBytes());
|
||||
final List<ColumnFamilyHandle> cfCustomList = new ArrayList<>();
|
||||
db.multiGetAsList(cfCustomList, keys);
|
||||
|
||||
} finally {
|
||||
for (final ColumnFamilyHandle columnFamilyHandle :
|
||||
columnFamilyHandleList) {
|
||||
columnFamilyHandle.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -661,25 +517,12 @@ public class ColumnFamilyTest {
|
||||
final byte[] b0 = new byte[]{(byte) 0x00};
|
||||
final byte[] b1 = new byte[]{(byte) 0x01};
|
||||
final byte[] b2 = new byte[]{(byte) 0x02};
|
||||
ColumnFamilyHandle cf1 = null, cf2 = null, cf3 = null;
|
||||
try {
|
||||
cf1 = db.createColumnFamily(new ColumnFamilyDescriptor(b0));
|
||||
cf2 = db.createColumnFamily(new ColumnFamilyDescriptor(b1));
|
||||
final List<byte[]> families = RocksDB.listColumnFamilies(options,
|
||||
dbFolder.getRoot().getAbsolutePath());
|
||||
db.createColumnFamily(new ColumnFamilyDescriptor(b0));
|
||||
db.createColumnFamily(new ColumnFamilyDescriptor(b1));
|
||||
final List<byte[]> families =
|
||||
RocksDB.listColumnFamilies(options, dbFolder.getRoot().getAbsolutePath());
|
||||
assertThat(families).contains("default".getBytes(), b0, b1);
|
||||
cf3 = db.createColumnFamily(new ColumnFamilyDescriptor(b2));
|
||||
} finally {
|
||||
if (cf1 != null) {
|
||||
cf1.close();
|
||||
}
|
||||
if (cf2 != null) {
|
||||
cf2.close();
|
||||
}
|
||||
if (cf3 != null) {
|
||||
cf3.close();
|
||||
}
|
||||
}
|
||||
db.createColumnFamily(new ColumnFamilyDescriptor(b2));
|
||||
}
|
||||
}
|
||||
|
||||
@ -690,22 +533,13 @@ public class ColumnFamilyTest {
|
||||
final RocksDB db = RocksDB.open(options,
|
||||
dbFolder.getRoot().getAbsolutePath());
|
||||
) {
|
||||
try {
|
||||
final byte[] b0 = new byte[] {0, 0};
|
||||
final byte[] b1 = new byte[] {0, 1};
|
||||
cf1 = db.createColumnFamily(new ColumnFamilyDescriptor(b0));
|
||||
cf2 = db.createColumnFamily(new ColumnFamilyDescriptor(b1));
|
||||
final List<byte[]> families = RocksDB.listColumnFamilies(options,
|
||||
dbFolder.getRoot().getAbsolutePath());
|
||||
final List<byte[]> families =
|
||||
RocksDB.listColumnFamilies(options, dbFolder.getRoot().getAbsolutePath());
|
||||
assertThat(families).contains("default".getBytes(), b0, b1);
|
||||
} finally {
|
||||
if (cf1 != null) {
|
||||
cf1.close();
|
||||
}
|
||||
if (cf2 != null) {
|
||||
cf2.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -716,17 +550,57 @@ public class ColumnFamilyTest {
|
||||
final RocksDB db = RocksDB.open(options,
|
||||
dbFolder.getRoot().getAbsolutePath());
|
||||
) {
|
||||
try {
|
||||
final String simplifiedChinese = "\u7b80\u4f53\u5b57";
|
||||
columnFamilyHandle = db.createColumnFamily(
|
||||
new ColumnFamilyDescriptor(simplifiedChinese.getBytes()));
|
||||
columnFamilyHandle =
|
||||
db.createColumnFamily(new ColumnFamilyDescriptor(simplifiedChinese.getBytes()));
|
||||
|
||||
final List<byte[]> families = RocksDB.listColumnFamilies(options,
|
||||
dbFolder.getRoot().getAbsolutePath());
|
||||
assertThat(families).contains("default".getBytes(),
|
||||
simplifiedChinese.getBytes());
|
||||
final List<byte[]> families =
|
||||
RocksDB.listColumnFamilies(options, dbFolder.getRoot().getAbsolutePath());
|
||||
assertThat(families).contains("default".getBytes(), simplifiedChinese.getBytes());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDestroyColumnFamilyHandle() throws RocksDBException {
|
||||
try (final Options options = new Options().setCreateIfMissing(true);
|
||||
final RocksDB db = RocksDB.open(options, dbFolder.getRoot().getAbsolutePath());) {
|
||||
final byte[] name1 = "cf1".getBytes();
|
||||
final byte[] name2 = "cf2".getBytes();
|
||||
final ColumnFamilyDescriptor desc1 = new ColumnFamilyDescriptor(name1);
|
||||
final ColumnFamilyDescriptor desc2 = new ColumnFamilyDescriptor(name2);
|
||||
final ColumnFamilyHandle cf1 = db.createColumnFamily(desc1);
|
||||
final ColumnFamilyHandle cf2 = db.createColumnFamily(desc2);
|
||||
assertTrue(cf1.isOwningHandle());
|
||||
assertTrue(cf2.isOwningHandle());
|
||||
assertFalse(cf1.isDefaultColumnFamily());
|
||||
db.destroyColumnFamilyHandle(cf1);
|
||||
// At this point cf1 should not be used!
|
||||
assertFalse(cf1.isOwningHandle());
|
||||
assertTrue(cf2.isOwningHandle());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Deprecated
|
||||
/**
|
||||
* @deprecated Now explicitly closing instances of ColumnFamilyHandle is not required.
|
||||
* RocksDB instance will take care of closing its associated ColumnFamilyHandle objects.
|
||||
*/
|
||||
public void testColumnFamilyCloseBeforeDb() throws RocksDBException {
|
||||
final List<ColumnFamilyDescriptor> cfNames =
|
||||
Arrays.asList(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
|
||||
new ColumnFamilyDescriptor("new_cf".getBytes()));
|
||||
final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
|
||||
|
||||
try (final DBOptions options =
|
||||
new DBOptions().setCreateIfMissing(true).setCreateMissingColumnFamilies(true);
|
||||
final RocksDB db = RocksDB.open(
|
||||
options, dbFolder.getRoot().getAbsolutePath(), cfNames, columnFamilyHandleList)) {
|
||||
try {
|
||||
db.put("testKey".getBytes(), "tstValue".getBytes());
|
||||
// Do something...
|
||||
} finally {
|
||||
if (columnFamilyHandle != null) {
|
||||
for (final ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) {
|
||||
columnFamilyHandle.close();
|
||||
}
|
||||
}
|
||||
|
@ -39,10 +39,8 @@ public class CompactionFilterFactoryTest {
|
||||
|
||||
final List<ColumnFamilyHandle> cfHandles = new ArrayList<>();
|
||||
|
||||
try (final RocksDB rocksDb = RocksDB.open(options,
|
||||
dbFolder.getRoot().getAbsolutePath(), cfNames, cfHandles);
|
||||
) {
|
||||
try {
|
||||
try (final RocksDB rocksDb =
|
||||
RocksDB.open(options, dbFolder.getRoot().getAbsolutePath(), cfNames, cfHandles)) {
|
||||
final byte[] key1 = "key1".getBytes();
|
||||
final byte[] key2 = "key2".getBytes();
|
||||
|
||||
@ -57,11 +55,6 @@ public class CompactionFilterFactoryTest {
|
||||
assertThat(rocksDb.get(cfHandles.get(1), key1)).isEqualTo(value1);
|
||||
final boolean exists = rocksDb.keyMayExist(cfHandles.get(1), key2, null);
|
||||
assertThat(exists).isFalse();
|
||||
} finally {
|
||||
for (final ColumnFamilyHandle cfHandle : cfHandles) {
|
||||
cfHandle.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user