@ -41,13 +41,14 @@ class LRUCacheTest : public testing::Test {
}
void NewCache ( size_t capacity , double high_pri_pool_ratio = 0.0 ,
double low_pri_pool_ratio = 1.0 ,
bool use_adaptive_mutex = kDefaultToAdaptiveMutex ) {
DeleteCache ( ) ;
cache_ = reinterpret_cast < LRUCacheShard * > (
port : : cacheline_aligned_alloc ( sizeof ( LRUCacheShard ) ) ) ;
new ( cache_ ) LRUCacheShard (
capacity , false /*strict_capcity_limit*/ , high_pri_pool_ratio ,
use_adaptive_mutex , kDontChargeCacheMetadata ,
low_pri_pool_ratio , use_adaptive_mutex , kDontChargeCacheMetadata ,
24 /*max_upper_hash_bits*/ , nullptr /*secondary_cache*/ ) ;
}
@ -76,32 +77,66 @@ class LRUCacheTest : public testing::Test {
void Erase ( const std : : string & key ) { cache_ - > Erase ( key , 0 /*hash*/ ) ; }
void ValidateLRUList ( std : : vector < std : : string > keys ,
size_t num_high_pri_pool_keys = 0 ) {
size_t num_high_pri_pool_keys = 0 ,
size_t num_low_pri_pool_keys = 0 ,
size_t num_bottom_pri_pool_keys = 0 ) {
LRUHandle * lru ;
LRUHandle * lru_low_pri ;
cache_ - > TEST_GetLRUList ( & lru , & lru_low_pri ) ;
LRUHandle * lru_bottom_pri ;
cache_ - > TEST_GetLRUList ( & lru , & lru_low_pri , & lru_bottom_pri ) ;
LRUHandle * iter = lru ;
bool in_low_pri_pool = false ;
bool in_high_pri_pool = false ;
size_t high_pri_pool_keys = 0 ;
size_t low_pri_pool_keys = 0 ;
size_t bottom_pri_pool_keys = 0 ;
if ( iter = = lru_bottom_pri ) {
in_low_pri_pool = true ;
in_high_pri_pool = false ;
}
if ( iter = = lru_low_pri ) {
in_low_pri_pool = false ;
in_high_pri_pool = true ;
}
for ( const auto & key : keys ) {
iter = iter - > next ;
ASSERT_NE ( lru , iter ) ;
ASSERT_EQ ( key , iter - > key ( ) . ToString ( ) ) ;
ASSERT_EQ ( in_high_pri_pool , iter - > InHighPriPool ( ) ) ;
ASSERT_EQ ( in_low_pri_pool , iter - > InLowPriPool ( ) ) ;
if ( in_high_pri_pool ) {
ASSERT_FALSE ( iter - > InLowPriPool ( ) ) ;
high_pri_pool_keys + + ;
} else if ( in_low_pri_pool ) {
ASSERT_FALSE ( iter - > InHighPriPool ( ) ) ;
low_pri_pool_keys + + ;
} else {
bottom_pri_pool_keys + + ;
}
if ( iter = = lru_bottom_pri ) {
ASSERT_FALSE ( in_low_pri_pool ) ;
ASSERT_FALSE ( in_high_pri_pool ) ;
in_low_pri_pool = true ;
in_high_pri_pool = false ;
}
if ( iter = = lru_low_pri ) {
ASSERT_TRUE ( in_low_pri_pool ) ;
ASSERT_FALSE ( in_high_pri_pool ) ;
in_low_pri_pool = false ;
in_high_pri_pool = true ;
}
}
ASSERT_EQ ( lru , iter - > next ) ;
ASSERT_FALSE ( in_low_pri_pool ) ;
ASSERT_TRUE ( in_high_pri_pool ) ;
ASSERT_EQ ( num_high_pri_pool_keys , high_pri_pool_keys ) ;
ASSERT_EQ ( num_low_pri_pool_keys , low_pri_pool_keys ) ;
ASSERT_EQ ( num_bottom_pri_pool_keys , bottom_pri_pool_keys ) ;
}
private :
@ -113,98 +148,219 @@ TEST_F(LRUCacheTest, BasicLRU) {
for ( char ch = ' a ' ; ch < = ' e ' ; ch + + ) {
Insert ( ch ) ;
}
ValidateLRUList ( { " a " , " b " , " c " , " d " , " e " } ) ;
ValidateLRUList ( { " a " , " b " , " c " , " d " , " e " } , 0 , 5 ) ;
for ( char ch = ' x ' ; ch < = ' z ' ; ch + + ) {
Insert ( ch ) ;
}
ValidateLRUList ( { " d " , " e " , " x " , " y " , " z " } ) ;
ValidateLRUList ( { " d " , " e " , " x " , " y " , " z " } , 0 , 5 ) ;
ASSERT_FALSE ( Lookup ( " b " ) ) ;
ValidateLRUList ( { " d " , " e " , " x " , " y " , " z " } ) ;
ValidateLRUList ( { " d " , " e " , " x " , " y " , " z " } , 0 , 5 ) ;
ASSERT_TRUE ( Lookup ( " e " ) ) ;
ValidateLRUList ( { " d " , " x " , " y " , " z " , " e " } ) ;
ValidateLRUList ( { " d " , " x " , " y " , " z " , " e " } , 0 , 5 ) ;
ASSERT_TRUE ( Lookup ( " z " ) ) ;
ValidateLRUList ( { " d " , " x " , " y " , " e " , " z " } ) ;
ValidateLRUList ( { " d " , " x " , " y " , " e " , " z " } , 0 , 5 ) ;
Erase ( " x " ) ;
ValidateLRUList ( { " d " , " y " , " e " , " z " } ) ;
ValidateLRUList ( { " d " , " y " , " e " , " z " } , 0 , 4 ) ;
ASSERT_TRUE ( Lookup ( " d " ) ) ;
ValidateLRUList ( { " y " , " e " , " z " , " d " } ) ;
ValidateLRUList ( { " y " , " e " , " z " , " d " } , 0 , 4 ) ;
Insert ( " u " ) ;
ValidateLRUList ( { " y " , " e " , " z " , " d " , " u " } ) ;
ValidateLRUList ( { " y " , " e " , " z " , " d " , " u " } , 0 , 5 ) ;
Insert ( " v " ) ;
ValidateLRUList ( { " e " , " z " , " d " , " u " , " v " } ) ;
ValidateLRUList ( { " e " , " z " , " d " , " u " , " v " } , 0 , 5 ) ;
}
TEST_F ( LRUCacheTest , MidpointInsertion ) {
// Allocate 2 cache entries to high-pri pool.
NewCache ( 5 , 0.45 ) ;
TEST_F ( LRUCacheTest , LowPriority MidpointInsertion) {
// Allocate 2 cache entries to high-pri pool and 3 to low-pri pool .
NewCache ( 5 , /* high_pri_pool_ratio */ 0.40 , /* low_pri_pool_ratio */ 0.60 ) ;
Insert ( " a " , Cache : : Priority : : LOW ) ;
Insert ( " b " , Cache : : Priority : : LOW ) ;
Insert ( " c " , Cache : : Priority : : LOW ) ;
Insert ( " x " , Cache : : Priority : : HIGH ) ;
Insert ( " y " , Cache : : Priority : : HIGH ) ;
ValidateLRUList ( { " a " , " b " , " c " , " x " , " y " } , 2 ) ;
ValidateLRUList ( { " a " , " b " , " c " , " x " , " y " } , 2 , 3 ) ;
// Low-pri entries inserted to the tail of low-pri list (the midpoint).
// After lookup, it will move to the tail of the full list.
Insert ( " d " , Cache : : Priority : : LOW ) ;
ValidateLRUList ( { " b " , " c " , " d " , " x " , " y " } , 2 ) ;
ValidateLRUList ( { " b " , " c " , " d " , " x " , " y " } , 2 , 3 ) ;
ASSERT_TRUE ( Lookup ( " d " ) ) ;
ValidateLRUList ( { " b " , " c " , " x " , " y " , " d " } , 2 ) ;
ValidateLRUList ( { " b " , " c " , " x " , " y " , " d " } , 2 , 3 ) ;
// High-pri entries will be inserted to the tail of full list.
Insert ( " z " , Cache : : Priority : : HIGH ) ;
ValidateLRUList ( { " c " , " x " , " y " , " d " , " z " } , 2 ) ;
ValidateLRUList ( { " c " , " x " , " y " , " d " , " z " } , 2 , 3 ) ;
}
TEST_F ( LRUCacheTest , BottomPriorityMidpointInsertion ) {
// Allocate 2 cache entries to high-pri pool and 2 to low-pri pool.
NewCache ( 6 , /* high_pri_pool_ratio */ 0.35 , /* low_pri_pool_ratio */ 0.35 ) ;
Insert ( " a " , Cache : : Priority : : BOTTOM ) ;
Insert ( " b " , Cache : : Priority : : BOTTOM ) ;
Insert ( " i " , Cache : : Priority : : LOW ) ;
Insert ( " j " , Cache : : Priority : : LOW ) ;
Insert ( " x " , Cache : : Priority : : HIGH ) ;
Insert ( " y " , Cache : : Priority : : HIGH ) ;
ValidateLRUList ( { " a " , " b " , " i " , " j " , " x " , " y " } , 2 , 2 , 2 ) ;
// Low-pri entries will be inserted to the tail of low-pri list (the
// midpoint). After lookup, 'k' will move to the tail of the full list, and
// 'x' will spill over to the low-pri pool.
Insert ( " k " , Cache : : Priority : : LOW ) ;
ValidateLRUList ( { " b " , " i " , " j " , " k " , " x " , " y " } , 2 , 2 , 2 ) ;
ASSERT_TRUE ( Lookup ( " k " ) ) ;
ValidateLRUList ( { " b " , " i " , " j " , " x " , " y " , " k " } , 2 , 2 , 2 ) ;
// High-pri entries will be inserted to the tail of full list. Although y was
// inserted with high priority, it got spilled over to the low-pri pool. As
// a result, j also got spilled over to the bottom-pri pool.
Insert ( " z " , Cache : : Priority : : HIGH ) ;
ValidateLRUList ( { " i " , " j " , " x " , " y " , " k " , " z " } , 2 , 2 , 2 ) ;
Erase ( " x " ) ;
ValidateLRUList ( { " i " , " j " , " y " , " k " , " z " } , 2 , 1 , 2 ) ;
Erase ( " y " ) ;
ValidateLRUList ( { " i " , " j " , " k " , " z " } , 2 , 0 , 2 ) ;
// Bottom-pri entries will be inserted to the tail of bottom-pri list.
Insert ( " c " , Cache : : Priority : : BOTTOM ) ;
ValidateLRUList ( { " i " , " j " , " c " , " k " , " z " } , 2 , 0 , 3 ) ;
Insert ( " d " , Cache : : Priority : : BOTTOM ) ;
ValidateLRUList ( { " i " , " j " , " c " , " d " , " k " , " z " } , 2 , 0 , 4 ) ;
Insert ( " e " , Cache : : Priority : : BOTTOM ) ;
ValidateLRUList ( { " j " , " c " , " d " , " e " , " k " , " z " } , 2 , 0 , 4 ) ;
// Low-pri entries will be inserted to the tail of low-pri list (the
// midpoint).
Insert ( " l " , Cache : : Priority : : LOW ) ;
ValidateLRUList ( { " c " , " d " , " e " , " l " , " k " , " z " } , 2 , 1 , 3 ) ;
Insert ( " m " , Cache : : Priority : : LOW ) ;
ValidateLRUList ( { " d " , " e " , " l " , " m " , " k " , " z " } , 2 , 2 , 2 ) ;
Erase ( " k " ) ;
ValidateLRUList ( { " d " , " e " , " l " , " m " , " z " } , 1 , 2 , 2 ) ;
Erase ( " z " ) ;
ValidateLRUList ( { " d " , " e " , " l " , " m " } , 0 , 2 , 2 ) ;
// Bottom-pri entries will be inserted to the tail of bottom-pri list.
Insert ( " f " , Cache : : Priority : : BOTTOM ) ;
ValidateLRUList ( { " d " , " e " , " f " , " l " , " m " } , 0 , 2 , 3 ) ;
Insert ( " g " , Cache : : Priority : : BOTTOM ) ;
ValidateLRUList ( { " d " , " e " , " f " , " g " , " l " , " m " } , 0 , 2 , 4 ) ;
// High-pri entries will be inserted to the tail of full list.
Insert ( " o " , Cache : : Priority : : HIGH ) ;
ValidateLRUList ( { " e " , " f " , " g " , " l " , " m " , " o " } , 1 , 2 , 3 ) ;
Insert ( " p " , Cache : : Priority : : HIGH ) ;
ValidateLRUList ( { " f " , " g " , " l " , " m " , " o " , " p " } , 2 , 2 , 2 ) ;
}
TEST_F ( LRUCacheTest , EntriesWithPriority ) {
// Allocate 2 cache entries to high-pri pool.
NewCache ( 5 , 0.45 ) ;
// Allocate 2 cache entries to high-pri pool and 2 to low-pri pool .
NewCache ( 6 , /* high_pri_pool_ratio */ 0.35 , /* low_pri_pool_ratio */ 0.3 5) ;
Insert ( " a " , Cache : : Priority : : LOW ) ;
Insert ( " b " , Cache : : Priority : : LOW ) ;
ValidateLRUList ( { " a " , " b " } , 0 , 2 , 0 ) ;
// Low-pri entries can overflow to bottom-pri pool.
Insert ( " c " , Cache : : Priority : : LOW ) ;
ValidateLRUList ( { " a " , " b " , " c " } , 0 ) ;
ValidateLRUList ( { " a " , " b " , " c " } , 0 , 2 , 1 ) ;
// Low-pri entries can take high-pri pool capacity if available
// Bottom-pri entries can take high-pri pool capacity if available
Insert ( " t " , Cache : : Priority : : LOW ) ;
Insert ( " u " , Cache : : Priority : : LOW ) ;
ValidateLRUList ( { " a " , " b " , " c " , " t " , " u " } , 0 , 2 , 3 ) ;
Insert ( " v " , Cache : : Priority : : LOW ) ;
ValidateLRUList ( { " a " , " b " , " c " , " u " , " v " } , 0 ) ;
ValidateLRUList ( { " a " , " b " , " c " , " t " , " u " , " v " } , 0 , 2 , 4 ) ;
Insert ( " w " , Cache : : Priority : : LOW ) ;
ValidateLRUList ( { " b " , " c " , " t " , " u " , " v " , " w " } , 0 , 2 , 4 ) ;
Insert ( " X " , Cache : : Priority : : HIGH ) ;
Insert ( " Y " , Cache : : Priority : : HIGH ) ;
ValidateLRUList ( { " c " , " u " , " v " , " X " , " Y " } , 2 ) ;
ValidateLRUList ( { " t " , " u " , " v " , " w " , " X " , " Y " } , 2 , 2 , 2 ) ;
// High-pri entries can overflow to low-pri pool.
// After lookup, the high-pri entry 'X' got spilled over to the low-pri pool.
// The low-pri entry 'v' got spilled over to the bottom-pri pool.
Insert ( " Z " , Cache : : Priority : : HIGH ) ;
ValidateLRUList ( { " u " , " v " , " X " , " Y " , " Z " } , 2 ) ;
ValidateLRUList ( { " u " , " v " , " w " , " X " , " Y " , " Z " } , 2 , 2 , 2 ) ;
// Low-pri entries will be inserted to head of low-pri pool.
Insert ( " a " , Cache : : Priority : : LOW ) ;
ValidateLRUList ( { " v " , " X " , " a " , " Y " , " Z " } , 2 ) ;
ValidateLRUList ( { " v " , " w " , " X " , " a " , " Y " , " Z " } , 2 , 2 , 2 ) ;
// Low-pri entries will be inserted to head of high-pri pool after lookup.
// After lookup, the high-pri entry 'Y' got spilled over to the low-pri pool.
// The low-pri entry 'X' got spilled over to the bottom-pri pool.
ASSERT_TRUE ( Lookup ( " v " ) ) ;
ValidateLRUList ( { " X " , " a " , " Y " , " Z " , " v " } , 2 ) ;
ValidateLRUList ( { " w " , " X " , " a " , " Y " , " Z " , " v " } , 2 , 2 , 2 ) ;
// High-pri entries will be inserted to the head of the list after lookup.
// After lookup, the high-pri entry 'Z' got spilled over to the low-pri pool.
// The low-pri entry 'a' got spilled over to the bottom-pri pool.
ASSERT_TRUE ( Lookup ( " X " ) ) ;
ValidateLRUList ( { " a " , " Y " , " Z " , " v " , " X " } , 2 ) ;
ValidateLRUList ( { " w " , " a " , " Y " , " Z " , " v " , " X " } , 2 , 2 , 2 ) ;
// After lookup, the low pri entry 'Z' got promoted back to high-pri pool. The
// high-pri entry 'v' got spilled over to the low-pri pool.
ASSERT_TRUE ( Lookup ( " Z " ) ) ;
ValidateLRUList ( { " a " , " Y " , " v " , " X " , " Z " } , 2 ) ;
ValidateLRUList ( { " w " , " a " , " Y " , " v " , " X " , " Z " } , 2 , 2 , 2 ) ;
Erase ( " Y " ) ;
ValidateLRUList ( { " a " , " v " , " X " , " Z " } , 2 ) ;
ValidateLRUList ( { " w " , " a " , " v " , " X " , " Z " } , 2 , 1 , 2 ) ;
Erase ( " X " ) ;
ValidateLRUList ( { " a " , " v " , " Z " } , 1 ) ;
ValidateLRUList ( { " w " , " a " , " v " , " Z " } , 1 , 1 , 2 ) ;
Insert ( " d " , Cache : : Priority : : LOW ) ;
Insert ( " e " , Cache : : Priority : : LOW ) ;
ValidateLRUList ( { " a " , " v " , " d " , " e " , " Z " } , 1 ) ;
ValidateLRUList ( { " w " , " a " , " v " , " d " , " e " , " Z " } , 1 , 2 , 3 ) ;
Insert ( " f " , Cache : : Priority : : LOW ) ;
Insert ( " g " , Cache : : Priority : : LOW ) ;
ValidateLRUList ( { " d " , " e " , " f " , " g " , " Z " } , 1 ) ;
ValidateLRUList ( { " v " , " d " , " e " , " f " , " g " , " Z " } , 1 , 2 , 3 ) ;
ASSERT_TRUE ( Lookup ( " d " ) ) ;
ValidateLRUList ( { " v " , " e " , " f " , " g " , " Z " , " d " } , 2 , 2 , 2 ) ;
// Erase some entries.
Erase ( " e " ) ;
Erase ( " f " ) ;
Erase ( " Z " ) ;
ValidateLRUList ( { " v " , " g " , " d " } , 1 , 1 , 1 ) ;
// Bottom-pri entries can take low- and high-pri pool capacity if available
Insert ( " o " , Cache : : Priority : : BOTTOM ) ;
ValidateLRUList ( { " v " , " o " , " g " , " d " } , 1 , 1 , 2 ) ;
Insert ( " p " , Cache : : Priority : : BOTTOM ) ;
ValidateLRUList ( { " v " , " o " , " p " , " g " , " d " } , 1 , 1 , 3 ) ;
Insert ( " q " , Cache : : Priority : : BOTTOM ) ;
ValidateLRUList ( { " v " , " o " , " p " , " q " , " g " , " d " } , 1 , 1 , 4 ) ;
// High-pri entries can overflow to low-pri pool, and bottom-pri entries will
// be evicted.
Insert ( " x " , Cache : : Priority : : HIGH ) ;
ValidateLRUList ( { " o " , " p " , " q " , " g " , " d " , " x " } , 2 , 1 , 3 ) ;
Insert ( " y " , Cache : : Priority : : HIGH ) ;
ValidateLRUList ( { " p " , " q " , " g " , " d " , " x " , " y " } , 2 , 2 , 2 ) ;
Insert ( " z " , Cache : : Priority : : HIGH ) ;
ValidateLRUList ( { " q " , " g " , " d " , " x " , " y " , " z " } , 2 , 2 , 2 ) ;
// 'g' is bottom-pri before this lookup, it will be inserted to head of
// high-pri pool after lookup.
ASSERT_TRUE ( Lookup ( " g " ) ) ;
ValidateLRUList ( { " q " , " d " , " x " , " y " , " z " , " g " } , 2 , 2 , 2 ) ;
// High-pri entries will be inserted to head of high-pri pool after lookup.
ASSERT_TRUE ( Lookup ( " z " ) ) ;
ValidateLRUList ( { " q " , " d " , " x " , " y " , " g " , " z " } , 2 , 2 , 2 ) ;
// Bottom-pri entries will be inserted to head of high-pri pool after lookup.
ASSERT_TRUE ( Lookup ( " d " ) ) ;
ValidateLRUList ( { " e " , " f " , " g " , " Z " , " d " } , 2 ) ;
ValidateLRUList ( { " q " , " x " , " y " , " g " , " z " , " d " } , 2 , 2 , 2 ) ;
// Bottom-pri entries will be inserted to the tail of bottom-pri list.
Insert ( " m " , Cache : : Priority : : BOTTOM ) ;
ValidateLRUList ( { " x " , " m " , " y " , " g " , " z " , " d " } , 2 , 2 , 2 ) ;
// Bottom-pri entries will be inserted to head of high-pri pool after lookup.
ASSERT_TRUE ( Lookup ( " m " ) ) ;
ValidateLRUList ( { " x " , " y " , " g " , " z " , " d " , " m " } , 2 , 2 , 2 ) ;
}
// TODO: FastLRUCache and ClockCache use the same tests. We can probably remove
@ -547,8 +703,9 @@ class TestSecondaryCache : public SecondaryCache {
explicit TestSecondaryCache ( size_t capacity )
: num_inserts_ ( 0 ) , num_lookups_ ( 0 ) , inject_failure_ ( false ) {
cache_ = NewLRUCache ( capacity , 0 , false , 0.5 , nullptr ,
kDefaultToAdaptiveMutex , kDontChargeCacheMetadata ) ;
cache_ =
NewLRUCache ( capacity , 0 , false , 0.5 /* high_pri_pool_ratio */ , nullptr ,
kDefaultToAdaptiveMutex , kDontChargeCacheMetadata ) ;
}
~ TestSecondaryCache ( ) override { cache_ . reset ( ) ; }
@ -785,7 +942,10 @@ Cache::CacheItemHelper LRUCacheSecondaryCacheTest::helper_fail_(
LRUCacheSecondaryCacheTest : : DeletionCallback ) ;
TEST_F ( LRUCacheSecondaryCacheTest , BasicTest ) {
LRUCacheOptions opts ( 1024 , 0 , false , 0.5 , nullptr , kDefaultToAdaptiveMutex ,
LRUCacheOptions opts ( 1024 /* capacity */ , 0 /* num_shard_bits */ ,
false /* strict_capacity_limit */ ,
0.5 /* high_pri_pool_ratio */ ,
nullptr /* memory_allocator */ , kDefaultToAdaptiveMutex ,
kDontChargeCacheMetadata ) ;
std : : shared_ptr < TestSecondaryCache > secondary_cache =
std : : make_shared < TestSecondaryCache > ( 2048 ) ;
@ -831,7 +991,10 @@ TEST_F(LRUCacheSecondaryCacheTest, BasicTest) {
}
TEST_F ( LRUCacheSecondaryCacheTest , BasicFailTest ) {
LRUCacheOptions opts ( 1024 , 0 , false , 0.5 , nullptr , kDefaultToAdaptiveMutex ,
LRUCacheOptions opts ( 1024 /* capacity */ , 0 /* num_shard_bits */ ,
false /* strict_capacity_limit */ ,
0.5 /* high_pri_pool_ratio */ ,
nullptr /* memory_allocator */ , kDefaultToAdaptiveMutex ,
kDontChargeCacheMetadata ) ;
std : : shared_ptr < TestSecondaryCache > secondary_cache =
std : : make_shared < TestSecondaryCache > ( 2048 ) ;
@ -862,7 +1025,10 @@ TEST_F(LRUCacheSecondaryCacheTest, BasicFailTest) {
}
TEST_F ( LRUCacheSecondaryCacheTest , SaveFailTest ) {
LRUCacheOptions opts ( 1024 , 0 , false , 0.5 , nullptr , kDefaultToAdaptiveMutex ,
LRUCacheOptions opts ( 1024 /* capacity */ , 0 /* num_shard_bits */ ,
false /* strict_capacity_limit */ ,
0.5 /* high_pri_pool_ratio */ ,
nullptr /* memory_allocator */ , kDefaultToAdaptiveMutex ,
kDontChargeCacheMetadata ) ;
std : : shared_ptr < TestSecondaryCache > secondary_cache =
std : : make_shared < TestSecondaryCache > ( 2048 ) ;
@ -909,7 +1075,10 @@ TEST_F(LRUCacheSecondaryCacheTest, SaveFailTest) {
}
TEST_F ( LRUCacheSecondaryCacheTest , CreateFailTest ) {
LRUCacheOptions opts ( 1024 , 0 , false , 0.5 , nullptr , kDefaultToAdaptiveMutex ,
LRUCacheOptions opts ( 1024 /* capacity */ , 0 /* num_shard_bits */ ,
false /* strict_capacity_limit */ ,
0.5 /* high_pri_pool_ratio */ ,
nullptr /* memory_allocator */ , kDefaultToAdaptiveMutex ,
kDontChargeCacheMetadata ) ;
std : : shared_ptr < TestSecondaryCache > secondary_cache =
std : : make_shared < TestSecondaryCache > ( 2048 ) ;
@ -952,8 +1121,11 @@ TEST_F(LRUCacheSecondaryCacheTest, CreateFailTest) {
}
TEST_F ( LRUCacheSecondaryCacheTest , FullCapacityTest ) {
LRUCacheOptions opts ( 1024 , 0 , /*_strict_capacity_limit=*/ true , 0.5 , nullptr ,
kDefaultToAdaptiveMutex , kDontChargeCacheMetadata ) ;
LRUCacheOptions opts ( 1024 /* capacity */ , 0 /* num_shard_bits */ ,
true /* strict_capacity_limit */ ,
0.5 /* high_pri_pool_ratio */ ,
nullptr /* memory_allocator */ , kDefaultToAdaptiveMutex ,
kDontChargeCacheMetadata ) ;
std : : shared_ptr < TestSecondaryCache > secondary_cache =
std : : make_shared < TestSecondaryCache > ( 2048 ) ;
opts . secondary_cache = secondary_cache ;
@ -1003,8 +1175,11 @@ TEST_F(LRUCacheSecondaryCacheTest, FullCapacityTest) {
// if we try to insert block_1 to the block cache, it will always fails. Only
// block_2 will be successfully inserted into the block cache.
TEST_F ( DBSecondaryCacheTest , TestSecondaryCacheCorrectness1 ) {
LRUCacheOptions opts ( 4 * 1024 , 0 , false , 0.5 , nullptr ,
kDefaultToAdaptiveMutex , kDontChargeCacheMetadata ) ;
LRUCacheOptions opts ( 4 * 1024 /* capacity */ , 0 /* num_shard_bits */ ,
false /* strict_capacity_limit */ ,
0.5 /* high_pri_pool_ratio */ ,
nullptr /* memory_allocator */ , kDefaultToAdaptiveMutex ,
kDontChargeCacheMetadata ) ;
std : : shared_ptr < TestSecondaryCache > secondary_cache (
new TestSecondaryCache ( 2048 * 1024 ) ) ;
opts . secondary_cache = secondary_cache ;
@ -1097,7 +1272,10 @@ TEST_F(DBSecondaryCacheTest, TestSecondaryCacheCorrectness1) {
// insert and cache block_1 in the block cache (this is the different place
// from TestSecondaryCacheCorrectness1)
TEST_F ( DBSecondaryCacheTest , TestSecondaryCacheCorrectness2 ) {
LRUCacheOptions opts ( 6100 , 0 , false , 0.5 , nullptr , kDefaultToAdaptiveMutex ,
LRUCacheOptions opts ( 6100 /* capacity */ , 0 /* num_shard_bits */ ,
false /* strict_capacity_limit */ ,
0.5 /* high_pri_pool_ratio */ ,
nullptr /* memory_allocator */ , kDefaultToAdaptiveMutex ,
kDontChargeCacheMetadata ) ;
std : : shared_ptr < TestSecondaryCache > secondary_cache (
new TestSecondaryCache ( 2048 * 1024 ) ) ;
@ -1187,8 +1365,11 @@ TEST_F(DBSecondaryCacheTest, TestSecondaryCacheCorrectness2) {
// cache all the blocks in the block cache and there is not secondary cache
// insertion. 2 lookup is needed for the blocks.
TEST_F ( DBSecondaryCacheTest , NoSecondaryCacheInsertion ) {
LRUCacheOptions opts ( 1024 * 1024 , 0 , false , 0.5 , nullptr ,
kDefaultToAdaptiveMutex , kDontChargeCacheMetadata ) ;
LRUCacheOptions opts ( 1024 * 1024 /* capacity */ , 0 /* num_shard_bits */ ,
false /* strict_capacity_limit */ ,
0.5 /* high_pri_pool_ratio */ ,
nullptr /* memory_allocator */ , kDefaultToAdaptiveMutex ,
kDontChargeCacheMetadata ) ;
std : : shared_ptr < TestSecondaryCache > secondary_cache (
new TestSecondaryCache ( 2048 * 1024 ) ) ;
opts . secondary_cache = secondary_cache ;
@ -1238,8 +1419,11 @@ TEST_F(DBSecondaryCacheTest, NoSecondaryCacheInsertion) {
}
TEST_F ( DBSecondaryCacheTest , SecondaryCacheIntensiveTesting ) {
LRUCacheOptions opts ( 8 * 1024 , 0 , false , 0.5 , nullptr ,
kDefaultToAdaptiveMutex , kDontChargeCacheMetadata ) ;
LRUCacheOptions opts ( 8 * 1024 /* capacity */ , 0 /* num_shard_bits */ ,
false /* strict_capacity_limit */ ,
0.5 /* high_pri_pool_ratio */ ,
nullptr /* memory_allocator */ , kDefaultToAdaptiveMutex ,
kDontChargeCacheMetadata ) ;
std : : shared_ptr < TestSecondaryCache > secondary_cache (
new TestSecondaryCache ( 2048 * 1024 ) ) ;
opts . secondary_cache = secondary_cache ;
@ -1284,8 +1468,11 @@ TEST_F(DBSecondaryCacheTest, SecondaryCacheIntensiveTesting) {
// if we try to insert block_1 to the block cache, it will always fails. Only
// block_2 will be successfully inserted into the block cache.
TEST_F ( DBSecondaryCacheTest , SecondaryCacheFailureTest ) {
LRUCacheOptions opts ( 4 * 1024 , 0 , false , 0.5 , nullptr ,
kDefaultToAdaptiveMutex , kDontChargeCacheMetadata ) ;
LRUCacheOptions opts ( 4 * 1024 /* capacity */ , 0 /* num_shard_bits */ ,
false /* strict_capacity_limit */ ,
0.5 /* high_pri_pool_ratio */ ,
nullptr /* memory_allocator */ , kDefaultToAdaptiveMutex ,
kDontChargeCacheMetadata ) ;
std : : shared_ptr < TestSecondaryCache > secondary_cache (
new TestSecondaryCache ( 2048 * 1024 ) ) ;
opts . secondary_cache = secondary_cache ;
@ -1373,7 +1560,10 @@ TEST_F(DBSecondaryCacheTest, SecondaryCacheFailureTest) {
}
TEST_F ( LRUCacheSecondaryCacheTest , BasicWaitAllTest ) {
LRUCacheOptions opts ( 1024 , 2 , false , 0.5 , nullptr , kDefaultToAdaptiveMutex ,
LRUCacheOptions opts ( 1024 /* capacity */ , 2 /* num_shard_bits */ ,
false /* strict_capacity_limit */ ,
0.5 /* high_pri_pool_ratio */ ,
nullptr /* memory_allocator */ , kDefaultToAdaptiveMutex ,
kDontChargeCacheMetadata ) ;
std : : shared_ptr < TestSecondaryCache > secondary_cache =
std : : make_shared < TestSecondaryCache > ( 32 * 1024 ) ;
@ -1433,7 +1623,10 @@ TEST_F(LRUCacheSecondaryCacheTest, BasicWaitAllTest) {
// a sync point callback in TestSecondaryCache::Lookup. We then control the
// lookup result by setting the ResultMap.
TEST_F ( DBSecondaryCacheTest , TestSecondaryCacheMultiGet ) {
LRUCacheOptions opts ( 1 < < 20 , 0 , false , 0.5 , nullptr , kDefaultToAdaptiveMutex ,
LRUCacheOptions opts ( 1 < < 20 /* capacity */ , 0 /* num_shard_bits */ ,
false /* strict_capacity_limit */ ,
0.5 /* high_pri_pool_ratio */ ,
nullptr /* memory_allocator */ , kDefaultToAdaptiveMutex ,
kDontChargeCacheMetadata ) ;
std : : shared_ptr < TestSecondaryCache > secondary_cache (
new TestSecondaryCache ( 2048 * 1024 ) ) ;
@ -1516,15 +1709,16 @@ class LRUCacheWithStat : public LRUCache {
public :
LRUCacheWithStat (
size_t _capacity , int _num_shard_bits , bool _strict_capacity_limit ,
double _high_pri_pool_ratio ,
double _high_pri_pool_ratio , double _low_pri_pool_ratio ,
std : : shared_ptr < MemoryAllocator > _memory_allocator = nullptr ,
bool _use_adaptive_mutex = kDefaultToAdaptiveMutex ,
CacheMetadataChargePolicy _metadata_charge_policy =
kDontChargeCacheMetadata ,
const std : : shared_ptr < SecondaryCache > & _secondary_cache = nullptr )
: LRUCache ( _capacity , _num_shard_bits , _strict_capacity_limit ,
_high_pri_pool_ratio , _memory_allocator , _use_adaptive_mutex ,
_metadata_charge_policy , _secondary_cache ) {
_high_pri_pool_ratio , _low_pri_pool_ratio , _memory_allocator ,
_use_adaptive_mutex , _metadata_charge_policy ,
_secondary_cache ) {
insert_count_ = 0 ;
lookup_count_ = 0 ;
}
@ -1567,13 +1761,17 @@ class LRUCacheWithStat : public LRUCache {
# ifndef ROCKSDB_LITE
TEST_F ( DBSecondaryCacheTest , LRUCacheDumpLoadBasic ) {
LRUCacheOptions cache_opts ( 1024 * 1024 , 0 , false , 0.5 , nullptr ,
LRUCacheOptions cache_opts ( 1024 * 1024 /* capacity */ , 0 /* num_shard_bits */ ,
false /* strict_capacity_limit */ ,
0.5 /* high_pri_pool_ratio */ ,
nullptr /* memory_allocator */ ,
kDefaultToAdaptiveMutex , kDontChargeCacheMetadata ) ;
LRUCacheWithStat * tmp_cache = new LRUCacheWithStat (
cache_opts . capacity , cache_opts . num_shard_bits ,
cache_opts . strict_capacity_limit , cache_opts . high_pri_pool_ratio ,
cache_opts . memory_allocator , cache_opts . use_adaptive_mutex ,
cache_opts . metadata_charge_policy , cache_opts . secondary_cache ) ;
cache_opts . low_pri_pool_ratio , cache_opts . memory_allocator ,
cache_opts . use_adaptive_mutex , cache_opts . metadata_charge_policy ,
cache_opts . secondary_cache ) ;
std : : shared_ptr < Cache > cache ( tmp_cache ) ;
BlockBasedTableOptions table_options ;
table_options . block_cache = cache ;
@ -1644,8 +1842,9 @@ TEST_F(DBSecondaryCacheTest, LRUCacheDumpLoadBasic) {
tmp_cache = new LRUCacheWithStat (
cache_opts . capacity , cache_opts . num_shard_bits ,
cache_opts . strict_capacity_limit , cache_opts . high_pri_pool_ratio ,
cache_opts . memory_allocator , cache_opts . use_adaptive_mutex ,
cache_opts . metadata_charge_policy , cache_opts . secondary_cache ) ;
cache_opts . low_pri_pool_ratio , cache_opts . memory_allocator ,
cache_opts . use_adaptive_mutex , cache_opts . metadata_charge_policy ,
cache_opts . secondary_cache ) ;
std : : shared_ptr < Cache > cache_new ( tmp_cache ) ;
table_options . block_cache = cache_new ;
table_options . block_size = 4 * 1024 ;
@ -1702,13 +1901,17 @@ TEST_F(DBSecondaryCacheTest, LRUCacheDumpLoadBasic) {
}
TEST_F ( DBSecondaryCacheTest , LRUCacheDumpLoadWithFilter ) {
LRUCacheOptions cache_opts ( 1024 * 1024 , 0 , false , 0.5 , nullptr ,
LRUCacheOptions cache_opts ( 1024 * 1024 /* capacity */ , 0 /* num_shard_bits */ ,
false /* strict_capacity_limit */ ,
0.5 /* high_pri_pool_ratio */ ,
nullptr /* memory_allocator */ ,
kDefaultToAdaptiveMutex , kDontChargeCacheMetadata ) ;
LRUCacheWithStat * tmp_cache = new LRUCacheWithStat (
cache_opts . capacity , cache_opts . num_shard_bits ,
cache_opts . strict_capacity_limit , cache_opts . high_pri_pool_ratio ,
cache_opts . memory_allocator , cache_opts . use_adaptive_mutex ,
cache_opts . metadata_charge_policy , cache_opts . secondary_cache ) ;
cache_opts . low_pri_pool_ratio , cache_opts . memory_allocator ,
cache_opts . use_adaptive_mutex , cache_opts . metadata_charge_policy ,
cache_opts . secondary_cache ) ;
std : : shared_ptr < Cache > cache ( tmp_cache ) ;
BlockBasedTableOptions table_options ;
table_options . block_cache = cache ;
@ -1806,8 +2009,9 @@ TEST_F(DBSecondaryCacheTest, LRUCacheDumpLoadWithFilter) {
tmp_cache = new LRUCacheWithStat (
cache_opts . capacity , cache_opts . num_shard_bits ,
cache_opts . strict_capacity_limit , cache_opts . high_pri_pool_ratio ,
cache_opts . memory_allocator , cache_opts . use_adaptive_mutex ,
cache_opts . metadata_charge_policy , cache_opts . secondary_cache ) ;
cache_opts . low_pri_pool_ratio , cache_opts . memory_allocator ,
cache_opts . use_adaptive_mutex , cache_opts . metadata_charge_policy ,
cache_opts . secondary_cache ) ;
std : : shared_ptr < Cache > cache_new ( tmp_cache ) ;
table_options . block_cache = cache_new ;
table_options . block_size = 4 * 1024 ;
@ -1873,8 +2077,11 @@ TEST_F(DBSecondaryCacheTest, LRUCacheDumpLoadWithFilter) {
// Test the option not to use the secondary cache in a certain DB.
TEST_F ( DBSecondaryCacheTest , TestSecondaryCacheOptionBasic ) {
LRUCacheOptions opts ( 4 * 1024 , 0 , false , 0.5 , nullptr ,
kDefaultToAdaptiveMutex , kDontChargeCacheMetadata ) ;
LRUCacheOptions opts ( 4 * 1024 /* capacity */ , 0 /* num_shard_bits */ ,
false /* strict_capacity_limit */ ,
0.5 /* high_pri_pool_ratio */ ,
nullptr /* memory_allocator */ , kDefaultToAdaptiveMutex ,
kDontChargeCacheMetadata ) ;
std : : shared_ptr < TestSecondaryCache > secondary_cache (
new TestSecondaryCache ( 2048 * 1024 ) ) ;
opts . secondary_cache = secondary_cache ;
@ -1965,8 +2172,11 @@ TEST_F(DBSecondaryCacheTest, TestSecondaryCacheOptionBasic) {
// with new options, which set the lowest_used_cache_tier to
// kNonVolatileBlockTier. So secondary cache will be used.
TEST_F ( DBSecondaryCacheTest , TestSecondaryCacheOptionChange ) {
LRUCacheOptions opts ( 4 * 1024 , 0 , false , 0.5 , nullptr ,
kDefaultToAdaptiveMutex , kDontChargeCacheMetadata ) ;
LRUCacheOptions opts ( 4 * 1024 /* capacity */ , 0 /* num_shard_bits */ ,
false /* strict_capacity_limit */ ,
0.5 /* high_pri_pool_ratio */ ,
nullptr /* memory_allocator */ , kDefaultToAdaptiveMutex ,
kDontChargeCacheMetadata ) ;
std : : shared_ptr < TestSecondaryCache > secondary_cache (
new TestSecondaryCache ( 2048 * 1024 ) ) ;
opts . secondary_cache = secondary_cache ;
@ -2057,8 +2267,11 @@ TEST_F(DBSecondaryCacheTest, TestSecondaryCacheOptionChange) {
// Two DB test. We create 2 DBs sharing the same block cache and secondary
// cache. We diable the secondary cache option for DB2.
TEST_F ( DBSecondaryCacheTest , TestSecondaryCacheOptionTwoDB ) {
LRUCacheOptions opts ( 4 * 1024 , 0 , false , 0.5 , nullptr ,
kDefaultToAdaptiveMutex , kDontChargeCacheMetadata ) ;
LRUCacheOptions opts ( 4 * 1024 /* capacity */ , 0 /* num_shard_bits */ ,
false /* strict_capacity_limit */ ,
0.5 /* high_pri_pool_ratio */ ,
nullptr /* memory_allocator */ , kDefaultToAdaptiveMutex ,
kDontChargeCacheMetadata ) ;
std : : shared_ptr < TestSecondaryCache > secondary_cache (
new TestSecondaryCache ( 2048 * 1024 ) ) ;
opts . secondary_cache = secondary_cache ;