@ -12,98 +12,32 @@
# include "memory/jemalloc_nodump_allocator.h"
# include "rocksdb/convenience.h"
# include "test_util/secondary_cache_test_util.h"
# include "test_util/testharness.h"
# include "test_util/testutil.h"
namespace ROCKSDB_NAMESPACE {
using secondary_cache_test_util : : GetHelper ;
using secondary_cache_test_util : : GetHelperFail ;
using secondary_cache_test_util : : TestCreateContext ;
using secondary_cache_test_util : : TestItem ;
class CompressedSecondaryCacheTest : public testing : : Test ,
public Cache : : CreateContext {
public Test CreateContext {
public :
CompressedSecondaryCacheTest ( ) : fail_create_ ( false ) { }
CompressedSecondaryCacheTest ( ) { }
~ CompressedSecondaryCacheTest ( ) override = default ;
protected :
class TestItem {
public :
TestItem ( const char * buf , size_t size ) : buf_ ( new char [ size ] ) , size_ ( size ) {
memcpy ( buf_ . get ( ) , buf , size ) ;
}
~ TestItem ( ) = default ;
char * Buf ( ) { return buf_ . get ( ) ; }
[[nodiscard]] size_t Size ( ) const { return size_ ; }
private :
std : : unique_ptr < char [ ] > buf_ ;
size_t size_ ;
} ;
static size_t SizeCallback ( Cache : : ObjectPtr obj ) {
return static_cast < TestItem * > ( obj ) - > Size ( ) ;
}
static Status SaveToCallback ( Cache : : ObjectPtr from_obj , size_t from_offset ,
size_t length , char * out ) {
auto item = static_cast < TestItem * > ( from_obj ) ;
const char * buf = item - > Buf ( ) ;
EXPECT_EQ ( length , item - > Size ( ) ) ;
EXPECT_EQ ( from_offset , 0 ) ;
memcpy ( out , buf , length ) ;
return Status : : OK ( ) ;
}
static void DeletionCallback ( Cache : : ObjectPtr obj ,
MemoryAllocator * /*alloc*/ ) {
delete static_cast < TestItem * > ( obj ) ;
obj = nullptr ;
}
static Status SaveToCallbackFail ( Cache : : ObjectPtr /*obj*/ , size_t /*offset*/ ,
size_t /*size*/ , char * /*out*/ ) {
return Status : : NotSupported ( ) ;
}
static Status CreateCallback ( const Slice & data , Cache : : CreateContext * context ,
MemoryAllocator * /*allocator*/ ,
Cache : : ObjectPtr * out_obj , size_t * out_charge ) {
auto t = static_cast < CompressedSecondaryCacheTest * > ( context ) ;
if ( t - > fail_create_ ) {
return Status : : NotSupported ( ) ;
}
* out_obj = new TestItem ( data . data ( ) , data . size ( ) ) ;
* out_charge = data . size ( ) ;
return Status : : OK ( ) ;
}
static constexpr auto GenerateHelpersByRole ( ) {
std : : array < Cache : : CacheItemHelper , kNumCacheEntryRoles > a ;
for ( uint32_t i = 0 ; i < kNumCacheEntryRoles ; + + i ) {
a [ i ] = Cache : : CacheItemHelper { static_cast < CacheEntryRole > ( i ) ,
& DeletionCallback , & SizeCallback ,
& SaveToCallback , & CreateCallback } ;
}
return a ;
}
static const std : : array < Cache : : CacheItemHelper , kNumCacheEntryRoles >
kHelperByRole ;
static const Cache : : CacheItemHelper & kHelper ;
static constexpr Cache : : CacheItemHelper kHelperFail {
CacheEntryRole : : kDataBlock , & DeletionCallback , & SizeCallback ,
& SaveToCallbackFail , & CreateCallback } ;
void SetFailCreate ( bool fail ) { fail_create_ = fail ; }
void BasicTestHelper ( std : : shared_ptr < SecondaryCache > sec_cache ,
bool sec_cache_is_compressed ) {
get_perf_context ( ) - > Reset ( ) ;
bool kept_in_sec_cache { true } ;
// Lookup an non-existent key.
std : : unique_ptr < SecondaryCacheResultHandle > handle0 = sec_cache - > Lookup (
" k0 " , & kHelper , this , true , /*advise_erase=*/ true , kept_in_sec_cache ) ;
std : : unique_ptr < SecondaryCacheResultHandle > handle0 =
sec_cache - > Lookup ( " k0 " , GetHelper ( ) , this , true , /*advise_erase=*/ true ,
kept_in_sec_cache ) ;
ASSERT_EQ ( handle0 , nullptr ) ;
Random rnd ( 301 ) ;
@ -111,21 +45,23 @@ class CompressedSecondaryCacheTest : public testing::Test,
std : : string str1 ( rnd . RandomString ( 1000 ) ) ;
TestItem item1 ( str1 . data ( ) , str1 . length ( ) ) ;
// A dummy handle is inserted if the item is inserted for the first time.
ASSERT_OK ( sec_cache - > Insert ( " k1 " , & item1 , & kHelper ) ) ;
ASSERT_OK ( sec_cache - > Insert ( " k1 " , & item1 , GetHelper ( ) ) ) ;
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_insert_dummy_count , 1 ) ;
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_uncompressed_bytes , 0 ) ;
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_compressed_bytes , 0 ) ;
std : : unique_ptr < SecondaryCacheResultHandle > handle1_1 = sec_cache - > Lookup (
" k1 " , & kHelper , this , true , /*advise_erase=*/ false , kept_in_sec_cache ) ;
std : : unique_ptr < SecondaryCacheResultHandle > handle1_1 =
sec_cache - > Lookup ( " k1 " , GetHelper ( ) , this , true , /*advise_erase=*/ false ,
kept_in_sec_cache ) ;
ASSERT_EQ ( handle1_1 , nullptr ) ;
// Insert and Lookup the item k1 for the second time and advise erasing it.
ASSERT_OK ( sec_cache - > Insert ( " k1 " , & item1 , & kHelper ) ) ;
ASSERT_OK ( sec_cache - > Insert ( " k1 " , & item1 , GetHelper ( ) ) ) ;
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_insert_real_count , 1 ) ;
std : : unique_ptr < SecondaryCacheResultHandle > handle1_2 = sec_cache - > Lookup (
" k1 " , & kHelper , this , true , /*advise_erase=*/ true , kept_in_sec_cache ) ;
std : : unique_ptr < SecondaryCacheResultHandle > handle1_2 =
sec_cache - > Lookup ( " k1 " , GetHelper ( ) , this , true , /*advise_erase=*/ true ,
kept_in_sec_cache ) ;
ASSERT_NE ( handle1_2 , nullptr ) ;
ASSERT_FALSE ( kept_in_sec_cache ) ;
if ( sec_cache_is_compressed ) {
@ -144,20 +80,22 @@ class CompressedSecondaryCacheTest : public testing::Test,
ASSERT_EQ ( memcmp ( val1 - > Buf ( ) , item1 . Buf ( ) , item1 . Size ( ) ) , 0 ) ;
// Lookup the item k1 again.
std : : unique_ptr < SecondaryCacheResultHandle > handle1_3 = sec_cache - > Lookup (
" k1 " , & kHelper , this , true , /*advise_erase=*/ true , kept_in_sec_cache ) ;
std : : unique_ptr < SecondaryCacheResultHandle > handle1_3 =
sec_cache - > Lookup ( " k1 " , GetHelper ( ) , this , true , /*advise_erase=*/ true ,
kept_in_sec_cache ) ;
ASSERT_EQ ( handle1_3 , nullptr ) ;
// Insert and Lookup the item k2.
std : : string str2 ( rnd . RandomString ( 1000 ) ) ;
TestItem item2 ( str2 . data ( ) , str2 . length ( ) ) ;
ASSERT_OK ( sec_cache - > Insert ( " k2 " , & item2 , & kHelper ) ) ;
ASSERT_OK ( sec_cache - > Insert ( " k2 " , & item2 , GetHelper ( ) ) ) ;
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_insert_dummy_count , 2 ) ;
std : : unique_ptr < SecondaryCacheResultHandle > handle2_1 = sec_cache - > Lookup (
" k2 " , & kHelper , this , true , /*advise_erase=*/ false , kept_in_sec_cache ) ;
std : : unique_ptr < SecondaryCacheResultHandle > handle2_1 =
sec_cache - > Lookup ( " k2 " , GetHelper ( ) , this , true , /*advise_erase=*/ false ,
kept_in_sec_cache ) ;
ASSERT_EQ ( handle2_1 , nullptr ) ;
ASSERT_OK ( sec_cache - > Insert ( " k2 " , & item2 , & kHelper ) ) ;
ASSERT_OK ( sec_cache - > Insert ( " k2 " , & item2 , GetHelper ( ) ) ) ;
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_insert_real_count , 2 ) ;
if ( sec_cache_is_compressed ) {
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_uncompressed_bytes ,
@ -168,8 +106,9 @@ class CompressedSecondaryCacheTest : public testing::Test,
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_uncompressed_bytes , 0 ) ;
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_compressed_bytes , 0 ) ;
}
std : : unique_ptr < SecondaryCacheResultHandle > handle2_2 = sec_cache - > Lookup (
" k2 " , & kHelper , this , true , /*advise_erase=*/ false , kept_in_sec_cache ) ;
std : : unique_ptr < SecondaryCacheResultHandle > handle2_2 =
sec_cache - > Lookup ( " k2 " , GetHelper ( ) , this , true , /*advise_erase=*/ false ,
kept_in_sec_cache ) ;
ASSERT_NE ( handle2_2 , nullptr ) ;
std : : unique_ptr < TestItem > val2 =
std : : unique_ptr < TestItem > ( static_cast < TestItem * > ( handle2_2 - > Value ( ) ) ) ;
@ -238,24 +177,26 @@ class CompressedSecondaryCacheTest : public testing::Test,
std : : string str1 ( rnd . RandomString ( 1000 ) ) ;
TestItem item1 ( str1 . data ( ) , str1 . length ( ) ) ;
// Insert a dummy handle.
ASSERT_OK ( sec_cache - > Insert ( " k1 " , & item1 , & kHelper ) ) ;
ASSERT_OK ( sec_cache - > Insert ( " k1 " , & item1 , GetHelper ( ) ) ) ;
// Insert k1.
ASSERT_OK ( sec_cache - > Insert ( " k1 " , & item1 , & kHelper ) ) ;
ASSERT_OK ( sec_cache - > Insert ( " k1 " , & item1 , GetHelper ( ) ) ) ;
// Insert and Lookup the second item.
std : : string str2 ( rnd . RandomString ( 200 ) ) ;
TestItem item2 ( str2 . data ( ) , str2 . length ( ) ) ;
// Insert a dummy handle, k1 is not evicted.
ASSERT_OK ( sec_cache - > Insert ( " k2 " , & item2 , & kHelper ) ) ;
ASSERT_OK ( sec_cache - > Insert ( " k2 " , & item2 , GetHelper ( ) ) ) ;
bool kept_in_sec_cache { false } ;
std : : unique_ptr < SecondaryCacheResultHandle > handle1 = sec_cache - > Lookup (
" k1 " , & kHelper , this , true , /*advise_erase=*/ false , kept_in_sec_cache ) ;
std : : unique_ptr < SecondaryCacheResultHandle > handle1 =
sec_cache - > Lookup ( " k1 " , GetHelper ( ) , this , true , /*advise_erase=*/ false ,
kept_in_sec_cache ) ;
ASSERT_EQ ( handle1 , nullptr ) ;
// Insert k2 and k1 is evicted.
ASSERT_OK ( sec_cache - > Insert ( " k2 " , & item2 , & kHelper ) ) ;
std : : unique_ptr < SecondaryCacheResultHandle > handle2 = sec_cache - > Lookup (
" k2 " , & kHelper , this , true , /*advise_erase=*/ false , kept_in_sec_cache ) ;
ASSERT_OK ( sec_cache - > Insert ( " k2 " , & item2 , GetHelper ( ) ) ) ;
std : : unique_ptr < SecondaryCacheResultHandle > handle2 =
sec_cache - > Lookup ( " k2 " , GetHelper ( ) , this , true , /*advise_erase=*/ false ,
kept_in_sec_cache ) ;
ASSERT_NE ( handle2 , nullptr ) ;
std : : unique_ptr < TestItem > val2 =
std : : unique_ptr < TestItem > ( static_cast < TestItem * > ( handle2 - > Value ( ) ) ) ;
@ -263,24 +204,26 @@ class CompressedSecondaryCacheTest : public testing::Test,
ASSERT_EQ ( memcmp ( val2 - > Buf ( ) , item2 . Buf ( ) , item2 . Size ( ) ) , 0 ) ;
// Insert k1 again and a dummy handle is inserted.
ASSERT_OK ( sec_cache - > Insert ( " k1 " , & item1 , & kHelper ) ) ;
ASSERT_OK ( sec_cache - > Insert ( " k1 " , & item1 , GetHelper ( ) ) ) ;
std : : unique_ptr < SecondaryCacheResultHandle > handle1_1 = sec_cache - > Lookup (
" k1 " , & kHelper , this , true , /*advise_erase=*/ false , kept_in_sec_cache ) ;
std : : unique_ptr < SecondaryCacheResultHandle > handle1_1 =
sec_cache - > Lookup ( " k1 " , GetHelper ( ) , this , true , /*advise_erase=*/ false ,
kept_in_sec_cache ) ;
ASSERT_EQ ( handle1_1 , nullptr ) ;
// Create Fails.
SetFailCreate ( true ) ;
std : : unique_ptr < SecondaryCacheResultHandle > handle2_1 = sec_cache - > Lookup (
" k2 " , & kHelper , this , true , /*advise_erase=*/ true , kept_in_sec_cache ) ;
std : : unique_ptr < SecondaryCacheResultHandle > handle2_1 =
sec_cache - > Lookup ( " k2 " , GetHelper ( ) , this , true , /*advise_erase=*/ true ,
kept_in_sec_cache ) ;
ASSERT_EQ ( handle2_1 , nullptr ) ;
// Save Fails.
std : : string str3 = rnd . RandomString ( 10 ) ;
TestItem item3 ( str3 . data ( ) , str3 . length ( ) ) ;
// The Status is OK because a dummy handle is inserted.
ASSERT_OK ( sec_cache - > Insert ( " k3 " , & item3 , & kHelperFail ) ) ;
ASSERT_NOK ( sec_cache - > Insert ( " k3 " , & item3 , & kHelperFail ) ) ;
ASSERT_OK ( sec_cache - > Insert ( " k3 " , & item3 , GetHelperFail ( ) ) ) ;
ASSERT_NOK ( sec_cache - > Insert ( " k3 " , & item3 , GetHelperFail ( ) ) ) ;
sec_cache . reset ( ) ;
}
@ -317,13 +260,13 @@ class CompressedSecondaryCacheTest : public testing::Test,
Random rnd ( 301 ) ;
std : : string str1 = rnd . RandomString ( 1001 ) ;
auto item1_1 = new TestItem ( str1 . data ( ) , str1 . length ( ) ) ;
ASSERT_OK ( cache - > Insert ( " k1 " , item1_1 , & kHelper , str1 . length ( ) ) ) ;
ASSERT_OK ( cache - > Insert ( " k1 " , item1_1 , GetHelper ( ) , str1 . length ( ) ) ) ;
std : : string str2 = rnd . RandomString ( 1012 ) ;
auto item2_1 = new TestItem ( str2 . data ( ) , str2 . length ( ) ) ;
// After this Insert, primary cache contains k2 and secondary cache contains
// k1's dummy item.
ASSERT_OK ( cache - > Insert ( " k2 " , item2_1 , & kHelper , str2 . length ( ) ) ) ;
ASSERT_OK ( cache - > Insert ( " k2 " , item2_1 , GetHelper ( ) , str2 . length ( ) ) ) ;
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_insert_dummy_count , 1 ) ;
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_uncompressed_bytes , 0 ) ;
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_compressed_bytes , 0 ) ;
@ -332,19 +275,19 @@ class CompressedSecondaryCacheTest : public testing::Test,
auto item3_1 = new TestItem ( str3 . data ( ) , str3 . length ( ) ) ;
// After this Insert, primary cache contains k3 and secondary cache contains
// k1's dummy item and k2's dummy item.
ASSERT_OK ( cache - > Insert ( " k3 " , item3_1 , & kHelper , str3 . length ( ) ) ) ;
ASSERT_OK ( cache - > Insert ( " k3 " , item3_1 , GetHelper ( ) , str3 . length ( ) ) ) ;
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_insert_dummy_count , 2 ) ;
// After this Insert, primary cache contains k1 and secondary cache contains
// k1's dummy item, k2's dummy item, and k3's dummy item.
auto item1_2 = new TestItem ( str1 . data ( ) , str1 . length ( ) ) ;
ASSERT_OK ( cache - > Insert ( " k1 " , item1_2 , & kHelper , str1 . length ( ) ) ) ;
ASSERT_OK ( cache - > Insert ( " k1 " , item1_2 , GetHelper ( ) , str1 . length ( ) ) ) ;
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_insert_dummy_count , 3 ) ;
// After this Insert, primary cache contains k2 and secondary cache contains
// k1's item, k2's dummy item, and k3's dummy item.
auto item2_2 = new TestItem ( str2 . data ( ) , str2 . length ( ) ) ;
ASSERT_OK ( cache - > Insert ( " k2 " , item2_2 , & kHelper , str2 . length ( ) ) ) ;
ASSERT_OK ( cache - > Insert ( " k2 " , item2_2 , GetHelper ( ) , str2 . length ( ) ) ) ;
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_insert_real_count , 1 ) ;
if ( sec_cache_is_compressed ) {
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_uncompressed_bytes ,
@ -359,7 +302,7 @@ class CompressedSecondaryCacheTest : public testing::Test,
// After this Insert, primary cache contains k3 and secondary cache contains
// k1's item and k2's item.
auto item3_2 = new TestItem ( str3 . data ( ) , str3 . length ( ) ) ;
ASSERT_OK ( cache - > Insert ( " k3 " , item3_2 , & kHelper , str3 . length ( ) ) ) ;
ASSERT_OK ( cache - > Insert ( " k3 " , item3_2 , GetHelper ( ) , str3 . length ( ) ) ) ;
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_insert_real_count , 2 ) ;
if ( sec_cache_is_compressed ) {
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_uncompressed_bytes ,
@ -372,7 +315,7 @@ class CompressedSecondaryCacheTest : public testing::Test,
}
Cache : : Handle * handle ;
handle = cache - > Lookup ( " k3 " , & kHelper , this , Cache : : Priority : : LOW , true ,
handle = cache - > Lookup ( " k3 " , GetHelper ( ) , this , Cache : : Priority : : LOW , true ,
stats . get ( ) ) ;
ASSERT_NE ( handle , nullptr ) ;
auto val3 = static_cast < TestItem * > ( cache - > Value ( handle ) ) ;
@ -381,13 +324,13 @@ class CompressedSecondaryCacheTest : public testing::Test,
cache - > Release ( handle ) ;
// Lookup an non-existent key.
handle = cache - > Lookup ( " k0 " , & kHelper , this , Cache : : Priority : : LOW , true ,
handle = cache - > Lookup ( " k0 " , GetHelper ( ) , this , Cache : : Priority : : LOW , true ,
stats . get ( ) ) ;
ASSERT_EQ ( handle , nullptr ) ;
// This Lookup should just insert a dummy handle in the primary cache
// and the k1 is still in the secondary cache.
handle = cache - > Lookup ( " k1 " , & kHelper , this , Cache : : Priority : : LOW , true ,
handle = cache - > Lookup ( " k1 " , GetHelper ( ) , this , Cache : : Priority : : LOW , true ,
stats . get ( ) ) ;
ASSERT_NE ( handle , nullptr ) ;
ASSERT_EQ ( get_perf_context ( ) - > block_cache_standalone_handle_count , 1 ) ;
@ -399,7 +342,7 @@ class CompressedSecondaryCacheTest : public testing::Test,
// This Lookup should erase k1 from the secondary cache and insert
// it into primary cache; then k3 is demoted.
// k2 and k3 are in secondary cache.
handle = cache - > Lookup ( " k1 " , & kHelper , this , Cache : : Priority : : LOW , true ,
handle = cache - > Lookup ( " k1 " , GetHelper ( ) , this , Cache : : Priority : : LOW , true ,
stats . get ( ) ) ;
ASSERT_NE ( handle , nullptr ) ;
ASSERT_EQ ( get_perf_context ( ) - > block_cache_standalone_handle_count , 1 ) ;
@ -407,7 +350,7 @@ class CompressedSecondaryCacheTest : public testing::Test,
cache - > Release ( handle ) ;
// k2 is still in secondary cache.
handle = cache - > Lookup ( " k2 " , & kHelper , this , Cache : : Priority : : LOW , true ,
handle = cache - > Lookup ( " k2 " , GetHelper ( ) , this , Cache : : Priority : : LOW , true ,
stats . get ( ) ) ;
ASSERT_NE ( handle , nullptr ) ;
ASSERT_EQ ( get_perf_context ( ) - > block_cache_standalone_handle_count , 2 ) ;
@ -415,7 +358,7 @@ class CompressedSecondaryCacheTest : public testing::Test,
// Testing SetCapacity().
ASSERT_OK ( secondary_cache - > SetCapacity ( 0 ) ) ;
handle = cache - > Lookup ( " k3 " , & kHelper , this , Cache : : Priority : : LOW , true ,
handle = cache - > Lookup ( " k3 " , GetHelper ( ) , this , Cache : : Priority : : LOW , true ,
stats . get ( ) ) ;
ASSERT_EQ ( handle , nullptr ) ;
@ -425,30 +368,30 @@ class CompressedSecondaryCacheTest : public testing::Test,
ASSERT_EQ ( capacity , 7000 ) ;
auto item1_3 = new TestItem ( str1 . data ( ) , str1 . length ( ) ) ;
// After this Insert, primary cache contains k1.
ASSERT_OK ( cache - > Insert ( " k1 " , item1_3 , & kHelper , str2 . length ( ) ) ) ;
ASSERT_OK ( cache - > Insert ( " k1 " , item1_3 , GetHelper ( ) , str2 . length ( ) ) ) ;
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_insert_dummy_count , 3 ) ;
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_insert_real_count , 4 ) ;
auto item2_3 = new TestItem ( str2 . data ( ) , str2 . length ( ) ) ;
// After this Insert, primary cache contains k2 and secondary cache contains
// k1's dummy item.
ASSERT_OK ( cache - > Insert ( " k2 " , item2_3 , & kHelper , str1 . length ( ) ) ) ;
ASSERT_OK ( cache - > Insert ( " k2 " , item2_3 , GetHelper ( ) , str1 . length ( ) ) ) ;
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_insert_dummy_count , 4 ) ;
auto item1_4 = new TestItem ( str1 . data ( ) , str1 . length ( ) ) ;
// After this Insert, primary cache contains k1 and secondary cache contains
// k1's dummy item and k2's dummy item.
ASSERT_OK ( cache - > Insert ( " k1 " , item1_4 , & kHelper , str2 . length ( ) ) ) ;
ASSERT_OK ( cache - > Insert ( " k1 " , item1_4 , GetHelper ( ) , str2 . length ( ) ) ) ;
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_insert_dummy_count , 5 ) ;
auto item2_4 = new TestItem ( str2 . data ( ) , str2 . length ( ) ) ;
// After this Insert, primary cache contains k2 and secondary cache contains
// k1's real item and k2's dummy item.
ASSERT_OK ( cache - > Insert ( " k2 " , item2_4 , & kHelper , str2 . length ( ) ) ) ;
ASSERT_OK ( cache - > Insert ( " k2 " , item2_4 , GetHelper ( ) , str2 . length ( ) ) ) ;
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_insert_real_count , 5 ) ;
// This Lookup should just insert a dummy handle in the primary cache
// and the k1 is still in the secondary cache.
handle = cache - > Lookup ( " k1 " , & kHelper , this , Cache : : Priority : : LOW , true ,
handle = cache - > Lookup ( " k1 " , GetHelper ( ) , this , Cache : : Priority : : LOW , true ,
stats . get ( ) ) ;
ASSERT_NE ( handle , nullptr ) ;
@ -487,13 +430,14 @@ class CompressedSecondaryCacheTest : public testing::Test,
Random rnd ( 301 ) ;
std : : string str1 = rnd . RandomString ( 1001 ) ;
auto item1 = std : : make_unique < TestItem > ( str1 . data ( ) , str1 . length ( ) ) ;
ASSERT_OK ( cache - > Insert ( " k1 " , item1 . get ( ) , & kHelper , str1 . length ( ) ) ) ;
ASSERT_OK ( cache - > Insert ( " k1 " , item1 . get ( ) , GetHelper ( ) , str1 . length ( ) ) ) ;
item1 . release ( ) ; // Appease clang-analyze "potential memory leak"
Cache : : Handle * handle ;
handle = cache - > Lookup ( " k2 " , nullptr , this , Cache : : Priority : : LOW , true ) ;
ASSERT_EQ ( handle , nullptr ) ;
handle = cache - > Lookup ( " k2 " , & kHelper , this , Cache : : Priority : : LOW , false ) ;
handle =
cache - > Lookup ( " k2 " , GetHelper ( ) , this , Cache : : Priority : : LOW , false ) ;
ASSERT_EQ ( handle , nullptr ) ;
cache . reset ( ) ;
@ -529,25 +473,25 @@ class CompressedSecondaryCacheTest : public testing::Test,
Random rnd ( 301 ) ;
std : : string str1 = rnd . RandomString ( 1001 ) ;
auto item1 = new TestItem ( str1 . data ( ) , str1 . length ( ) ) ;
ASSERT_OK ( cache - > Insert ( " k1 " , item1 , & kHelperFail , str1 . length ( ) ) ) ;
ASSERT_OK ( cache - > Insert ( " k1 " , item1 , GetHelperFail ( ) , str1 . length ( ) ) ) ;
std : : string str2 = rnd . RandomString ( 1002 ) ;
auto item2 = new TestItem ( str2 . data ( ) , str2 . length ( ) ) ;
// k1 should be demoted to the secondary cache.
ASSERT_OK ( cache - > Insert ( " k2 " , item2 , & kHelperFail , str2 . length ( ) ) ) ;
ASSERT_OK ( cache - > Insert ( " k2 " , item2 , GetHelperFail ( ) , str2 . length ( ) ) ) ;
Cache : : Handle * handle ;
handle =
cache - > Lookup ( " k2 " , & kHelperFail , this , Cache : : Priority : : LOW , true ) ;
cache - > Lookup ( " k2 " , GetHelperFail ( ) , this , Cache : : Priority : : LOW , true ) ;
ASSERT_NE ( handle , nullptr ) ;
cache - > Release ( handle ) ;
// This lookup should fail, since k1 demotion would have failed.
handle =
cache - > Lookup ( " k1 " , & kHelperFail , this , Cache : : Priority : : LOW , true ) ;
cache - > Lookup ( " k1 " , GetHelperFail ( ) , this , Cache : : Priority : : LOW , true ) ;
ASSERT_EQ ( handle , nullptr ) ;
// Since k1 was not promoted, k2 should still be in cache.
handle =
cache - > Lookup ( " k2 " , & kHelperFail , this , Cache : : Priority : : LOW , true ) ;
cache - > Lookup ( " k2 " , GetHelperFail ( ) , this , Cache : : Priority : : LOW , true ) ;
ASSERT_NE ( handle , nullptr ) ;
cache - > Release ( handle ) ;
@ -584,23 +528,23 @@ class CompressedSecondaryCacheTest : public testing::Test,
Random rnd ( 301 ) ;
std : : string str1 = rnd . RandomString ( 1001 ) ;
auto item1 = new TestItem ( str1 . data ( ) , str1 . length ( ) ) ;
ASSERT_OK ( cache - > Insert ( " k1 " , item1 , & kHelper , str1 . length ( ) ) ) ;
ASSERT_OK ( cache - > Insert ( " k1 " , item1 , GetHelper ( ) , str1 . length ( ) ) ) ;
std : : string str2 = rnd . RandomString ( 1002 ) ;
auto item2 = new TestItem ( str2 . data ( ) , str2 . length ( ) ) ;
// k1 should be demoted to the secondary cache.
ASSERT_OK ( cache - > Insert ( " k2 " , item2 , & kHelper , str2 . length ( ) ) ) ;
ASSERT_OK ( cache - > Insert ( " k2 " , item2 , GetHelper ( ) , str2 . length ( ) ) ) ;
Cache : : Handle * handle ;
SetFailCreate ( true ) ;
handle = cache - > Lookup ( " k2 " , & kHelper , this , Cache : : Priority : : LOW , true ) ;
handle = cache - > Lookup ( " k2 " , GetHelper ( ) , this , Cache : : Priority : : LOW , true ) ;
ASSERT_NE ( handle , nullptr ) ;
cache - > Release ( handle ) ;
// This lookup should fail, since k1 creation would have failed
handle = cache - > Lookup ( " k1 " , & kHelper , this , Cache : : Priority : : LOW , true ) ;
handle = cache - > Lookup ( " k1 " , GetHelper ( ) , this , Cache : : Priority : : LOW , true ) ;
ASSERT_EQ ( handle , nullptr ) ;
// Since k1 didn't get promoted, k2 should still be in cache
handle = cache - > Lookup ( " k2 " , & kHelper , this , Cache : : Priority : : LOW , true ) ;
handle = cache - > Lookup ( " k2 " , GetHelper ( ) , this , Cache : : Priority : : LOW , true ) ;
ASSERT_NE ( handle , nullptr ) ;
cache - > Release ( handle ) ;
@ -637,27 +581,28 @@ class CompressedSecondaryCacheTest : public testing::Test,
Random rnd ( 301 ) ;
std : : string str1 = rnd . RandomString ( 1001 ) ;
auto item1_1 = new TestItem ( str1 . data ( ) , str1 . length ( ) ) ;
ASSERT_OK ( cache - > Insert ( " k1 " , item1_1 , & kHelper , str1 . length ( ) ) ) ;
ASSERT_OK ( cache - > Insert ( " k1 " , item1_1 , GetHelper ( ) , str1 . length ( ) ) ) ;
std : : string str2 = rnd . RandomString ( 1002 ) ;
std : : string str2_clone { str2 } ;
auto item2 = new TestItem ( str2 . data ( ) , str2 . length ( ) ) ;
// After this Insert, primary cache contains k2 and secondary cache contains
// k1's dummy item.
ASSERT_OK ( cache - > Insert ( " k2 " , item2 , & kHelper , str2 . length ( ) ) ) ;
ASSERT_OK ( cache - > Insert ( " k2 " , item2 , GetHelper ( ) , str2 . length ( ) ) ) ;
// After this Insert, primary cache contains k1 and secondary cache contains
// k1's dummy item and k2's dummy item.
auto item1_2 = new TestItem ( str1 . data ( ) , str1 . length ( ) ) ;
ASSERT_OK ( cache - > Insert ( " k1 " , item1_2 , & kHelper , str1 . length ( ) ) ) ;
ASSERT_OK ( cache - > Insert ( " k1 " , item1_2 , GetHelper ( ) , str1 . length ( ) ) ) ;
auto item2_2 = new TestItem ( str2 . data ( ) , str2 . length ( ) ) ;
// After this Insert, primary cache contains k2 and secondary cache contains
// k1's item and k2's dummy item.
ASSERT_OK ( cache - > Insert ( " k2 " , item2_2 , & kHelper , str2 . length ( ) ) ) ;
ASSERT_OK ( cache - > Insert ( " k2 " , item2_2 , GetHelper ( ) , str2 . length ( ) ) ) ;
Cache : : Handle * handle2 ;
handle2 = cache - > Lookup ( " k2 " , & kHelper , this , Cache : : Priority : : LOW , true ) ;
handle2 =
cache - > Lookup ( " k2 " , GetHelper ( ) , this , Cache : : Priority : : LOW , true ) ;
ASSERT_NE ( handle2 , nullptr ) ;
cache - > Release ( handle2 ) ;
@ -665,12 +610,14 @@ class CompressedSecondaryCacheTest : public testing::Test,
// strict_capacity_limit is true, but the lookup should still succeed.
// A k1's dummy item is inserted into primary cache.
Cache : : Handle * handle1 ;
handle1 = cache - > Lookup ( " k1 " , & kHelper , this , Cache : : Priority : : LOW , true ) ;
handle1 =
cache - > Lookup ( " k1 " , GetHelper ( ) , this , Cache : : Priority : : LOW , true ) ;
ASSERT_NE ( handle1 , nullptr ) ;
cache - > Release ( handle1 ) ;
// Since k1 didn't get inserted, k2 should still be in cache
handle2 = cache - > Lookup ( " k2 " , & kHelper , this , Cache : : Priority : : LOW , true ) ;
handle2 =
cache - > Lookup ( " k2 " , GetHelper ( ) , this , Cache : : Priority : : LOW , true ) ;
ASSERT_NE ( handle2 , nullptr ) ;
cache - > Release ( handle2 ) ;
@ -794,18 +741,8 @@ class CompressedSecondaryCacheTest : public testing::Test,
sec_cache - > GetHelper ( true ) - > del_cb ( chunks_head , /*alloc*/ nullptr ) ;
}
private :
bool fail_create_ ;
} ;
const std : : array < Cache : : CacheItemHelper , kNumCacheEntryRoles >
CompressedSecondaryCacheTest : : kHelperByRole = GenerateHelpersByRole ( ) ;
const Cache : : CacheItemHelper & CompressedSecondaryCacheTest : : kHelper =
CompressedSecondaryCacheTest : : kHelperByRole [ static_cast < int > (
CacheEntryRole : : kDataBlock ) ] ;
class CompressedSecCacheTestWithCompressAndAllocatorParam
: public CompressedSecondaryCacheTest ,
public : : testing : : WithParamInterface < std : : tuple < bool , bool > > {
@ -964,15 +901,15 @@ TEST_P(CompressedSecondaryCacheTestWithCompressionParam, EntryRoles) {
Slice ith_key = Slice ( junk . data ( ) , 5 ) ;
get_perf_context ( ) - > Reset ( ) ;
ASSERT_OK ( sec_cache - > Insert ( ith_key , & item , & kHelperByRole [ i ] ) ) ;
ASSERT_OK ( sec_cache - > Insert ( ith_key , & item , GetHelper ( role ) ) ) ;
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_insert_dummy_count , 1U ) ;
ASSERT_OK ( sec_cache - > Insert ( ith_key , & item , & kHelperByRole [ i ] ) ) ;
ASSERT_OK ( sec_cache - > Insert ( ith_key , & item , GetHelper ( role ) ) ) ;
ASSERT_EQ ( get_perf_context ( ) - > compressed_sec_cache_insert_real_count , 1U ) ;
bool kept_in_sec_cache { true } ;
std : : unique_ptr < SecondaryCacheResultHandle > handle =
sec_cache - > Lookup ( ith_key , & kHelperByRole [ i ] , this , true ,
sec_cache - > Lookup ( ith_key , GetHelper ( role ) , this , true ,
/*advise_erase=*/ true , kept_in_sec_cache ) ;
ASSERT_NE ( handle , nullptr ) ;