DeleteRange() return NotSupported if row_cache is configured (#12512)

Summary:
...since this feature combination is not supported yet (https://github.com/facebook/rocksdb/issues/4122).

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

Test Plan: new unit test.

Reviewed By: jaykorean, jowlyzhang

Differential Revision: D55820323

Pulled By: cbi42

fbshipit-source-id: eeb5e97d15c9bdc388793a2fb8e52cfa47e34bcf
This commit is contained in:
Changyu Bi 2024-04-29 16:33:13 -07:00 committed by Facebook GitHub Bot
parent b2931a5c53
commit 5c1334f763
8 changed files with 40 additions and 7 deletions

View file

@ -464,12 +464,14 @@ TEST_F(DBBasicTest, TimedPutBasic) {
ASSERT_EQ("bv1", Get(1, "bar")); ASSERT_EQ("bv1", Get(1, "bar"));
ASSERT_OK(TimedPut(1, "baz", "bzv1", /*write_unix_time=*/0)); ASSERT_OK(TimedPut(1, "baz", "bzv1", /*write_unix_time=*/0));
ASSERT_EQ("bzv1", Get(1, "baz")); ASSERT_EQ("bzv1", Get(1, "baz"));
std::string range_del_begin = "b"; if (option_config_ != kRowCache) {
std::string range_del_end = "baz"; std::string range_del_begin = "b";
Slice begin_rdel = range_del_begin, end_rdel = range_del_end; std::string range_del_end = "baz";
ASSERT_OK( Slice begin_rdel = range_del_begin, end_rdel = range_del_end;
db_->DeleteRange(WriteOptions(), handles_[1], begin_rdel, end_rdel)); ASSERT_OK(
ASSERT_EQ("NOT_FOUND", Get(1, "bar")); db_->DeleteRange(WriteOptions(), handles_[1], begin_rdel, end_rdel));
ASSERT_EQ("NOT_FOUND", Get(1, "bar"));
}
ASSERT_EQ("bzv1", Get(1, "baz")); ASSERT_EQ("bzv1", Get(1, "baz"));
ASSERT_OK(SingleDelete(1, "baz")); ASSERT_OK(SingleDelete(1, "baz"));

View file

@ -3806,6 +3806,21 @@ TEST_F(DBRangeDelTest, RefreshWithSnapshot) {
iter.reset(); iter.reset();
db_->ReleaseSnapshot(snapshot); db_->ReleaseSnapshot(snapshot);
} }
TEST_F(DBRangeDelTest, RowCache) {
Options options = CurrentOptions();
options.row_cache = NewLRUCache(8 << 10);
DestroyAndReopen(options);
ASSERT_OK(Put(Key(3), "val"));
ASSERT_TRUE(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
Key(3), Key(5))
.IsNotSupported());
WriteBatch wb;
ASSERT_OK(wb.Put(Key(6), "abc"));
ASSERT_OK(wb.DeleteRange(Key(1), Key(5)));
ASSERT_TRUE(db_->Write(WriteOptions(), &wb).IsNotSupported());
ASSERT_EQ(Get(Key(3)), "val");
}
} // namespace ROCKSDB_NAMESPACE } // namespace ROCKSDB_NAMESPACE
int main(int argc, char** argv) { int main(int argc, char** argv) {

View file

@ -154,6 +154,9 @@ bool DBTestBase::ShouldSkipOptions(int option_config, int skip_mask) {
if ((skip_mask & kSkipMmapReads) && option_config == kWalDirAndMmapReads) { if ((skip_mask & kSkipMmapReads) && option_config == kWalDirAndMmapReads) {
return true; return true;
} }
if ((skip_mask & kSkipRowCache) && option_config == kRowCache) {
return true;
}
return false; return false;
} }

View file

@ -1071,6 +1071,7 @@ class DBTestBase : public testing::Test {
kSkipNoSeekToLast = 32, kSkipNoSeekToLast = 32,
kSkipFIFOCompaction = 128, kSkipFIFOCompaction = 128,
kSkipMmapReads = 256, kSkipMmapReads = 256,
kSkipRowCache = 512,
}; };
const int kRangeDelSkipConfigs = const int kRangeDelSkipConfigs =
@ -1078,7 +1079,9 @@ class DBTestBase : public testing::Test {
kSkipPlainTable | kSkipPlainTable |
// MmapReads disables the iterator pinning that RangeDelAggregator // MmapReads disables the iterator pinning that RangeDelAggregator
// requires. // requires.
kSkipMmapReads; kSkipMmapReads |
// Not compatible yet.
kSkipRowCache;
// `env_do_fsync` decides whether the special Env would do real // `env_do_fsync` decides whether the special Env would do real
// fsync for files and directories. Skipping fsync can speed up // fsync for files and directories. Skipping fsync can speed up

View file

@ -2514,6 +2514,11 @@ class MemTableInserter : public WriteBatch::Handler {
assert(ret_status.ok()); assert(ret_status.ok());
if (db_ != nullptr) { if (db_ != nullptr) {
if (db_->immutable_db_options().row_cache) {
ret_status.PermitUncheckedError();
return Status::NotSupported(
"DeleteRange is not compatible with row cache.");
}
auto cf_handle = cf_mems_->GetColumnFamilyHandle(); auto cf_handle = cf_mems_->GetColumnFamilyHandle();
if (cf_handle == nullptr) { if (cf_handle == nullptr) {
cf_handle = db_->DefaultColumnFamily(); cf_handle = db_->DefaultColumnFamily();

View file

@ -541,6 +541,8 @@ class DB {
// 2) Limiting the maximum number of open files in the presence of range // 2) Limiting the maximum number of open files in the presence of range
// tombstones can degrade read performance. To avoid this problem, set // tombstones can degrade read performance. To avoid this problem, set
// max_open_files to -1 whenever possible. // max_open_files to -1 whenever possible.
// 3) Incompatible with row_cache, will return Status::NotSupported() if
// row_cache is configured.
virtual Status DeleteRange(const WriteOptions& options, virtual Status DeleteRange(const WriteOptions& options,
ColumnFamilyHandle* column_family, ColumnFamilyHandle* column_family,
const Slice& begin_key, const Slice& end_key); const Slice& begin_key, const Slice& end_key);

View file

@ -1223,6 +1223,8 @@ struct DBOptions {
bool allow_2pc = false; bool allow_2pc = false;
// A global cache for table-level rows. // A global cache for table-level rows.
// Used to speed up Get() queries.
// NOTE: does not work with DeleteRange() yet.
// Default: nullptr (disabled) // Default: nullptr (disabled)
std::shared_ptr<RowCache> row_cache = nullptr; std::shared_ptr<RowCache> row_cache = nullptr;

View file

@ -0,0 +1 @@
* DeleteRange() will return NotSupported() if row_cache is configured since they don't work together in some cases.