@ -87,49 +87,61 @@ class CompressedSecondaryCacheTest : public testing::Test {
void BasicTestHelper ( std : : shared_ptr < SecondaryCache > sec_cache ) {
void BasicTestHelper ( std : : shared_ptr < SecondaryCache > sec_cache ) {
bool is_in_sec_cache { true } ;
bool is_in_sec_cache { true } ;
// Lookup an non-existent key.
// Lookup an non-existent key.
std : : unique_ptr < SecondaryCacheResultHandle > handle0 =
std : : unique_ptr < SecondaryCacheResultHandle > handle0 = sec_cache - > Lookup (
sec_cache - > Lookup ( " k0 " , test_item_creator , true , is_in_sec_cache ) ;
" k0 " , test_item_creator , true , /*advise_erase=*/ true , is_in_sec_cache ) ;
ASSERT_EQ ( handle0 , nullptr ) ;
ASSERT_EQ ( handle0 , nullptr ) ;
Random rnd ( 301 ) ;
Random rnd ( 301 ) ;
// Insert and Lookup the first item.
// Insert and Lookup the item k1 for the first time.
std : : string str1 ;
std : : string str1 ( rnd . RandomString ( 1000 ) ) ;
test : : CompressibleString ( & rnd , 0.25 , 1000 , & str1 ) ;
TestItem item1 ( str1 . data ( ) , str1 . length ( ) ) ;
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 ,
ASSERT_OK ( sec_cache - > Insert ( " k1 " , & item1 ,
& CompressedSecondaryCacheTest : : helper_ ) ) ;
& CompressedSecondaryCacheTest : : helper_ ) ) ;
std : : unique_ptr < SecondaryCacheResultHandle > handle1 =
std : : unique_ptr < SecondaryCacheResultHandle > handle1_1 = sec_cache - > Lookup (
sec_cache - > Lookup ( " k1 " , test_item_creator , true , is_in_sec_cache ) ;
" k1 " , test_item_creator , true , /*advise_erase=*/ false , is_in_sec_cache ) ;
ASSERT_NE ( handle1 , nullptr ) ;
ASSERT_EQ ( handle1_1 , nullptr ) ;
// Insert and Lookup the item k1 for the second time.
ASSERT_OK ( sec_cache - > Insert ( " k1 " , & item1 ,
& CompressedSecondaryCacheTest : : helper_ ) ) ;
std : : unique_ptr < SecondaryCacheResultHandle > handle1_2 = sec_cache - > Lookup (
" k1 " , test_item_creator , true , /*advise_erase=*/ true , is_in_sec_cache ) ;
ASSERT_NE ( handle1_2 , nullptr ) ;
ASSERT_FALSE ( is_in_sec_cache ) ;
ASSERT_FALSE ( is_in_sec_cache ) ;
std : : unique_ptr < TestItem > val1 =
std : : unique_ptr < TestItem > val1 =
std : : unique_ptr < TestItem > ( static_cast < TestItem * > ( handle1 - > Value ( ) ) ) ;
std : : unique_ptr < TestItem > ( static_cast < TestItem * > ( handle1_2 - > Value ( ) ) ) ;
ASSERT_NE ( val1 , nullptr ) ;
ASSERT_NE ( val1 , nullptr ) ;
ASSERT_EQ ( memcmp ( val1 - > Buf ( ) , item1 . Buf ( ) , item1 . Size ( ) ) , 0 ) ;
ASSERT_EQ ( memcmp ( val1 - > Buf ( ) , item1 . Buf ( ) , item1 . Size ( ) ) , 0 ) ;
// Lookup the first item again.
// Lookup the item k1 again.
std : : unique_ptr < SecondaryCacheResultHandle > handle1_1 =
std : : unique_ptr < SecondaryCacheResultHandle > handle1_3 = sec_cache - > Lookup (
sec_cache - > Lookup ( " k1 " , test_item_creator , true , is_in_sec_cache ) ;
" k1 " , test_item_creator , true , /*advise_erase=*/ true , is_in_sec_cache ) ;
ASSERT_EQ ( handle1_1 , nullptr ) ;
ASSERT_EQ ( handle1_3 , nullptr ) ;
// Insert and Lookup the second item.
// Insert and Lookup the item k2.
std : : string str2 ;
std : : string str2 ( rnd . RandomString ( 1000 ) ) ;
test : : CompressibleString ( & rnd , 0.5 , 1000 , & str2 ) ;
TestItem item2 ( str2 . data ( ) , str2 . length ( ) ) ;
TestItem item2 ( str2 . data ( ) , str2 . length ( ) ) ;
ASSERT_OK ( sec_cache - > Insert ( " k2 " , & item2 ,
ASSERT_OK ( sec_cache - > Insert ( " k2 " , & item2 ,
& CompressedSecondaryCacheTest : : helper_ ) ) ;
& CompressedSecondaryCacheTest : : helper_ ) ) ;
std : : unique_ptr < SecondaryCacheResultHandle > handle2 =
std : : unique_ptr < SecondaryCacheResultHandle > handle2_1 = sec_cache - > Lookup (
sec_cache - > Lookup ( " k2 " , test_item_creator , true , is_in_sec_cache ) ;
" k2 " , test_item_creator , true , /*advise_erase=*/ false , is_in_sec_cache ) ;
ASSERT_NE ( handle2 , nullptr ) ;
ASSERT_EQ ( handle2_1 , nullptr ) ;
ASSERT_OK ( sec_cache - > Insert ( " k2 " , & item2 ,
& CompressedSecondaryCacheTest : : helper_ ) ) ;
std : : unique_ptr < SecondaryCacheResultHandle > handle2_2 = sec_cache - > Lookup (
" k2 " , test_item_creator , true , /*advise_erase=*/ false , is_in_sec_cache ) ;
ASSERT_EQ ( handle2_1 , nullptr ) ;
std : : unique_ptr < TestItem > val2 =
std : : unique_ptr < TestItem > val2 =
std : : unique_ptr < TestItem > ( static_cast < TestItem * > ( handle2 - > Value ( ) ) ) ;
std : : unique_ptr < TestItem > ( static_cast < TestItem * > ( handle2_2 - > Value ( ) ) ) ;
ASSERT_NE ( val2 , nullptr ) ;
ASSERT_NE ( val2 , nullptr ) ;
ASSERT_EQ ( memcmp ( val2 - > Buf ( ) , item2 . Buf ( ) , item2 . Size ( ) ) , 0 ) ;
ASSERT_EQ ( memcmp ( val2 - > Buf ( ) , item2 . Buf ( ) , item2 . Size ( ) ) , 0 ) ;
std : : vector < SecondaryCacheResultHandle * > handles = { handle1 . get ( ) ,
std : : vector < SecondaryCacheResultHandle * > handles = { handle1_2 . get ( ) ,
handle2 . get ( ) } ;
handle2_2 . get ( ) } ;
sec_cache - > WaitAll ( handles ) ;
sec_cache - > WaitAll ( handles ) ;
sec_cache . reset ( ) ;
sec_cache . reset ( ) ;
@ -188,36 +200,55 @@ class CompressedSecondaryCacheTest : public testing::Test {
Random rnd ( 301 ) ;
Random rnd ( 301 ) ;
std : : string str1 ( rnd . RandomString ( 1000 ) ) ;
std : : string str1 ( rnd . RandomString ( 1000 ) ) ;
TestItem item1 ( str1 . data ( ) , str1 . length ( ) ) ;
TestItem item1 ( str1 . data ( ) , str1 . length ( ) ) ;
// Insert a dummy handle.
ASSERT_OK ( sec_cache - > Insert ( " k1 " , & item1 ,
& CompressedSecondaryCacheTest : : helper_ ) ) ;
// Insert k1.
ASSERT_OK ( sec_cache - > Insert ( " k1 " , & item1 ,
ASSERT_OK ( sec_cache - > Insert ( " k1 " , & item1 ,
& CompressedSecondaryCacheTest : : helper_ ) ) ;
& CompressedSecondaryCacheTest : : helper_ ) ) ;
// Insert and Lookup the second item.
// Insert and Lookup the second item.
std : : string str2 ( rnd . RandomString ( 200 ) ) ;
std : : string str2 ( rnd . RandomString ( 200 ) ) ;
TestItem item2 ( str2 . data ( ) , str2 . length ( ) ) ;
TestItem item2 ( str2 . data ( ) , str2 . length ( ) ) ;
// k1 is evicted.
// Insert a dummy handle, k1 is not evicted.
ASSERT_OK ( sec_cache - > Insert ( " k2 " , & item2 ,
ASSERT_OK ( sec_cache - > Insert ( " k2 " , & item2 ,
& CompressedSecondaryCacheTest : : helper_ ) ) ;
& CompressedSecondaryCacheTest : : helper_ ) ) ;
bool is_in_sec_cache { false } ;
bool is_in_sec_cache { false } ;
std : : unique_ptr < SecondaryCacheResultHandle > handle1_1 =
std : : unique_ptr < SecondaryCacheResultHandle > handle1 = sec_cache - > Lookup (
sec_cache - > Lookup ( " k1 " , test_item_creator , true , is_in_sec_cache ) ;
" k1 " , test_item_creator , true , /*advise_erase=*/ false , is_in_sec_cache ) ;
ASSERT_EQ ( handle1_1 , nullptr ) ;
ASSERT_EQ ( handle1 , nullptr ) ;
std : : unique_ptr < SecondaryCacheResultHandle > handle2 =
sec_cache - > Lookup ( " k2 " , test_item_creator , true , is_in_sec_cache ) ;
// Insert k2 and k1 is evicted.
ASSERT_OK ( sec_cache - > Insert ( " k2 " , & item2 ,
& CompressedSecondaryCacheTest : : helper_ ) ) ;
std : : unique_ptr < SecondaryCacheResultHandle > handle2 = sec_cache - > Lookup (
" k2 " , test_item_creator , true , /*advise_erase=*/ false , is_in_sec_cache ) ;
ASSERT_NE ( handle2 , nullptr ) ;
ASSERT_NE ( handle2 , nullptr ) ;
std : : unique_ptr < TestItem > val2 =
std : : unique_ptr < TestItem > val2 =
std : : unique_ptr < TestItem > ( static_cast < TestItem * > ( handle2 - > Value ( ) ) ) ;
std : : unique_ptr < TestItem > ( static_cast < TestItem * > ( handle2 - > Value ( ) ) ) ;
ASSERT_NE ( val2 , nullptr ) ;
ASSERT_NE ( val2 , nullptr ) ;
ASSERT_EQ ( memcmp ( val2 - > Buf ( ) , item2 . Buf ( ) , item2 . Size ( ) ) , 0 ) ;
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 ,
& CompressedSecondaryCacheTest : : helper_ ) ) ;
std : : unique_ptr < SecondaryCacheResultHandle > handle1_1 = sec_cache - > Lookup (
" k1 " , test_item_creator , true , /*advise_erase=*/ false , is_in_sec_cache ) ;
ASSERT_EQ ( handle1_1 , nullptr ) ;
// Create Fails.
// Create Fails.
SetFailCreate ( true ) ;
SetFailCreate ( true ) ;
std : : unique_ptr < SecondaryCacheResultHandle > handle2_1 =
std : : unique_ptr < SecondaryCacheResultHandle > handle2_1 = sec_cache - > Lookup (
sec_cache - > Lookup ( " k2 " , test_item_creator , true , is_in_sec_cache ) ;
" k2 " , test_item_creator , true , /*advise_erase=*/ true , is_in_sec_cache ) ;
ASSERT_EQ ( handle2_1 , nullptr ) ;
ASSERT_EQ ( handle2_1 , nullptr ) ;
// Save Fails.
// Save Fails.
std : : string str3 = rnd . RandomString ( 10 ) ;
std : : string str3 = rnd . RandomString ( 10 ) ;
TestItem item3 ( str3 . data ( ) , str3 . length ( ) ) ;
TestItem item3 ( str3 . data ( ) , str3 . length ( ) ) ;
// The Status is OK because a dummy handle is inserted.
ASSERT_OK ( sec_cache - > Insert ( " k3 " , & item3 ,
& CompressedSecondaryCacheTest : : helper_fail_ ) ) ;
ASSERT_NOK ( sec_cache - > Insert ( " k3 " , & item3 ,
ASSERT_NOK ( sec_cache - > Insert ( " k3 " , & item3 ,
& CompressedSecondaryCacheTest : : helper_fail_ ) ) ;
& CompressedSecondaryCacheTest : : helper_fail_ ) ) ;
@ -236,41 +267,56 @@ class CompressedSecondaryCacheTest : public testing::Test {
secondary_cache_opts . compression_type = CompressionType : : kNoCompression ;
secondary_cache_opts . compression_type = CompressionType : : kNoCompression ;
}
}
secondary_cache_opts . capacity = 23 00;
secondary_cache_opts . capacity = 60 00;
secondary_cache_opts . num_shard_bits = 0 ;
secondary_cache_opts . num_shard_bits = 0 ;
std : : shared_ptr < SecondaryCache > secondary_cache =
std : : shared_ptr < SecondaryCache > secondary_cache =
NewCompressedSecondaryCache ( secondary_cache_opts ) ;
NewCompressedSecondaryCache ( secondary_cache_opts ) ;
LRUCacheOptions lru_cache_opts (
LRUCacheOptions lru_cache_opts (
1300 /* capacity */ , 0 /* num_shard_bits */ ,
/*_capacity =*/ 1300 , /*_num_shard_bits =*/ 0 ,
false /* strict_capacity_limit */ , 0.5 /* high_pri_pool_ratio */ ,
/*_strict_capacity_limit =*/ false , /*_high_pri_pool_ratio =*/ 0.5 ,
nullptr /* memory_allocator */ , kDefaultToAdaptiveMutex ,
/*_memory_allocator =*/ nullptr , kDefaultToAdaptiveMutex ,
kDefaultCacheMetadataChargePolicy ) ;
kDefaultCacheMetadataChargePolicy , /*_low_pri_pool_ratio =*/ 0.0 ) ;
lru_cache_opts . secondary_cache = secondary_cache ;
lru_cache_opts . secondary_cache = secondary_cache ;
std : : shared_ptr < Cache > cache = NewLRUCache ( lru_cache_opts ) ;
std : : shared_ptr < Cache > cache = NewLRUCache ( lru_cache_opts ) ;
std : : shared_ptr < Statistics > stats = CreateDBStatistics ( ) ;
std : : shared_ptr < Statistics > stats = CreateDBStatistics ( ) ;
Random rnd ( 301 ) ;
Random rnd ( 301 ) ;
std : : string str1 = rnd . RandomString ( 1001 ) ;
std : : string str1 ;
TestItem * item1_1 = new TestItem ( str1 . data ( ) , str1 . length ( ) ) ;
test : : CompressibleString ( & rnd , 0.5 , 1001 , & str1 ) ;
ASSERT_OK ( cache - > Insert (
std : : string str1_clone { str1 } ;
" k1 " , item1_1 , & CompressedSecondaryCacheTest : : helper_ , str1 . length ( ) ) ) ;
TestItem * item1 = new TestItem ( str1 . data ( ) , str1 . length ( ) ) ;
ASSERT_OK ( cache - > Insert ( " k1 " , item1 , & CompressedSecondaryCacheTest : : helper_ ,
std : : string str2 = rnd . RandomString ( 1012 ) ;
str1 . length ( ) ) ) ;
TestItem * item2_1 = new TestItem ( str2 . data ( ) , str2 . length ( ) ) ;
// After this Insert, primary cache contains k2 and secondary cache contains
std : : string str2 ;
// k1's dummy item.
test : : CompressibleString ( & rnd , 0.5 , 1012 , & str2 ) ;
ASSERT_OK ( cache - > Insert (
TestItem * item2 = new TestItem ( str2 . data ( ) , str2 . length ( ) ) ;
" k2 " , item2_1 , & CompressedSecondaryCacheTest : : helper_ , str2 . length ( ) ) ) ;
// After Insert, cache contains k2 and secondary cache contains k1.
ASSERT_OK ( cache - > Insert ( " k2 " , item2 , & CompressedSecondaryCacheTest : : helper_ ,
std : : string str3 = rnd . RandomString ( 1024 ) ;
str2 . length ( ) ) ) ;
TestItem * item3_1 = new TestItem ( str3 . data ( ) , str3 . length ( ) ) ;
// After this Insert, primary cache contains k3 and secondary cache contains
std : : string str3 ;
// k1's dummy item and k2's dummy item.
test : : CompressibleString ( & rnd , 0.5 , 1024 , & str3 ) ;
ASSERT_OK ( cache - > Insert (
TestItem * item3 = new TestItem ( str3 . data ( ) , str3 . length ( ) ) ;
" k3 " , item3_1 , & CompressedSecondaryCacheTest : : helper_ , str3 . length ( ) ) ) ;
// After Insert, cache contains k3 and secondary cache contains k1 and k2.
ASSERT_OK ( cache - > Insert ( " k3 " , item3 , & CompressedSecondaryCacheTest : : helper_ ,
// After this Insert, primary cache contains k1 and secondary cache contains
str3 . length ( ) ) ) ;
// k1's dummy item, k2's dummy item, and k3's dummy item.
TestItem * item1_2 = new TestItem ( str1 . data ( ) , str1 . length ( ) ) ;
ASSERT_OK ( cache - > Insert (
" k1 " , item1_2 , & CompressedSecondaryCacheTest : : helper_ , str1 . length ( ) ) ) ;
// After this Insert, primary cache contains k2 and secondary cache contains
// k1's item, k2's dummy item, and k3's dummy item.
TestItem * item2_2 = new TestItem ( str2 . data ( ) , str2 . length ( ) ) ;
ASSERT_OK ( cache - > Insert (
" k2 " , item2_2 , & CompressedSecondaryCacheTest : : helper_ , str2 . length ( ) ) ) ;
// After this Insert, primary cache contains k3 and secondary cache contains
// k1's item and k2's item.
TestItem * item3_2 = new TestItem ( str3 . data ( ) , str3 . length ( ) ) ;
ASSERT_OK ( cache - > Insert (
" k3 " , item3_2 , & CompressedSecondaryCacheTest : : helper_ , str3 . length ( ) ) ) ;
Cache : : Handle * handle ;
Cache : : Handle * handle ;
handle = cache - > Lookup ( " k3 " , & CompressedSecondaryCacheTest : : helper_ ,
handle = cache - > Lookup ( " k3 " , & CompressedSecondaryCacheTest : : helper_ ,
@ -279,7 +325,7 @@ class CompressedSecondaryCacheTest : public testing::Test {
ASSERT_NE ( handle , nullptr ) ;
ASSERT_NE ( handle , nullptr ) ;
TestItem * val3 = static_cast < TestItem * > ( cache - > Value ( handle ) ) ;
TestItem * val3 = static_cast < TestItem * > ( cache - > Value ( handle ) ) ;
ASSERT_NE ( val3 , nullptr ) ;
ASSERT_NE ( val3 , nullptr ) ;
ASSERT_EQ ( memcmp ( val3 - > Buf ( ) , item3 - > Buf ( ) , item3 - > Size ( ) ) , 0 ) ;
ASSERT_EQ ( memcmp ( val3 - > Buf ( ) , item3_2 - > Buf ( ) , item3_2 - > Size ( ) ) , 0 ) ;
cache - > Release ( handle ) ;
cache - > Release ( handle ) ;
// Lookup an non-existent key.
// Lookup an non-existent key.
@ -288,17 +334,26 @@ class CompressedSecondaryCacheTest : public testing::Test {
stats . get ( ) ) ;
stats . get ( ) ) ;
ASSERT_EQ ( handle , nullptr ) ;
ASSERT_EQ ( handle , nullptr ) ;
// This Lookup should promote k1 and erase k1 from the secondary cache,
// This Lookup should just insert a dummy handle in the primary cache
// then k3 is demoted. So k2 and k3 are in the secondary cache.
// and the k1 is still in the secondary cache.
handle = cache - > Lookup ( " k1 " , & CompressedSecondaryCacheTest : : helper_ ,
handle = cache - > Lookup ( " k1 " , & CompressedSecondaryCacheTest : : helper_ ,
test_item_creator , Cache : : Priority : : LOW , true ,
test_item_creator , Cache : : Priority : : LOW , true ,
stats . get ( ) ) ;
stats . get ( ) ) ;
ASSERT_NE ( handle , nullptr ) ;
ASSERT_NE ( handle , nullptr ) ;
TestItem * val1_1 = static_cast < TestItem * > ( cache - > Value ( handle ) ) ;
TestItem * val1_1 = static_cast < TestItem * > ( cache - > Value ( handle ) ) ;
ASSERT_NE ( val1_1 , nullptr ) ;
ASSERT_NE ( val1_1 , nullptr ) ;
ASSERT_EQ ( memcmp ( val1_1 - > Buf ( ) , str1_clone . data ( ) , str1_clone . size ( ) ) , 0 ) ;
ASSERT_EQ ( memcmp ( val1_1 - > Buf ( ) , str1 . data ( ) , str1 . size ( ) ) , 0 ) ;
cache - > Release ( handle ) ;
// This Lookup should erase k1 from the secondary cache and insert
// it into primary cache; then k3 is demoted.
handle = cache - > Lookup ( " k1 " , & CompressedSecondaryCacheTest : : helper_ ,
test_item_creator , Cache : : Priority : : LOW , true ,
stats . get ( ) ) ;
ASSERT_NE ( handle , nullptr ) ;
cache - > Release ( handle ) ;
cache - > Release ( handle ) ;
// k2 is still in secondary cache.
handle = cache - > Lookup ( " k2 " , & CompressedSecondaryCacheTest : : helper_ ,
handle = cache - > Lookup ( " k2 " , & CompressedSecondaryCacheTest : : helper_ ,
test_item_creator , Cache : : Priority : : LOW , true ,
test_item_creator , Cache : : Priority : : LOW , true ,
stats . get ( ) ) ;
stats . get ( ) ) ;
@ -321,22 +376,21 @@ class CompressedSecondaryCacheTest : public testing::Test {
secondary_cache_opts . compression_type = CompressionType : : kNoCompression ;
secondary_cache_opts . compression_type = CompressionType : : kNoCompression ;
}
}
secondary_cache_opts . capacity = 23 00;
secondary_cache_opts . capacity = 60 00;
secondary_cache_opts . num_shard_bits = 0 ;
secondary_cache_opts . num_shard_bits = 0 ;
std : : shared_ptr < SecondaryCache > secondary_cache =
std : : shared_ptr < SecondaryCache > secondary_cache =
NewCompressedSecondaryCache ( secondary_cache_opts ) ;
NewCompressedSecondaryCache ( secondary_cache_opts ) ;
LRUCacheOptions opts (
LRUCacheOptions opts (
1024 /* capacity */ , 0 /* num_shard_bits */ ,
/*_capacity=*/ 1300 , /*_num_shard_bits=*/ 0 ,
false /* strict_capacity_limit */ , 0.5 /* high_pri_pool_ratio */ ,
/*_strict_capacity_limit=*/ false , /*_high_pri_pool_ratio=*/ 0.5 ,
nullptr /* memory_allocator */ , kDefaultToAdaptiveMutex ,
/*_memory_allocator=*/ nullptr , kDefaultToAdaptiveMutex ,
kDefaultCacheMetadataChargePolicy ) ;
kDefaultCacheMetadataChargePolicy , /*_low_pri_pool_ratio=*/ 0.0 ) ;
opts . secondary_cache = secondary_cache ;
opts . secondary_cache = secondary_cache ;
std : : shared_ptr < Cache > cache = NewLRUCache ( opts ) ;
std : : shared_ptr < Cache > cache = NewLRUCache ( opts ) ;
Random rnd ( 301 ) ;
Random rnd ( 301 ) ;
std : : string str1 ;
std : : string str1 = rnd . RandomString ( 1001 ) ;
test : : CompressibleString ( & rnd , 0.5 , 1001 , & str1 ) ;
auto item1 =
auto item1 =
std : : unique_ptr < TestItem > ( new TestItem ( str1 . data ( ) , str1 . length ( ) ) ) ;
std : : unique_ptr < TestItem > ( new TestItem ( str1 . data ( ) , str1 . length ( ) ) ) ;
ASSERT_NOK ( cache - > Insert ( " k1 " , item1 . get ( ) , nullptr , str1 . length ( ) ) ) ;
ASSERT_NOK ( cache - > Insert ( " k1 " , item1 . get ( ) , nullptr , str1 . length ( ) ) ) ;
@ -369,30 +423,28 @@ class CompressedSecondaryCacheTest : public testing::Test {
secondary_cache_opts . compression_type = CompressionType : : kNoCompression ;
secondary_cache_opts . compression_type = CompressionType : : kNoCompression ;
}
}
secondary_cache_opts . capacity = 23 00;
secondary_cache_opts . capacity = 60 00;
secondary_cache_opts . num_shard_bits = 0 ;
secondary_cache_opts . num_shard_bits = 0 ;
std : : shared_ptr < SecondaryCache > secondary_cache =
std : : shared_ptr < SecondaryCache > secondary_cache =
NewCompressedSecondaryCache ( secondary_cache_opts ) ;
NewCompressedSecondaryCache ( secondary_cache_opts ) ;
LRUCacheOptions opts (
LRUCacheOptions opts (
1200 /* capacity */ , 0 /* num_shard_bits */ ,
/*_capacity=*/ 1300 , /*_num_shard_bits=*/ 0 ,
false /* strict_capacity_limit */ , 0.5 /* high_pri_pool_ratio */ ,
/*_strict_capacity_limit=*/ false , /*_high_pri_pool_ratio=*/ 0.5 ,
nullptr /* memory_allocator */ , kDefaultToAdaptiveMutex ,
/*_memory_allocator=*/ nullptr , kDefaultToAdaptiveMutex ,
kDefaultCacheMetadataChargePolicy ) ;
kDefaultCacheMetadataChargePolicy , /*_low_pri_pool_ratio=*/ 0.0 ) ;
opts . secondary_cache = secondary_cache ;
opts . secondary_cache = secondary_cache ;
std : : shared_ptr < Cache > cache = NewLRUCache ( opts ) ;
std : : shared_ptr < Cache > cache = NewLRUCache ( opts ) ;
Random rnd ( 301 ) ;
Random rnd ( 301 ) ;
std : : string str1 ;
std : : string str1 = rnd . RandomString ( 1001 ) ;
test : : CompressibleString ( & rnd , 0.5 , 1001 , & str1 ) ;
TestItem * item1 = new TestItem ( str1 . data ( ) , str1 . length ( ) ) ;
TestItem * item1 = new TestItem ( str1 . data ( ) , str1 . length ( ) ) ;
ASSERT_OK ( cache - > Insert ( " k1 " , item1 ,
ASSERT_OK ( cache - > Insert ( " k1 " , item1 ,
& CompressedSecondaryCacheTest : : helper_fail_ ,
& CompressedSecondaryCacheTest : : helper_fail_ ,
str1 . length ( ) ) ) ;
str1 . length ( ) ) ) ;
std : : string str2 ;
std : : string str2 = rnd . RandomString ( 1002 ) ;
test : : CompressibleString ( & rnd , 0.5 , 1002 , & str2 ) ;
TestItem * item2 = new TestItem ( str2 . data ( ) , str2 . length ( ) ) ;
TestItem * item2 = new TestItem ( str2 . data ( ) , str2 . length ( ) ) ;
// k1 should be demoted to the secondary cache.
// k1 should be demoted to the secondary cache.
ASSERT_OK ( cache - > Insert ( " k2 " , item2 ,
ASSERT_OK ( cache - > Insert ( " k2 " , item2 ,
@ -404,11 +456,11 @@ class CompressedSecondaryCacheTest : public testing::Test {
test_item_creator , Cache : : Priority : : LOW , true ) ;
test_item_creator , Cache : : Priority : : LOW , true ) ;
ASSERT_NE ( handle , nullptr ) ;
ASSERT_NE ( handle , nullptr ) ;
cache - > Release ( handle ) ;
cache - > Release ( handle ) ;
// This lookup should fail, since k1 demotion would have failed
// This lookup should fail, since k1 demotion would have failed.
handle = cache - > Lookup ( " k1 " , & CompressedSecondaryCacheTest : : helper_fail_ ,
handle = cache - > Lookup ( " k1 " , & CompressedSecondaryCacheTest : : helper_fail_ ,
test_item_creator , Cache : : Priority : : LOW , true ) ;
test_item_creator , Cache : : Priority : : LOW , true ) ;
ASSERT_EQ ( handle , nullptr ) ;
ASSERT_EQ ( handle , nullptr ) ;
// Since k1 didn't get promoted, k2 should still be in cache
// Since k1 was not promoted, k2 should still be in cache.
handle = cache - > Lookup ( " k2 " , & CompressedSecondaryCacheTest : : helper_fail_ ,
handle = cache - > Lookup ( " k2 " , & CompressedSecondaryCacheTest : : helper_fail_ ,
test_item_creator , Cache : : Priority : : LOW , true ) ;
test_item_creator , Cache : : Priority : : LOW , true ) ;
ASSERT_NE ( handle , nullptr ) ;
ASSERT_NE ( handle , nullptr ) ;
@ -430,29 +482,27 @@ class CompressedSecondaryCacheTest : public testing::Test {
secondary_cache_opts . compression_type = CompressionType : : kNoCompression ;
secondary_cache_opts . compression_type = CompressionType : : kNoCompression ;
}
}
secondary_cache_opts . capacity = 23 00;
secondary_cache_opts . capacity = 60 00;
secondary_cache_opts . num_shard_bits = 0 ;
secondary_cache_opts . num_shard_bits = 0 ;
std : : shared_ptr < SecondaryCache > secondary_cache =
std : : shared_ptr < SecondaryCache > secondary_cache =
NewCompressedSecondaryCache ( secondary_cache_opts ) ;
NewCompressedSecondaryCache ( secondary_cache_opts ) ;
LRUCacheOptions opts (
LRUCacheOptions opts (
1200 /* capacity */ , 0 /* num_shard_bits */ ,
/*_capacity=*/ 1300 , /*_num_shard_bits=*/ 0 ,
false /* strict_capacity_limit */ , 0.5 /* high_pri_pool_ratio */ ,
/*_strict_capacity_limit=*/ false , /*_high_pri_pool_ratio=*/ 0.5 ,
nullptr /* memory_allocator */ , kDefaultToAdaptiveMutex ,
/*_memory_allocator=*/ nullptr , kDefaultToAdaptiveMutex ,
kDefaultCacheMetadataChargePolicy ) ;
kDefaultCacheMetadataChargePolicy , /*_low_pri_pool_ratio=*/ 0.0 ) ;
opts . secondary_cache = secondary_cache ;
opts . secondary_cache = secondary_cache ;
std : : shared_ptr < Cache > cache = NewLRUCache ( opts ) ;
std : : shared_ptr < Cache > cache = NewLRUCache ( opts ) ;
Random rnd ( 301 ) ;
Random rnd ( 301 ) ;
std : : string str1 ;
std : : string str1 = rnd . RandomString ( 1001 ) ;
test : : CompressibleString ( & rnd , 0.5 , 1001 , & str1 ) ;
TestItem * item1 = new TestItem ( str1 . data ( ) , str1 . length ( ) ) ;
TestItem * item1 = new TestItem ( str1 . data ( ) , str1 . length ( ) ) ;
ASSERT_OK ( cache - > Insert ( " k1 " , item1 , & CompressedSecondaryCacheTest : : helper_ ,
ASSERT_OK ( cache - > Insert ( " k1 " , item1 , & CompressedSecondaryCacheTest : : helper_ ,
str1 . length ( ) ) ) ;
str1 . length ( ) ) ) ;
std : : string str2 ;
std : : string str2 = rnd . RandomString ( 1002 ) ;
test : : CompressibleString ( & rnd , 0.5 , 1002 , & str2 ) ;
TestItem * item2 = new TestItem ( str2 . data ( ) , str2 . length ( ) ) ;
TestItem * item2 = new TestItem ( str2 . data ( ) , str2 . length ( ) ) ;
// k1 should be demoted to the secondary cache.
// k1 should be demoted to the secondary cache.
ASSERT_OK ( cache - > Insert ( " k2 " , item2 , & CompressedSecondaryCacheTest : : helper_ ,
ASSERT_OK ( cache - > Insert ( " k2 " , item2 , & CompressedSecondaryCacheTest : : helper_ ,
@ -490,35 +540,46 @@ class CompressedSecondaryCacheTest : public testing::Test {
secondary_cache_opts . compression_type = CompressionType : : kNoCompression ;
secondary_cache_opts . compression_type = CompressionType : : kNoCompression ;
}
}
secondary_cache_opts . capacity = 23 00;
secondary_cache_opts . capacity = 60 00;
secondary_cache_opts . num_shard_bits = 0 ;
secondary_cache_opts . num_shard_bits = 0 ;
std : : shared_ptr < SecondaryCache > secondary_cache =
std : : shared_ptr < SecondaryCache > secondary_cache =
NewCompressedSecondaryCache ( secondary_cache_opts ) ;
NewCompressedSecondaryCache ( secondary_cache_opts ) ;
LRUCacheOptions opts (
LRUCacheOptions opts (
1200 /* capacity */ , 0 /* num_shard_bits */ ,
/*_capacity=*/ 1300 , /*_num_shard_bits=*/ 0 ,
true /* strict_capacity_limit */ , 0.5 /* high_pri_pool_ratio */ ,
/*_strict_capacity_limit=*/ false , /*_high_pri_pool_ratio=*/ 0.5 ,
nullptr /* memory_allocator */ , kDefaultToAdaptiveMutex ,
/*_memory_allocator=*/ nullptr , kDefaultToAdaptiveMutex ,
kDefaultCacheMetadataChargePolicy ) ;
kDefaultCacheMetadataChargePolicy , /*_low_pri_pool_ratio=*/ 0.0 ) ;
opts . secondary_cache = secondary_cache ;
opts . secondary_cache = secondary_cache ;
std : : shared_ptr < Cache > cache = NewLRUCache ( opts ) ;
std : : shared_ptr < Cache > cache = NewLRUCache ( opts ) ;
Random rnd ( 301 ) ;
Random rnd ( 301 ) ;
std : : string str1 ;
std : : string str1 = rnd . RandomString ( 1001 ) ;
test : : CompressibleString ( & rnd , 0.5 , 1001 , & str1 ) ;
TestItem * item1_1 = new TestItem ( str1 . data ( ) , str1 . length ( ) ) ;
TestItem * item1 = new TestItem ( str1 . data ( ) , str1 . length ( ) ) ;
ASSERT_OK ( cache - > Insert (
ASSERT_OK ( cache - > Insert ( " k1 " , item1 , & CompressedSecondaryCacheTest : : helper_ ,
" k1 " , item1_1 , & CompressedSecondaryCacheTest : : helper_ , str1 . length ( ) ) ) ;
str1 . length ( ) ) ) ;
std : : string str2 ;
std : : string str2 = rnd . RandomString ( 1002 ) ;
test : : CompressibleString ( & rnd , 0.5 , 1002 , & str2 ) ;
std : : string str2_clone { str2 } ;
std : : string str2_clone { str2 } ;
TestItem * item2 = new TestItem ( str2 . data ( ) , str2 . length ( ) ) ;
TestItem * item2 = new TestItem ( str2 . data ( ) , str2 . length ( ) ) ;
// k1 should be demoted to the secondary cache.
// After this Insert, primary cache contains k2 and secondary cache contains
// k1's dummy item.
ASSERT_OK ( cache - > Insert ( " k2 " , item2 , & CompressedSecondaryCacheTest : : helper_ ,
ASSERT_OK ( cache - > Insert ( " k2 " , item2 , & CompressedSecondaryCacheTest : : helper_ ,
str2 . length ( ) ) ) ;
str2 . length ( ) ) ) ;
// After this Insert, primary cache contains k1 and secondary cache contains
// k1's dummy item and k2's dummy item.
TestItem * item1_2 = new TestItem ( str1 . data ( ) , str1 . length ( ) ) ;
ASSERT_OK ( cache - > Insert (
" k1 " , item1_2 , & CompressedSecondaryCacheTest : : helper_ , str1 . length ( ) ) ) ;
TestItem * 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 , & CompressedSecondaryCacheTest : : helper_ , str2 . length ( ) ) ) ;
Cache : : Handle * handle2 ;
Cache : : Handle * handle2 ;
handle2 = cache - > Lookup ( " k2 " , & CompressedSecondaryCacheTest : : helper_ ,
handle2 = cache - > Lookup ( " k2 " , & CompressedSecondaryCacheTest : : helper_ ,
test_item_creator , Cache : : Priority : : LOW , true ) ;
test_item_creator , Cache : : Priority : : LOW , true ) ;
@ -527,6 +588,7 @@ class CompressedSecondaryCacheTest : public testing::Test {
// k1 promotion should fail because cache is at capacity and
// k1 promotion should fail because cache is at capacity and
// strict_capacity_limit is true, but the lookup should still succeed.
// strict_capacity_limit is true, but the lookup should still succeed.
// A k1's dummy item is inserted into primary cache.
Cache : : Handle * handle1 ;
Cache : : Handle * handle1 ;
handle1 = cache - > Lookup ( " k1 " , & CompressedSecondaryCacheTest : : helper_ ,
handle1 = cache - > Lookup ( " k1 " , & CompressedSecondaryCacheTest : : helper_ ,
test_item_creator , Cache : : Priority : : LOW , true ) ;
test_item_creator , Cache : : Priority : : LOW , true ) ;
@ -561,22 +623,24 @@ class CompressedSecondaryCacheTest : public testing::Test {
std : : make_unique < CompressedSecondaryCache > ( 1000 , 0 , true , 0.5 , 0.0 ,
std : : make_unique < CompressedSecondaryCache > ( 1000 , 0 , true , 0.5 , 0.0 ,
allocator ) ;
allocator ) ;
Random rnd ( 301 ) ;
Random rnd ( 301 ) ;
// 10000 = 8169 + 1769 + 62 , so there should be 3 chunks after split.
// 8500 = 8169 + 354, so there should be 2 chunks after split.
size_t str_size { 100 00} ;
size_t str_size { 85 00} ;
std : : string str = rnd . RandomString ( static_cast < int > ( str_size ) ) ;
std : : string str = rnd . RandomString ( static_cast < int > ( str_size ) ) ;
size_t charge { 0 } ;
size_t charge { 0 } ;
CacheValueChunk * chunks_head =
CacheValueChunk * chunks_head =
sec_cache - > SplitValueIntoChunks ( str , kLZ4Compression , charge ) ;
sec_cache - > SplitValueIntoChunks ( str , kLZ4Compression , charge ) ;
ASSERT_EQ ( charge , str_size + 3 * ( sizeof ( CacheValueChunk ) - 1 ) ) ;
ASSERT_EQ ( charge , str_size + 2 * ( sizeof ( CacheValueChunk ) - 1 ) ) ;
CacheValueChunk * current_chunk = chunks_head ;
CacheValueChunk * current_chunk = chunks_head ;
ASSERT_EQ ( current_chunk - > size , 8192 - sizeof ( CacheValueChunk ) + 1 ) ;
ASSERT_EQ ( current_chunk - > size , 8192 - sizeof ( CacheValueChunk ) + 1 ) ;
current_chunk = current_chunk - > next ;
current_chunk = current_chunk - > next ;
ASSERT_EQ ( current_chunk - > size , 1792 - sizeof ( CacheValueChunk ) + 1 ) ;
ASSERT_EQ ( current_chunk - > size , 354 - sizeof ( CacheValueChunk ) + 1 ) ;
current_chunk = current_chunk - > next ;
ASSERT_EQ ( current_chunk - > size , 62 ) ;
sec_cache - > DeletionCallback ( " dummy " , chunks_head ) ;
while ( chunks_head ! = nullptr ) {
CacheValueChunk * tmp_chunk = chunks_head ;
chunks_head = chunks_head - > next ;
tmp_chunk - > Free ( ) ;
}
}
}
void MergeChunksIntoValueTest ( ) {
void MergeChunksIntoValueTest ( ) {
@ -618,7 +682,11 @@ class CompressedSecondaryCacheTest : public testing::Test {
std : : string value_str { value . get ( ) , charge } ;
std : : string value_str { value . get ( ) , charge } ;
ASSERT_EQ ( strcmp ( value_str . data ( ) , str . data ( ) ) , 0 ) ;
ASSERT_EQ ( strcmp ( value_str . data ( ) , str . data ( ) ) , 0 ) ;
sec_cache - > DeletionCallback ( " dummy " , chunks_head ) ;
while ( chunks_head ! = nullptr ) {
CacheValueChunk * tmp_chunk = chunks_head ;
chunks_head = chunks_head - > next ;
tmp_chunk - > Free ( ) ;
}
}
}
void SplictValueAndMergeChunksTest ( ) {
void SplictValueAndMergeChunksTest ( ) {
@ -639,13 +707,13 @@ class CompressedSecondaryCacheTest : public testing::Test {
std : : make_unique < CompressedSecondaryCache > ( 1000 , 0 , true , 0.5 , 0.0 ,
std : : make_unique < CompressedSecondaryCache > ( 1000 , 0 , true , 0.5 , 0.0 ,
allocator ) ;
allocator ) ;
Random rnd ( 301 ) ;
Random rnd ( 301 ) ;
// 10000 = 8169 + 1769 + 62 , so there should be 3 chunks after split.
// 8500 = 8169 + 354, so there should be 2 chunks after split.
size_t str_size { 100 00} ;
size_t str_size { 85 00} ;
std : : string str = rnd . RandomString ( static_cast < int > ( str_size ) ) ;
std : : string str = rnd . RandomString ( static_cast < int > ( str_size ) ) ;
size_t charge { 0 } ;
size_t charge { 0 } ;
CacheValueChunk * chunks_head =
CacheValueChunk * chunks_head =
sec_cache - > SplitValueIntoChunks ( str , kLZ4Compression , charge ) ;
sec_cache - > SplitValueIntoChunks ( str , kLZ4Compression , charge ) ;
ASSERT_EQ ( charge , str_size + 3 * ( sizeof ( CacheValueChunk ) - 1 ) ) ;
ASSERT_EQ ( charge , str_size + 2 * ( sizeof ( CacheValueChunk ) - 1 ) ) ;
CacheAllocationPtr value =
CacheAllocationPtr value =
sec_cache - > MergeChunksIntoValue ( chunks_head , charge ) ;
sec_cache - > MergeChunksIntoValue ( chunks_head , charge ) ;
@ -653,7 +721,11 @@ class CompressedSecondaryCacheTest : public testing::Test {
std : : string value_str { value . get ( ) , charge } ;
std : : string value_str { value . get ( ) , charge } ;
ASSERT_EQ ( strcmp ( value_str . data ( ) , str . data ( ) ) , 0 ) ;
ASSERT_EQ ( strcmp ( value_str . data ( ) , str . data ( ) ) , 0 ) ;
sec_cache - > DeletionCallback ( " dummy " , chunks_head ) ;
while ( chunks_head ! = nullptr ) {
CacheValueChunk * tmp_chunk = chunks_head ;
chunks_head = chunks_head - > next ;
tmp_chunk - > Free ( ) ;
}
}
}
private :
private :