diff --git a/include/rocksdb/persistent_cache.h b/include/rocksdb/persistent_cache.h index ef49da5ab..8d01fa1bd 100644 --- a/include/rocksdb/persistent_cache.h +++ b/include/rocksdb/persistent_cache.h @@ -9,7 +9,9 @@ #include #include +#include +#include "rocksdb/env.h" #include "rocksdb/slice.h" #include "rocksdb/statistics.h" #include "rocksdb/status.h" @@ -46,4 +48,10 @@ class PersistentCache { virtual bool IsCompressed() = 0; }; +// Factor method to create a new persistent cache +Status NewPersistentCache(Env* const env, const std::string& path, + const uint64_t size, + const std::shared_ptr& log, + const bool optimized_for_nvm, + std::shared_ptr* cache); } // namespace rocksdb diff --git a/utilities/persistent_cache/block_cache_tier.cc b/utilities/persistent_cache/block_cache_tier.cc index 02b90e68d..49a70174c 100644 --- a/utilities/persistent_cache/block_cache_tier.cc +++ b/utilities/persistent_cache/block_cache_tier.cc @@ -359,6 +359,36 @@ bool BlockCacheTier::Reserve(const size_t size) { return true; } +Status NewPersistentCache(Env* const env, const std::string& path, + const uint64_t size, + const std::shared_ptr& log, + const bool optimized_for_nvm, + std::shared_ptr* cache) { + if (!cache) { + return Status::IOError("invalid argument cache"); + } + + auto opt = PersistentCacheConfig(env, path, size, log); + if (optimized_for_nvm) { + // the default settings are optimized for SSD + // NVM devices are better accessed with 4K direct IO and written with + // parallelism + opt.enable_direct_writes = true; + opt.writer_qdepth = 4; + opt.writer_dispatch_size = 4 * 1024; + } + + auto pcache = std::make_shared(opt); + Status s = pcache->Open(); + + if (!s.ok()) { + return s; + } + + *cache = pcache; + return s; +} + } // namespace rocksdb #endif // ifndef ROCKSDB_LITE diff --git a/utilities/persistent_cache/block_cache_tier.h b/utilities/persistent_cache/block_cache_tier.h index cc917c0f4..9330d0538 100644 --- a/utilities/persistent_cache/block_cache_tier.h +++ b/utilities/persistent_cache/block_cache_tier.h @@ -49,8 +49,8 @@ class BlockCacheTier : public PersistentCacheTier { } virtual ~BlockCacheTier() { - // By contract, the user should have called stop before destroying the - // object + // Close is re-entrant so we can call close even if it is already closed + Close(); assert(!insert_th_.joinable()); } diff --git a/utilities/persistent_cache/persistent_cache_test.cc b/utilities/persistent_cache/persistent_cache_test.cc index ad4a6fd59..0d8ab6971 100644 --- a/utilities/persistent_cache/persistent_cache_test.cc +++ b/utilities/persistent_cache/persistent_cache_test.cc @@ -235,6 +235,19 @@ static void UniqueIdCallback(void* arg) { } #endif +TEST_F(PersistentCacheTierTest, FactoryTest) { + for (auto nvm_opt : {true, false}) { + ASSERT_FALSE(cache_); + auto log = std::make_shared(); + std::shared_ptr cache; + ASSERT_OK(NewPersistentCache(Env::Default(), path_, + /*size=*/1 * 1024 * 1024 * 1024, log, nvm_opt, + &cache)); + ASSERT_TRUE(cache); + cache.reset(); + } +} + PersistentCacheDBTest::PersistentCacheDBTest() : DBTestBase("/cache_test") { #ifdef OS_LINUX rocksdb::SyncPoint::GetInstance()->EnableProcessing(); @@ -403,6 +416,7 @@ TEST_F(PersistentCacheDBTest, TieredCacheTest) { RunTest(std::bind(&MakeTieredCache, dbname_)); } #endif + } // namespace rocksdb int main(int argc, char** argv) {