This is an automated email from the ASF dual-hosted git repository.
alexey pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kudu.git
The following commit(s) were added to refs/heads/master by this push:
new 4b5003add KUDU-613: Integrate SLRU cache into block cache
4b5003add is described below
commit 4b5003add94e382278942489ef51662967b66197
Author: Mahesh Reddy <[email protected]>
AuthorDate: Tue Apr 2 15:36:42 2024 -0400
KUDU-613: Integrate SLRU cache into block cache
This patch integrates the new SLRU cache into the
block cache. It adds several flags to make the SLRU
cache configurable for capacity and lookups as well
as adding an eviction_policy flag to give users
the option to use the new SLRU cache. The default
value is still the old LRU cache.
Many integration tests that use the block cache
are also updated to include the block cache of
SLRU eviction policy.
Change-Id: I04411ab2756045f15a272f3397d46d871b087b03
Reviewed-on: http://gerrit.cloudera.org:8080/21390
Reviewed-by: Alexey Serbin <[email protected]>
Tested-by: Alexey Serbin <[email protected]>
---
src/kudu/cfile/block_cache-test.cc | 39 ++++-
src/kudu/cfile/block_cache.cc | 173 +++++++++++++++++----
src/kudu/cfile/block_cache.h | 32 +++-
src/kudu/cfile/cfile-test.cc | 103 +++++++-----
src/kudu/integration-tests/dense_node-itest.cc | 23 ++-
.../full_stack-insert-scan-test.cc | 24 ++-
.../heavy-update-compaction-itest.cc | 20 ++-
src/kudu/tserver/tablet_server-stress-test.cc | 23 ++-
8 files changed, 350 insertions(+), 87 deletions(-)
diff --git a/src/kudu/cfile/block_cache-test.cc
b/src/kudu/cfile/block_cache-test.cc
index bf87339e4..fd3ac48c2 100644
--- a/src/kudu/cfile/block_cache-test.cc
+++ b/src/kudu/cfile/block_cache-test.cc
@@ -27,10 +27,14 @@
#include <glog/logging.h>
#include <gtest/gtest.h>
+#include "kudu/gutil/singleton.h"
#include "kudu/util/cache.h"
#include "kudu/util/mem_tracker.h"
#include "kudu/util/slice.h"
+#include "kudu/util/string_case.h"
+#include "kudu/util/test_util.h"
+DECLARE_string(block_cache_eviction_policy);
DECLARE_double(cache_memtracker_approximation_ratio);
namespace kudu {
@@ -38,34 +42,53 @@ namespace cfile {
static const char* const kDataToCache = "hello world";
-TEST(TestBlockCache, TestBasics) {
+class BlockCacheTest :
+ public KuduTest,
+ public ::testing::WithParamInterface<std::string> {
+ protected:
+ void SetUp() override {
+ FLAGS_block_cache_eviction_policy = GetParam();
+ }
+
+ void TearDown() override {
+ Singleton<BlockCache>::UnsafeReset();
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(EvictionPolicyTypes, BlockCacheTest,
+ ::testing::Values("LRU", "SLRU"));
+
+TEST_P(BlockCacheTest, TestBasics) {
// Disable approximate tracking of cache memory since we make specific
// assertions on the MemTracker in this test.
FLAGS_cache_memtracker_approximation_ratio = 0;
size_t data_size = strlen(kDataToCache) + 1;
- BlockCache cache(512 * 1024 * 1024);
+ BlockCache* cache = BlockCache::GetSingleton();
BlockCache::FileId id(1234);
BlockCache::CacheKey key(id, 1);
std::shared_ptr<MemTracker> mem_tracker;
if (BlockCache::GetConfiguredCacheMemoryTypeOrDie() ==
Cache::MemoryType::DRAM) {
- ASSERT_TRUE(MemTracker::FindTracker("block_cache-sharded_lru_cache",
&mem_tracker));
+ std::string eviction_policy;
+ ToLowerCase(GetParam(), &eviction_policy);
+ std::string memTrackerName = "block_cache-sharded_" + eviction_policy +
"_cache";
+ ASSERT_TRUE(MemTracker::FindTracker(memTrackerName, &mem_tracker));
}
// Lookup something missing from cache
{
BlockCacheHandle handle;
- ASSERT_FALSE(cache.Lookup(key, Cache::EXPECT_IN_CACHE, &handle));
+ ASSERT_FALSE(cache->Lookup(key, Cache::EXPECT_IN_CACHE, &handle));
ASSERT_FALSE(handle.valid());
}
- BlockCache::PendingEntry data = cache.Allocate(key, data_size);
+ BlockCache::PendingEntry data = cache->Allocate(key, data_size);
memcpy(data.val_ptr(), kDataToCache, data_size);
// Insert and re-lookup
BlockCacheHandle inserted_handle;
- cache.Insert(&data, &inserted_handle);
+ cache->Insert(&data, &inserted_handle);
ASSERT_FALSE(data.valid());
ASSERT_TRUE(inserted_handle.valid());
@@ -76,7 +99,7 @@ TEST(TestBlockCache, TestBasics) {
}
BlockCacheHandle retrieved_handle;
- ASSERT_TRUE(cache.Lookup(key, Cache::EXPECT_IN_CACHE, &retrieved_handle));
+ ASSERT_TRUE(cache->Lookup(key, Cache::EXPECT_IN_CACHE, &retrieved_handle));
ASSERT_TRUE(retrieved_handle.valid());
ASSERT_EQ(0, memcmp(retrieved_handle.data().data(), kDataToCache,
data_size));
@@ -84,7 +107,7 @@ TEST(TestBlockCache, TestBasics) {
// Ensure that a lookup for a different offset doesn't
// return this data.
BlockCache::CacheKey key1(id, 3);
- ASSERT_FALSE(cache.Lookup(key1, Cache::EXPECT_IN_CACHE, &retrieved_handle));
+ ASSERT_FALSE(cache->Lookup(key1, Cache::EXPECT_IN_CACHE, &retrieved_handle));
}
diff --git a/src/kudu/cfile/block_cache.cc b/src/kudu/cfile/block_cache.cc
index 29b2c21b2..4ece823d2 100644
--- a/src/kudu/cfile/block_cache.cc
+++ b/src/kudu/cfile/block_cache.cc
@@ -17,6 +17,7 @@
#include "kudu/cfile/block_cache.h"
+#include <cmath>
#include <cstddef>
#include <cstdint>
#include <memory>
@@ -35,11 +36,31 @@
#include "kudu/util/flag_validators.h"
#include "kudu/util/process_memory.h"
#include "kudu/util/slice.h"
+#include "kudu/util/slru_cache.h"
#include "kudu/util/string_case.h"
DEFINE_int64(block_cache_capacity_mb, 512, "block cache capacity in MB");
TAG_FLAG(block_cache_capacity_mb, stable);
+DEFINE_string(block_cache_eviction_policy, "LRU",
+ "Eviction policy used for block cache. "
+ "Either 'LRU' (default) or 'SLRU' (experimental).");
+TAG_FLAG(block_cache_eviction_policy, advanced);
+TAG_FLAG(block_cache_eviction_policy, experimental);
+
+DEFINE_double(block_cache_protected_segment_percentage, 0.8,
+ "Percentage of 'block_cache_capacity_mb' that's the protected
segment's capacity. "
+ "Ex. For the default parameters of 0.8 for this flag and 512 MB
for "
+ "'block_cache_capacity_mb', the protected segment will be 0.8 *
512 = 410 MB."
+ "Must be >= 0 and <= 1.");
+TAG_FLAG(block_cache_protected_segment_percentage, experimental);
+
+DEFINE_uint32(block_cache_lookups_before_upgrade, 2,
+ "Number of lookups before entry is upgraded from probationary to
protected segment. "
+ "Must be > 0.");
+TAG_FLAG(block_cache_lookups_before_upgrade, experimental);
+
+
// Yes, it's strange: the default value is 'true' but that's intentional.
// The idea is to avoid the corresponding group flag validator striking
// while running anything but master and tserver. As for the master and
tserver,
@@ -61,6 +82,8 @@ DEFINE_string(block_cache_type, "DRAM",
DECLARE_uint32(log_container_rdb_block_cache_capacity_mb);
#endif
+using std::string;
+using std::unique_ptr;
using strings::Substitute;
template <class T> class scoped_refptr;
@@ -73,31 +96,24 @@ namespace cfile {
namespace {
-Cache* CreateCache(int64_t capacity) {
- const auto mem_type = BlockCache::GetConfiguredCacheMemoryTypeOrDie();
- switch (mem_type) {
- case Cache::MemoryType::DRAM:
- return NewCache<Cache::EvictionPolicy::LRU, Cache::MemoryType::DRAM>(
- capacity, "block_cache");
- case Cache::MemoryType::NVM:
- return NewCache<Cache::EvictionPolicy::LRU, Cache::MemoryType::NVM>(
- capacity, "block_cache");
- default:
- LOG(FATAL) << "unsupported LRU cache memory type: " << mem_type;
- return nullptr;
- }
+string ToUpper(const string& input) {
+ string temp;
+ ToUpperCase(input, &temp);
+ return temp;
}
} // anonymous namespace
bool ValidateBlockCacheCapacity() {
- if (FLAGS_force_block_cache_capacity) {
- return true;
- }
- if (FLAGS_block_cache_type != "DRAM") {
+ if (FLAGS_force_block_cache_capacity || ToUpper(FLAGS_block_cache_type) !=
"DRAM") {
return true;
}
+
int64_t capacity = FLAGS_block_cache_capacity_mb * 1024 * 1024;
+ if (capacity < 0) {
+ LOG(ERROR) << Substitute("Block cache capacity must be > 0. It's $0
bytes.", capacity);
+ }
+
int64_t mpt = process_memory::MemoryPressureThreshold();
if (capacity > mpt) {
LOG(ERROR) << Substitute("Block cache capacity exceeds the memory pressure
"
@@ -130,32 +146,130 @@ bool ValidateBlockCacheCapacity() {
#endif
return true;
}
+GROUP_FLAG_VALIDATOR(block_cache_capacity_mb, ValidateBlockCacheCapacity);
+bool ValidateBlockCacheSegmentCapacity() {
+ if (FLAGS_force_block_cache_capacity ||
+ ToUpper(FLAGS_block_cache_type) != "DRAM" ||
+ ToUpper(FLAGS_block_cache_eviction_policy) == "LRU") {
+ return true;
+ }
-GROUP_FLAG_VALIDATOR(block_cache_capacity_mb, ValidateBlockCacheCapacity);
+ const auto& percentage = FLAGS_block_cache_protected_segment_percentage;
+ if (percentage < 0 || percentage > 1) {
+ LOG(ERROR) << Substitute("FLAGS_block_cache_protected_segment_percentage
must be >= 0 "
+ "and <= 1. It's $0.", percentage);
+ return false;
+ }
+ return true;
+}
+GROUP_FLAG_VALIDATOR(block_cache_protected_segment_percentage,
ValidateBlockCacheSegmentCapacity);
+
+bool ValidateLookups() {
+ if (ToUpper(FLAGS_block_cache_eviction_policy) == "LRU") {
+ return true;
+ }
+
+ uint32_t lookups = FLAGS_block_cache_lookups_before_upgrade;
+ if (lookups == 0) {
+ LOG(ERROR) << Substitute("Number of lookups for SLRU cache must be > 0");
+ return false;
+ }
+ return true;
+}
+GROUP_FLAG_VALIDATOR(block_cache_lookups_before_upgrade, ValidateLookups);
+
+bool ValidateEvictionPolicy() {
+ const auto& eviction_policy = ToUpper(FLAGS_block_cache_eviction_policy);
+ return eviction_policy == "LRU" || eviction_policy == "SLRU";
+}
+GROUP_FLAG_VALIDATOR(block_cache_eviction_policy, ValidateEvictionPolicy);
+
+Cache* BlockCache::CreateCache(int64_t capacity) {
+ const auto& mem_type = BlockCache::GetConfiguredCacheMemoryTypeOrDie();
+ switch (mem_type) {
+ case Cache::MemoryType::DRAM:
+ return NewCache<Cache::EvictionPolicy::LRU, Cache::MemoryType::DRAM>(
+ capacity, "block_cache");
+ case Cache::MemoryType::NVM:
+ return NewCache<Cache::EvictionPolicy::LRU, Cache::MemoryType::NVM>(
+ capacity, "block_cache");
+ default:
+ LOG(FATAL) << "unsupported LRU cache memory type: " << mem_type;
+ return nullptr;
+ }
+}
+
+Cache* BlockCache::CreateCache(int64_t probationary_segment_capacity,
+ int64_t protected_segment_capacity,
+ uint32_t lookups) {
+ const auto& mem_type = BlockCache::GetConfiguredCacheMemoryTypeOrDie();
+ switch (mem_type) {
+ case Cache::MemoryType::DRAM:
+ return NewSLRUCache<Cache::MemoryType::DRAM>(
+ probationary_segment_capacity, protected_segment_capacity,
"block_cache", lookups);
+ default:
+ LOG(FATAL) << "unsupported SLRU cache memory type: " << mem_type;
+ return nullptr;
+ }
+}
Cache::MemoryType BlockCache::GetConfiguredCacheMemoryTypeOrDie() {
- ToUpperCase(FLAGS_block_cache_type, &FLAGS_block_cache_type);
- if (FLAGS_block_cache_type == "NVM") {
+ const auto& memory_type = ToUpper(FLAGS_block_cache_type);
+ if (memory_type == "NVM") {
return Cache::MemoryType::NVM;
}
- if (FLAGS_block_cache_type == "DRAM") {
+ if (memory_type == "DRAM") {
return Cache::MemoryType::DRAM;
}
- LOG(FATAL) << "Unknown block cache type: '" << FLAGS_block_cache_type
+ LOG(FATAL) << "Unknown block cache type: '" << memory_type
<< "' (expected 'DRAM' or 'NVM')";
__builtin_unreachable();
}
-BlockCache::BlockCache()
- : BlockCache(FLAGS_block_cache_capacity_mb * 1024 * 1024) {
+Cache::EvictionPolicy BlockCache::GetCacheEvictionPolicyOrDie() {
+ const auto& eviction_policy = ToUpper(FLAGS_block_cache_eviction_policy);
+ if (eviction_policy == "LRU") {
+ return Cache::EvictionPolicy::LRU;
+ }
+ if (eviction_policy == "SLRU") {
+ return Cache::EvictionPolicy::SLRU;
+ }
+
+ LOG(FATAL) << "Unknown block cache eviction policy: '" << eviction_policy
+ << "' (expected 'LRU' or 'SLRU')";
+ __builtin_unreachable();
+}
+
+BlockCache::BlockCache() {
+ const auto& eviction_policy = GetCacheEvictionPolicyOrDie();
+ if (eviction_policy == Cache::EvictionPolicy::LRU) {
+ unique_ptr<Cache> lru_cache(CreateCache(FLAGS_block_cache_capacity_mb *
1024 * 1024));
+ cache_ = std::move(lru_cache);
+ } else {
+ DCHECK(eviction_policy == Cache::EvictionPolicy::SLRU);
+ int64_t probationary_capacity =
+ static_cast<int>(std::round((1.0 -
FLAGS_block_cache_protected_segment_percentage)
+ * 1024 * 1024));
+ int64_t protected_capacity =
+
static_cast<int>(std::round(FLAGS_block_cache_protected_segment_percentage *
1024 * 1024));
+ unique_ptr<Cache> slru_cache(CreateCache(probationary_capacity,
protected_capacity,
+
FLAGS_block_cache_lookups_before_upgrade));
+ cache_ = std::move(slru_cache);
+ }
}
BlockCache::BlockCache(size_t capacity)
: cache_(CreateCache(capacity)) {
}
+BlockCache::BlockCache(size_t probationary_segment_capacity,
+ size_t protected_segment_capacity,
+ size_t lookups)
+ : cache_(CreateCache(probationary_segment_capacity,
protected_segment_capacity, lookups)) {
+}
+
BlockCache::PendingEntry BlockCache::Allocate(const CacheKey& key, size_t
block_size) {
Slice key_slice(reinterpret_cast<const uint8_t*>(&key), sizeof(key));
return PendingEntry(cache_->Allocate(key_slice, block_size));
@@ -180,8 +294,15 @@ void BlockCache::Insert(BlockCache::PendingEntry* entry,
BlockCacheHandle* inser
void BlockCache::StartInstrumentation(const scoped_refptr<MetricEntity>&
metric_entity,
Cache::ExistingMetricsPolicy
metrics_policy) {
- std::unique_ptr<BlockCacheMetrics> metrics(new
BlockCacheMetrics(metric_entity));
- cache_->SetMetrics(std::move(metrics), metrics_policy);
+ const auto& eviction_policy = GetCacheEvictionPolicyOrDie();
+ if (eviction_policy == Cache::EvictionPolicy::LRU) {
+ unique_ptr<BlockCacheMetrics> metrics(new
BlockCacheMetrics(metric_entity));
+ cache_->SetMetrics(std::move(metrics), metrics_policy);
+ } else {
+ DCHECK(eviction_policy == Cache::EvictionPolicy::SLRU);
+ unique_ptr<SLRUCacheMetrics> metrics(new SLRUCacheMetrics(metric_entity));
+ cache_->SetMetrics(std::move(metrics), metrics_policy);
+ }
}
} // namespace cfile
diff --git a/src/kudu/cfile/block_cache.h b/src/kudu/cfile/block_cache.h
index 2deb716b6..4a22753a4 100644
--- a/src/kudu/cfile/block_cache.h
+++ b/src/kudu/cfile/block_cache.h
@@ -21,6 +21,8 @@
#include <memory>
#include <utility>
+#include <gtest/gtest_prod.h>
+
#include "kudu/fs/block_id.h"
#include "kudu/gutil/macros.h"
#include "kudu/gutil/port.h"
@@ -42,10 +44,6 @@ class BlockCacheHandle;
// Provides a singleton and LRU cache for CFile blocks.
class BlockCache {
public:
- // Parse the gflag which configures the block cache. FATALs if the flag is
- // invalid.
- static Cache::MemoryType GetConfiguredCacheMemoryTypeOrDie();
-
// BlockId refers to the unique identifier for a Kudu block, that is, for an
// entire CFile. This is different than the block cache's notion of a block,
// which is just a portion of a CFile.
@@ -119,6 +117,10 @@ class BlockCache {
explicit BlockCache(size_t capacity);
+ BlockCache(size_t probationary_segment_capacity,
+ size_t protected_segment_capacity,
+ size_t lookups);
+
// Lookup the given block in the cache.
//
// If the entry is found, then sets *handle to refer to the entry.
@@ -164,8 +166,20 @@ class BlockCache {
private:
friend class Singleton<BlockCache>;
+ FRIEND_TEST(BlockCacheTest, TestBasics);
BlockCache();
+ // Parse the gflag which configures the block cache. FATALs if the flag is
invalid.
+ static Cache::MemoryType GetConfiguredCacheMemoryTypeOrDie();
+
+ // Parse the gflag which configure the block cache eviction policy. FATALs
if flag is invalid.
+ static Cache::EvictionPolicy GetCacheEvictionPolicyOrDie();
+
+ static Cache* CreateCache(int64_t capacity);
+ static Cache* CreateCache(int64_t probationary_segment_capacity,
+ int64_t protected_segment_capacity,
+ uint32_t lookups);
+
DISALLOW_COPY_AND_ASSIGN(BlockCache);
std::unique_ptr<Cache> cache_;
@@ -228,7 +242,17 @@ inline void BlockCache::PendingEntry::reset() {
// Validates the block cache capacity. Won't permit the cache to grow large
// enough to cause pernicious flushing behavior. See KUDU-2318.
+// Only necessary for DRAM-based caches. See KUDU-2920 for more details.
bool ValidateBlockCacheCapacity();
+// Does same as ValidateBlockCacheCapacity() except for block caches with SLRU
eviction policy.
+bool ValidateBlockCacheSegmentCapacity();
+
+// Validates number of lookups before upgrade for block cache of SLRU eviction
policy. Must be > 0.
+bool ValidateLookups();
+
+// Validates the eviction policy for block cache, either LRU or SLRU.
+bool ValidateEvictionPolicy();
+
} // namespace cfile
} // namespace kudu
diff --git a/src/kudu/cfile/cfile-test.cc b/src/kudu/cfile/cfile-test.cc
index 42ca249f4..c204d5e4e 100644
--- a/src/kudu/cfile/cfile-test.cc
+++ b/src/kudu/cfile/cfile-test.cc
@@ -26,6 +26,7 @@
#include <sstream>
#include <string>
#include <type_traits>
+#include <utility>
#include <vector>
#include <gflags/gflags.h>
@@ -83,6 +84,7 @@ class Arena;
DECLARE_bool(cfile_write_checksums);
DECLARE_bool(cfile_verify_checksums);
+DECLARE_string(block_cache_eviction_policy);
DECLARE_string(block_cache_type);
DECLARE_bool(force_block_cache_capacity);
DECLARE_int64(block_cache_capacity_mb);
@@ -404,7 +406,7 @@ class TestCFile : public CFileTestBase {
// once for each cache memory type (DRAM, NVM).
class TestCFileBothCacheMemoryTypes :
public TestCFile,
- public ::testing::WithParamInterface<Cache::MemoryType> {
+ public ::testing::WithParamInterface<std::pair<Cache::MemoryType,
Cache::EvictionPolicy>> {
public:
void SetUp() override {
// The NVM cache can run using any directory as its path -- it doesn't have
@@ -414,16 +416,31 @@ class TestCFileBothCacheMemoryTypes :
FLAGS_nvm_cache_path = GetTestPath("nvm-cache");
ASSERT_OK(Env::Default()->CreateDir(FLAGS_nvm_cache_path));
}
- switch (GetParam()) {
+ const auto& param = GetParam();
+ switch (param.first) {
case Cache::MemoryType::DRAM:
FLAGS_block_cache_type = "DRAM";
+ switch (param.second) {
+ case Cache::EvictionPolicy::LRU:
+ FLAGS_block_cache_eviction_policy = "LRU";
+ break;
+ case Cache::EvictionPolicy::SLRU:
+ FLAGS_block_cache_eviction_policy = "SLRU";
+ break;
+ default:
+ LOG(FATAL) << "Block cache does not support FIFO eviction policy";
+ }
break;
case Cache::MemoryType::NVM:
+ if (param.second != Cache::EvictionPolicy::LRU) {
+ LOG(FATAL) << "NVM cache only supports LRU eviction policy";
+ }
FLAGS_block_cache_type = "NVM";
+ FLAGS_block_cache_eviction_policy = "LRU";
break;
default:
LOG(FATAL) << "Unknown block cache type: '"
- << static_cast<int16_t>(GetParam());
+ << static_cast<int16_t>(param.first);
}
CFileTestBase::SetUp();
}
@@ -434,8 +451,12 @@ class TestCFileBothCacheMemoryTypes :
};
INSTANTIATE_TEST_SUITE_P(CacheMemoryTypes, TestCFileBothCacheMemoryTypes,
- ::testing::Values(Cache::MemoryType::DRAM,
- Cache::MemoryType::NVM));
+
::testing::Values(std::make_pair(Cache::MemoryType::DRAM,
+
Cache::EvictionPolicy::LRU),
+
std::make_pair(Cache::MemoryType::DRAM,
+
Cache::EvictionPolicy::SLRU),
+
std::make_pair(Cache::MemoryType::NVM,
+
Cache::EvictionPolicy::LRU)));
template <DataType type>
void CopyOne(CFileIterator* it, typename TypeTraits<type>::cpp_type* ret,
RowBlockMemory* mem) {
@@ -453,7 +474,7 @@ void CopyOne(CFileIterator* it, typename
TypeTraits<type>::cpp_type* ret, RowBlo
// They take way too long with debugging enabled.
TEST_P(TestCFileBothCacheMemoryTypes, TestWrite100MFileInts) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
BlockId block_id;
LOG_TIMING(INFO, "writing 100m ints") {
LOG(INFO) << "Starting writefile";
@@ -472,7 +493,7 @@ TEST_P(TestCFileBothCacheMemoryTypes,
TestWrite100MFileInts) {
}
TEST_P(TestCFileBothCacheMemoryTypes, TestWrite100MFileNullableInts) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
BlockId block_id;
LOG_TIMING(INFO, "writing 100m nullable ints") {
LOG(INFO) << "Starting writefile";
@@ -491,22 +512,22 @@ TEST_P(TestCFileBothCacheMemoryTypes,
TestWrite100MFileNullableInts) {
}
TEST_P(TestCFileBothCacheMemoryTypes, TestWrite100MFileStringsPrefixEncoding) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
TestWrite100MFileStrings(PREFIX_ENCODING);
}
TEST_P(TestCFileBothCacheMemoryTypes, TestWrite100MUniqueStringsDictEncoding) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
TestWrite100MFileStrings(DICT_ENCODING);
}
TEST_P(TestCFileBothCacheMemoryTypes,
TestWrite100MLowCardinalityStringsDictEncoding) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
TestWriteDictEncodingLowCardinalityStrings(100 * 1e6);
}
TEST_P(TestCFileBothCacheMemoryTypes, TestWrite100MFileStringsPlainEncoding) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
TestWrite100MFileStrings(PLAIN_ENCODING);
}
@@ -514,7 +535,7 @@ TEST_P(TestCFileBothCacheMemoryTypes,
TestWrite100MFileStringsPlainEncoding) {
// Write and Read 1 million unique strings with dictionary encoding
TEST_P(TestCFileBothCacheMemoryTypes,
TestWrite1MUniqueFileStringsDictEncoding) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
BlockId block_id;
LOG_TIMING(INFO, "writing 1M unique strings") {
LOG(INFO) << "Starting writefile";
@@ -534,49 +555,49 @@ TEST_P(TestCFileBothCacheMemoryTypes,
TestWrite1MUniqueFileStringsDictEncoding)
// Write and Read 1 million strings, which contains duplicates with dictionary
encoding
TEST_P(TestCFileBothCacheMemoryTypes,
TestWrite1MLowCardinalityStringsDictEncoding) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
TestWriteDictEncodingLowCardinalityStrings(1000000);
}
TEST_P(TestCFileBothCacheMemoryTypes, TestReadWriteUInt32) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
for (auto enc : { PLAIN_ENCODING, RLE }) {
TestReadWriteFixedSizeTypes<UInt32DataGenerator<false>>(enc);
}
}
TEST_P(TestCFileBothCacheMemoryTypes, TestReadWriteInt32) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
for (auto enc : { PLAIN_ENCODING, RLE }) {
TestReadWriteFixedSizeTypes<Int32DataGenerator<false>>(enc);
}
}
TEST_P(TestCFileBothCacheMemoryTypes, TestReadWriteUInt64) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
for (auto enc : { PLAIN_ENCODING, RLE, BIT_SHUFFLE }) {
TestReadWriteFixedSizeTypes<UInt64DataGenerator<false>>(enc);
}
}
TEST_P(TestCFileBothCacheMemoryTypes, TestReadWriteInt64) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
for (auto enc : { PLAIN_ENCODING, RLE, BIT_SHUFFLE }) {
TestReadWriteFixedSizeTypes<Int64DataGenerator<false>>(enc);
}
}
TEST_P(TestCFileBothCacheMemoryTypes, TestReadWriteInt128) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
TestReadWriteFixedSizeTypes<Int128DataGenerator<false>>(PLAIN_ENCODING);
}
TEST_P(TestCFileBothCacheMemoryTypes,
TestFixedSizeReadWritePlainEncodingFloat) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
TestReadWriteFixedSizeTypes<FPDataGenerator<FLOAT, false>>(PLAIN_ENCODING);
}
TEST_P(TestCFileBothCacheMemoryTypes,
TestFixedSizeReadWritePlainEncodingDouble) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
TestReadWriteFixedSizeTypes<FPDataGenerator<DOUBLE, false>>(PLAIN_ENCODING);
}
@@ -732,13 +753,13 @@ void TestCFile::TestReadWriteStrings(EncodingType
encoding,
TEST_P(TestCFileBothCacheMemoryTypes, TestReadWriteStringsPrefixEncoding) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
TestReadWriteStrings(PREFIX_ENCODING);
}
// Read/Write test for dictionary encoded blocks
TEST_P(TestCFileBothCacheMemoryTypes, TestReadWriteStringsDictEncoding) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
TestReadWriteStrings(DICT_ENCODING);
}
@@ -749,7 +770,7 @@ TEST_P(TestCFileBothCacheMemoryTypes,
TestReadWriteStringsDictEncoding) {
// and runs extremely slowly with TSAN enabled.
#ifndef THREAD_SANITIZER
TEST_P(TestCFileBothCacheMemoryTypes, TestReadWriteLargeStrings) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
// Pad the values out to a length of ~65KB.
// We use this method instead of just a longer sprintf format since
@@ -769,7 +790,7 @@ TEST_P(TestCFileBothCacheMemoryTypes,
TestReadWriteLargeStrings) {
// Test that metadata entries stored in the cfile are persisted.
TEST_P(TestCFileBothCacheMemoryTypes, TestMetadata) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
BlockId block_id;
@@ -812,7 +833,7 @@ TEST_P(TestCFileBothCacheMemoryTypes, TestMetadata) {
}
TEST_P(TestCFileBothCacheMemoryTypes, TestDefaultColumnIter) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
const int kNumItems = 64;
uint8_t non_null_bitmap[BitmapSize(kNumItems)];
@@ -863,7 +884,7 @@ TEST_P(TestCFileBothCacheMemoryTypes,
TestDefaultColumnIter) {
}
TEST_P(TestCFileBothCacheMemoryTypes, TestAppendRaw) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
TestReadWriteRawBlocks(NO_COMPRESSION, 1000);
TestReadWriteRawBlocks(SNAPPY, 1000);
TestReadWriteRawBlocks(LZ4, 1000);
@@ -871,7 +892,7 @@ TEST_P(TestCFileBothCacheMemoryTypes, TestAppendRaw) {
}
TEST_P(TestCFileBothCacheMemoryTypes, TestChecksumFlags) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
for (bool write_checksums : {false, true}) {
for (bool verify_checksums : {false, true}) {
FLAGS_cfile_write_checksums = write_checksums;
@@ -883,7 +904,7 @@ TEST_P(TestCFileBothCacheMemoryTypes, TestChecksumFlags) {
}
TEST_P(TestCFileBothCacheMemoryTypes, TestDataCorruption) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
FLAGS_cfile_write_checksums = true;
FLAGS_cfile_verify_checksums = true;
@@ -919,7 +940,7 @@ TEST_P(TestCFileBothCacheMemoryTypes, TestDataCorruption) {
}
TEST_P(TestCFileBothCacheMemoryTypes, TestNullInts) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
UInt32DataGenerator<true> generator;
TestNullTypes(&generator, PLAIN_ENCODING, NO_COMPRESSION);
@@ -931,7 +952,7 @@ TEST_P(TestCFileBothCacheMemoryTypes, TestNullInts) {
}
TEST_P(TestCFileBothCacheMemoryTypes, TestNullFloats) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
FPDataGenerator<FLOAT, true> generator;
TestNullTypes(&generator, PLAIN_ENCODING, NO_COMPRESSION);
@@ -939,7 +960,7 @@ TEST_P(TestCFileBothCacheMemoryTypes, TestNullFloats) {
}
TEST_P(TestCFileBothCacheMemoryTypes, TestNullPrefixStrings) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
StringDataGenerator<true> generator("hello %zu");
TestNullTypes(&generator, PLAIN_ENCODING, NO_COMPRESSION);
@@ -947,7 +968,7 @@ TEST_P(TestCFileBothCacheMemoryTypes,
TestNullPrefixStrings) {
}
TEST_P(TestCFileBothCacheMemoryTypes, TestNullPlainStrings) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
StringDataGenerator<true> generator("hello %zu");
TestNullTypes(&generator, PREFIX_ENCODING, NO_COMPRESSION);
@@ -956,7 +977,7 @@ TEST_P(TestCFileBothCacheMemoryTypes, TestNullPlainStrings)
{
// Test for dictionary encoding
TEST_P(TestCFileBothCacheMemoryTypes, TestNullDictStrings) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
StringDataGenerator<true> generator("hello %zu");
TestNullTypes(&generator, DICT_ENCODING, NO_COMPRESSION);
@@ -964,7 +985,7 @@ TEST_P(TestCFileBothCacheMemoryTypes, TestNullDictStrings) {
}
TEST_P(TestCFileBothCacheMemoryTypes, TestReleaseBlock) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
unique_ptr<WritableBlock> sink;
ASSERT_OK(fs_manager_->CreateNewBlock({}, &sink));
@@ -979,7 +1000,7 @@ TEST_P(TestCFileBothCacheMemoryTypes, TestReleaseBlock) {
}
TEST_P(TestCFileBothCacheMemoryTypes, TestLazyInit) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
// Create a small test file.
BlockId block_id;
@@ -1032,7 +1053,7 @@ TEST_P(TestCFileBothCacheMemoryTypes, TestLazyInit) {
// different reader instances operating on the same block should use the same
// block cache keys.
TEST_P(TestCFileBothCacheMemoryTypes, TestCacheKeysAreStable) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
// Set up block cache instrumentation.
MetricRegistry registry;
@@ -1075,21 +1096,21 @@ TEST_P(TestCFileBothCacheMemoryTypes,
TestCacheKeysAreStable) {
// Inject failures in nvm allocation and ensure that we can still read a file.
TEST_P(TestCFileBothCacheMemoryTypes, TestNvmAllocationFailure) {
- if (GetParam() != Cache::MemoryType::NVM) {
+ if (GetParam().first != Cache::MemoryType::NVM) {
GTEST_SKIP();
}
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
FLAGS_nvm_cache_simulate_allocation_failure = true;
TestReadWriteFixedSizeTypes<UInt32DataGenerator<false> >(PLAIN_ENCODING);
}
TEST_P(TestCFileBothCacheMemoryTypes, TestValidateBlockCacheCapacity) {
- RETURN_IF_NO_NVM_CACHE(GetParam());
+ RETURN_IF_NO_NVM_CACHE(GetParam().first);
FLAGS_force_block_cache_capacity = false;
FLAGS_block_cache_capacity_mb = 100000000; // very big number (100TB)
- switch (GetParam()) {
+ switch (GetParam().first) {
case Cache::MemoryType::DRAM:
ASSERT_FALSE(kudu::cfile::ValidateBlockCacheCapacity());
break;
@@ -1098,7 +1119,7 @@ TEST_P(TestCFileBothCacheMemoryTypes,
TestValidateBlockCacheCapacity) {
break;
default:
LOG(FATAL) << "Unknown block cache type: "
- << static_cast<int16_t>(GetParam());
+ << static_cast<int16_t>(GetParam().first);
}
}
diff --git a/src/kudu/integration-tests/dense_node-itest.cc
b/src/kudu/integration-tests/dense_node-itest.cc
index 212181eac..4e1e400b9 100644
--- a/src/kudu/integration-tests/dense_node-itest.cc
+++ b/src/kudu/integration-tests/dense_node-itest.cc
@@ -21,6 +21,7 @@
#include <cstdint>
#include <memory>
#include <ostream>
+#include <set>
#include <string>
#include <tuple>
#include <utility>
@@ -59,6 +60,7 @@ METRIC_DECLARE_gauge_uint64(threads_running);
DECLARE_bool(enable_rowset_compaction);
DECLARE_string(block_manager);
+DECLARE_string(block_cache_eviction_policy);
DEFINE_bool(measure_startup_drop_caches, false,
"Whether to drop kernel caches before measuring startup time. Must
be root");
@@ -88,13 +90,14 @@ using strings::Substitute;
class DenseNodeTest :
public ExternalMiniClusterITestBase,
- public testing::WithParamInterface<std::tuple<bool, string>> {
+ public testing::WithParamInterface<std::tuple<bool, string, string>> {
};
INSTANTIATE_TEST_SUITE_P(, DenseNodeTest,
::testing::Combine(
::testing::Bool(),
-
::testing::ValuesIn(BlockManager::block_manager_types())));
+
::testing::ValuesIn(BlockManager::block_manager_types()),
+ ::testing::Values("LRU", "SLRU")));
// Integration test that simulates "dense" Kudu nodes.
//
@@ -105,6 +108,10 @@ INSTANTIATE_TEST_SUITE_P(, DenseNodeTest,
// proxy for data in areas we care about (such as start up time, thread count,
// memory usage, etc.).
TEST_P(DenseNodeTest, RunTest) {
+ #ifdef THREAD_SANITIZER
+ SKIP_IF_SLOW_NOT_ALLOWED();
+ #endif
+
ExternalMiniClusterOptions opts;
opts.extra_tserver_flags = {
@@ -160,15 +167,23 @@ TEST_P(DenseNodeTest, RunTest) {
opts.extra_master_flags.emplace_back("--never_fsync=false");
}
- if (std::get<0>(GetParam())) {
+ const auto& setup = GetParam();
+
+ if (std::get<0>(setup)) {
opts.extra_master_flags.emplace_back("--encrypt_data_at_rest=true");
opts.extra_tserver_flags.emplace_back("--encrypt_data_at_rest=true");
}
- FLAGS_block_manager = std::get<1>(GetParam());
+ FLAGS_block_manager = std::get<1>(setup);
opts.extra_master_flags.emplace_back(Substitute("--block_manager=$0",
FLAGS_block_manager));
opts.extra_tserver_flags.emplace_back(Substitute("--block_manager=$0",
FLAGS_block_manager));
+ FLAGS_block_cache_eviction_policy = std::get<2>(setup);
+
opts.extra_master_flags.emplace_back(Substitute("--block_cache_eviction_policy=$0",
+
FLAGS_block_cache_eviction_policy));
+
opts.extra_tserver_flags.emplace_back(Substitute("--block_cache_eviction_policy=$0",
+
FLAGS_block_cache_eviction_policy));
+
// With the amount of data we're going to write, we need to make sure the
// tserver has enough time to start back up (startup is only considered to be
// "complete" when the tserver has loaded all fs metadata from disk).
diff --git a/src/kudu/integration-tests/full_stack-insert-scan-test.cc
b/src/kudu/integration-tests/full_stack-insert-scan-test.cc
index 0ba2428f5..c5a641835 100644
--- a/src/kudu/integration-tests/full_stack-insert-scan-test.cc
+++ b/src/kudu/integration-tests/full_stack-insert-scan-test.cc
@@ -32,6 +32,7 @@
#include <glog/logging.h>
#include <gtest/gtest.h>
+#include "kudu/cfile/block_cache.h"
#include "kudu/client/callbacks.h"
#include "kudu/client/client-test-util.h"
#include "kudu/client/client.h"
@@ -44,6 +45,7 @@
#include "kudu/common/partial_row.h"
#include "kudu/gutil/map-util.h"
#include "kudu/gutil/ref_counted.h"
+#include "kudu/gutil/singleton.h"
#include "kudu/gutil/strings/split.h"
#include "kudu/gutil/strings/substitute.h"
#include "kudu/master/mini_master.h"
@@ -84,6 +86,7 @@ DEFINE_bool(perf_record_scan_callgraph, false,
DEFINE_bool(perf_stat_scan, false, "Print \"perf stat\" results during "
"scan to stdout, disabled by default");
DECLARE_bool(enable_maintenance_manager);
+DECLARE_string(block_cache_eviction_policy);
using kudu::client::KuduClient;
using kudu::client::KuduClientBuilder;
@@ -282,14 +285,31 @@ void ReportAllDone(int id, int numids) {
const char* const FullStackInsertScanTest::kTableName =
"full-stack-mrs-test-tbl";
-TEST_F(FullStackInsertScanTest, MRSOnlyStressTest) {
+class FullStackInsertScanTestWithEvictionPolicy :
+ public FullStackInsertScanTest,
+ public ::testing::WithParamInterface<std::string> {
+ protected:
+ void SetUp() override {
+ FLAGS_block_cache_eviction_policy = GetParam();
+ FullStackInsertScanTest::SetUp();
+ }
+
+ void TearDown() override {
+ Singleton<cfile::BlockCache>::UnsafeReset();
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(EvictionPolicyTypes,
FullStackInsertScanTestWithEvictionPolicy,
+ ::testing::Values("LRU", "SLRU"));
+
+TEST_P(FullStackInsertScanTestWithEvictionPolicy, MRSOnlyStressTest) {
FLAGS_enable_maintenance_manager = false;
NO_FATALS(CreateTable());
NO_FATALS(DoConcurrentClientInserts());
NO_FATALS(DoTestScans());
}
-TEST_F(FullStackInsertScanTest, WithDiskStressTest) {
+TEST_P(FullStackInsertScanTestWithEvictionPolicy, WithDiskStressTest) {
NO_FATALS(CreateTable());
NO_FATALS(DoConcurrentClientInserts());
NO_FATALS(FlushToDisk());
diff --git a/src/kudu/integration-tests/heavy-update-compaction-itest.cc
b/src/kudu/integration-tests/heavy-update-compaction-itest.cc
index 0f57ebf07..a6e0af0e6 100644
--- a/src/kudu/integration-tests/heavy-update-compaction-itest.cc
+++ b/src/kudu/integration-tests/heavy-update-compaction-itest.cc
@@ -19,12 +19,14 @@
#include <cstdint>
#include <memory>
#include <string>
+#include <type_traits>
#include <vector>
#include <gflags/gflags.h>
#include <glog/logging.h>
#include <gtest/gtest.h>
+#include "kudu/cfile/block_cache.h"
#include "kudu/client/client.h"
#include "kudu/client/row_result.h"
#include "kudu/client/scan_batch.h"
@@ -34,6 +36,7 @@
#include "kudu/client/value.h"
#include "kudu/client/write_op.h"
#include "kudu/common/partial_row.h"
+#include "kudu/gutil/singleton.h"
#include "kudu/master/mini_master.h"
#include "kudu/mini-cluster/internal_mini_cluster.h"
#include "kudu/util/faststring.h"
@@ -46,6 +49,7 @@
#include "kudu/util/test_util.h"
DECLARE_int32(flush_threshold_mb);
+DECLARE_string(block_cache_eviction_policy);
DEFINE_int32(rounds, 100,
"How many rounds of updates will be performed. More rounds make
the "
@@ -170,12 +174,26 @@ class HeavyUpdateCompactionITest : public KuduTest {
Random rand_;
};
+class HeavyUpdateCompactionITestWithEvictionPolicy :
+ public HeavyUpdateCompactionITest,
+ public ::testing::WithParamInterface<std::string> {
+ protected:
+ void SetUp() override {
+ FLAGS_block_cache_eviction_policy = GetParam();
+ HeavyUpdateCompactionITest::SetUp();
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(EvictionPolicyTypes,
HeavyUpdateCompactionITestWithEvictionPolicy,
+ ::testing::Values("LRU", "SLRU"));
+
// Repro for KUDU-2231, which is an integer overflow in the RowSetInfo class.
// This test creates a rowset with a very large amount of REDO delta files
// (the bug was a 2GiB overflow), as well as mixed inserts. This causes the
// maintanance manager to schedule rowset compactions, which sometimes
// reproduces the overflow.
-TEST_F(HeavyUpdateCompactionITest, TestHeavyUpdateCompaction) {
+TEST_P(HeavyUpdateCompactionITestWithEvictionPolicy,
TestHeavyUpdateCompaction) {
+ Singleton<cfile::BlockCache>::UnsafeReset();
NO_FATALS(CreateTable());
shared_ptr<KuduSession> session = CreateSession();
diff --git a/src/kudu/tserver/tablet_server-stress-test.cc
b/src/kudu/tserver/tablet_server-stress-test.cc
index ec66b0103..c8ae6867d 100644
--- a/src/kudu/tserver/tablet_server-stress-test.cc
+++ b/src/kudu/tserver/tablet_server-stress-test.cc
@@ -17,6 +17,7 @@
#include <cstdint>
#include <functional>
#include <ostream>
+#include <string>
#include <thread>
#include <vector>
@@ -24,7 +25,9 @@
#include <glog/logging.h>
#include <gtest/gtest.h>
+#include "kudu/cfile/block_cache.h"
#include "kudu/gutil/ref_counted.h"
+#include "kudu/gutil/singleton.h"
#include "kudu/tserver/tablet_server-test-base.h"
#include "kudu/util/countdown_latch.h"
#include "kudu/util/jsonwriter.h"
@@ -46,6 +49,7 @@ DEFINE_int32(num_inserts_per_thread, 100000000,
"default is set high so that, typically, the 'runtime_secs'
parameter determines "
"how long this test will run.");
DECLARE_bool(enable_maintenance_manager);
+DECLARE_string(block_cache_eviction_policy);
METRIC_DEFINE_histogram(test, insert_latency,
"Insert Latency",
@@ -122,7 +126,24 @@ void TSStressTest::InserterThread(int thread_idx) {
LOG(INFO) << "Inserter thread " << thread_idx << " complete";
}
-TEST_F(TSStressTest, TestMTInserts) {
+class TSStressTestWithEvictionPolicy :
+ public TSStressTest,
+ public ::testing::WithParamInterface<std::string> {
+ protected:
+ void SetUp() override {
+ FLAGS_block_cache_eviction_policy = GetParam();
+ TSStressTest::SetUp();
+ }
+
+ void TearDown() override {
+ Singleton<cfile::BlockCache>::UnsafeReset();
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(EvictionPolicyTypes, TSStressTestWithEvictionPolicy,
+ ::testing::Values("LRU", "SLRU"));
+
+TEST_P(TSStressTestWithEvictionPolicy, TestMTInserts) {
thread timeout_thread;
StartThreads();
Stopwatch s(Stopwatch::ALL_THREADS);