NPE in Java_org_rocksdb_ColumnFamilyOptions_setSstPartitionerFactory (#9622)

Summary:
There was a mistake that incorrectly cast SstPartitionerFactory (missed shared pointer). It worked for database (correct cast), but not for family. Trying to set it in family has caused Access violation.

I have also added test and improved it. Older version was passing even without sst partitioner which is weird, because on Level1 we had two SST files with same key "aaaa1". I was not sure if it is a new feature and changed it to overlaping keys "aaaa0" - "aaaa2" overlaps "aaaa1".

Pull Request resolved: https://github.com/facebook/rocksdb/pull/9622

Reviewed By: ajkr

Differential Revision: D34871968

Pulled By: pdillinger

fbshipit-source-id: a08009766da49fc198692a610e8beb19caf737e6
This commit is contained in:
Tomas Kolda 2022-03-14 14:12:30 -07:00 committed by Andrew Kryczka
parent 348414d502
commit 9db48d6e08
2 changed files with 34 additions and 4 deletions

View File

@ -4260,9 +4260,10 @@ void Java_org_rocksdb_ColumnFamilyOptions_setSstPartitionerFactory(
JNIEnv*, jobject, jlong jhandle, jlong factory_handle) {
auto* options =
reinterpret_cast<ROCKSDB_NAMESPACE::ColumnFamilyOptions*>(jhandle);
auto* factory = reinterpret_cast<ROCKSDB_NAMESPACE::SstPartitionerFactory*>(
auto factory = reinterpret_cast<
std::shared_ptr<ROCKSDB_NAMESPACE::SstPartitionerFactory>*>(
factory_handle);
options->sst_partitioner_factory.reset(factory);
options->sst_partitioner_factory = *factory;
}
/*

View File

@ -5,6 +5,7 @@
package org.rocksdb;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.List;
@ -21,7 +22,7 @@ public class SstPartitionerTest {
@Rule public TemporaryFolder dbFolder = new TemporaryFolder();
@Test
public void sstFixedPrefix() throws InterruptedException, RocksDBException {
public void sstFixedPrefix() throws RocksDBException {
try (SstPartitionerFixedPrefixFactory factory = new SstPartitionerFixedPrefixFactory(4);
final Options opt =
new Options().setCreateIfMissing(true).setSstPartitionerFactory(factory);
@ -31,7 +32,8 @@ public class SstPartitionerTest {
db.put("bbbb1".getBytes(), "B".getBytes());
db.flush(new FlushOptions());
db.put("aaaa1".getBytes(), "A2".getBytes());
db.put("aaaa0".getBytes(), "A2".getBytes());
db.put("aaaa2".getBytes(), "A2".getBytes());
db.flush(new FlushOptions());
db.compactRange();
@ -40,4 +42,31 @@ public class SstPartitionerTest {
assertThat(metadata.size()).isEqualTo(2);
}
}
@Test
public void sstFixedPrefixFamily() throws RocksDBException {
final byte[] cfName = "new_cf".getBytes(UTF_8);
final ColumnFamilyDescriptor cfDescriptor = new ColumnFamilyDescriptor(cfName,
new ColumnFamilyOptions().setSstPartitionerFactory(
new SstPartitionerFixedPrefixFactory(4)));
try (final Options opt = new Options().setCreateIfMissing(true);
final RocksDB db = RocksDB.open(opt, dbFolder.getRoot().getAbsolutePath())) {
final ColumnFamilyHandle columnFamilyHandle = db.createColumnFamily(cfDescriptor);
// writing (long)100 under key
db.put(columnFamilyHandle, "aaaa1".getBytes(), "A".getBytes());
db.put(columnFamilyHandle, "bbbb1".getBytes(), "B".getBytes());
db.flush(new FlushOptions(), columnFamilyHandle);
db.put(columnFamilyHandle, "aaaa0".getBytes(), "A2".getBytes());
db.put(columnFamilyHandle, "aaaa2".getBytes(), "A2".getBytes());
db.flush(new FlushOptions(), columnFamilyHandle);
db.compactRange(columnFamilyHandle);
List<LiveFileMetaData> metadata = db.getLiveFilesMetaData();
assertThat(metadata.size()).isEqualTo(2);
}
}
}