deps/rocksdb/table/table_test.cc
// Block cache can contain raw data blocks as well as general objects. If an
// object depends on the table to be live, it then must be destructed before the
// table is closed. This test makes sure that the only items remains in the
// cache after the table is closed are raw data blocks.
Block cache can contain raw data blocks as well as general objects. If an
object depends on the table to be live, it then must be destructed before the
table is closed. This test makes sure that the only items remains in the
cache after the table is closed are raw data blocks.
Block cache can contain raw data blocks as well as general objects . If an object depends on the table to be live it then must be destructed before the table is closed . This test makes sure that the only items remains in the cache after the table is closed are raw data blocks .
TEST_P(BlockBasedTableTest, NoObjectInCacheAfterTableClose) {
  std::vector<CompressionType> compression_types{kNoCompression};
#ifdef ZLIB
  compression_types.push_back(kZlibCompression);
#endif  
#if LZ4_VERSION_NUMBER >= 10400
  compression_types.push_back(kLZ4Compression);
  compression_types.push_back(kLZ4HCCompression);
#endif  
#if ZSTD_VERSION_NUMBER >= 500
  compression_types.push_back(kZSTD);
#endif  
  for (int level: {-1, 0, 1, 10}) {
    for (auto index_type :
        {BlockBasedTableOptions::IndexType::kBinarySearch,
        BlockBasedTableOptions::IndexType::kTwoLevelIndexSearch}) {
      for (bool block_based_filter : {true, false}) {
        for (bool partition_filter : {true, false}) {
          if (partition_filter &&
              (block_based_filter ||
               index_type !=
               BlockBasedTableOptions::IndexType::kTwoLevelIndexSearch)) {
            continue;
          }
          for (bool index_and_filter_in_cache : {true, false}) {
            for (bool pin_l0 : {true, false}) {
              for (bool pin_top_level : {true, false}) {
                if (pin_l0 && !index_and_filter_in_cache) {
                  continue;
                }
                for (auto compression_type : compression_types) {
                  for (uint32_t max_dict_bytes : {0, 1 << 14}) {
                    if (compression_type == kNoCompression && max_dict_bytes)
                      continue;
                    Options opt;
                    std::unique_ptr<InternalKeyComparator> ikc;
                    ikc.reset(new test::PlainInternalKeyComparator(
                      opt.comparator));
                    opt.compression = compression_type;
                    opt.compression_opts.max_dict_bytes = max_dict_bytes;
                    BlockBasedTableOptions table_options =
                      GetBlockBasedTableOptions();
                    table_options.block_size = 1024;
                    table_options.index_type = index_type;
                    table_options.pin_l0_filter_and_index_blocks_in_cache =
                      pin_l0;
                    table_options.pin_top_level_index_and_filter =
                      pin_top_level;
                    table_options.partition_filters = partition_filter;
                    table_options.cache_index_and_filter_blocks =
                      index_and_filter_in_cache;
                    table_options.block_cache = std::make_shared<MockCache>(
                      16 * 1024 * 1024, 4, false, 0.0);
                    table_options.filter_policy.reset(
                      rocksdb::NewBloomFilterPolicy(10, block_based_filter));
                    opt.table_factory.reset(NewBlockBasedTableFactory(
                      table_options));
                    bool convert_to_internal_key = false;
                    TableConstructor c(BytewiseComparator(),
                      convert_to_internal_key, level);
                    std::string user_key = "k01";
                    std::string key =
                      InternalKey(user_key, 0, kTypeValue).Encode().ToString();
                    c.Add(key, "hello");
                    std::vector<std::string> keys;
                    stl_wrappers::KVMap kvmap;
                    const ImmutableCFOptions ioptions(opt);
                    const MutableCFOptions moptions(opt);
                    c.Finish(opt, ioptions, moptions, table_options, *ikc,
                      &keys, &kvmap);
                    auto table_reader =
                      dynamic_cast<BlockBasedTable*>(c.GetTableReader());
                    PinnableSlice value;
                    GetContext get_context(opt.comparator, nullptr, nullptr,
                      nullptr, GetContext::kNotFound, user_key, &value,
                      nullptr, nullptr, nullptr, nullptr);
                    InternalKey ikey(user_key, 0, kTypeValue);
                    auto s = table_reader->Get(ReadOptions(), key, &get_context,
                      moptions.prefix_extractor.get());
                    ASSERT_EQ(get_context.State(), GetContext::kFound);
                    ASSERT_STREQ(value.data(), "hello");
                    c.ResetTableReader();
                    auto usage = table_options.block_cache->GetUsage();
                    auto pinned_usage =
                      table_options.block_cache->GetPinnedUsage();
                    ASSERT_EQ(usage, MockCache::marked_size_);
                    ASSERT_GT(pinned_usage, 0);
                    value.Reset();
                    pinned_usage = table_options.block_cache->GetPinnedUsage();
                    ASSERT_EQ(pinned_usage, 0);
                  }
                }
              }
            }
          }
        }
      }
    }
  } 
}
TEST_P ( BlockBasedTableTest , NoObjectInCacheAfterTableClose ) { std :: vector < CompressionType > compression_types { kNoCompression } ; #ifdef ZLIB compression_types . push_back ( kZlibCompression ) ; #endif #if LZ4_VERSION_NUMBER >= 10400 compression_types . push_back ( kLZ4Compression ) ; compression_types . push_back ( kLZ4HCCompression ) ; #endif #if ZSTD_VERSION_NUMBER >= 500 compression_types . push_back ( kZSTD ) ; #endif for ( int level : { -1 , 0 , 1 , 10 } ) { for ( auto index_type : { BlockBasedTableOptions :: IndexType :: kBinarySearch , BlockBasedTableOptions :: IndexType :: kTwoLevelIndexSearch } ) { for ( bool block_based_filter : { true , false } ) { for ( bool partition_filter : { true , false } ) { if ( partition_filter && ( block_based_filter || index_type != BlockBasedTableOptions :: IndexType :: kTwoLevelIndexSearch ) ) { continue ; } for ( bool index_and_filter_in_cache : { true , false } ) { for ( bool pin_l0 : { true , false } ) { for ( bool pin_top_level : { true , false } ) { if ( pin_l0 && ! index_and_filter_in_cache ) { continue ; } for ( auto compression_type : compression_types ) { for ( uint32_t max_dict_bytes : { 0 , 1 << 14 } ) { if ( compression_type == kNoCompression && max_dict_bytes ) continue ; Options opt ; std :: unique_ptr < InternalKeyComparator > ikc ; ikc . reset ( new test :: PlainInternalKeyComparator ( opt . comparator ) ) ; opt . compression = compression_type ; opt . compression_opts . max_dict_bytes = max_dict_bytes ; BlockBasedTableOptions table_options = GetBlockBasedTableOptions ( ) ; table_options . block_size = 1024 ; table_options . index_type = index_type ; table_options . pin_l0_filter_and_index_blocks_in_cache = pin_l0 ; table_options . pin_top_level_index_and_filter = pin_top_level ; table_options . partition_filters = partition_filter ; table_options . cache_index_and_filter_blocks = index_and_filter_in_cache ; table_options . block_cache = std :: make_shared < MockCache > ( 16 * 1024 * 1024 , 4 , false , 0.0 ) ; table_options . filter_policy . reset ( rocksdb :: NewBloomFilterPolicy ( 10 , block_based_filter ) ) ; opt . table_factory . reset ( NewBlockBasedTableFactory ( table_options ) ) ; bool convert_to_internal_key = false ; TableConstructor c ( BytewiseComparator ( ) , convert_to_internal_key , level ) ; std :: string user_key = " " ; std :: string key = InternalKey ( user_key , 0 , kTypeValue ) . Encode ( ) . ToString ( ) ; c . Add ( key , " " ) ; std :: vector < std :: string > keys ; stl_wrappers :: KVMap kvmap ; const ImmutableCFOptions ioptions ( opt ) ; const MutableCFOptions moptions ( opt ) ; c . Finish ( opt , ioptions , moptions , table_options , * ikc , & keys , & kvmap ) ; auto table_reader = dynamic_cast < BlockBasedTable * > ( c . GetTableReader ( ) ) ; PinnableSlice value ; GetContext get_context ( opt . comparator , nullptr , nullptr , nullptr , GetContext :: kNotFound , user_key , & value , nullptr , nullptr , nullptr , nullptr ) ; InternalKey ikey ( user_key , 0 , kTypeValue ) ; auto s = table_reader -> Get ( ReadOptions ( ) , key , & get_context , moptions . prefix_extractor . get ( ) ) ; ASSERT_EQ ( get_context . State ( ) , GetContext :: kFound ) ; ASSERT_STREQ ( value . data ( ) , " " ) ; c . ResetTableReader ( ) ; auto usage = table_options . block_cache -> GetUsage ( ) ; auto pinned_usage = table_options . block_cache -> GetPinnedUsage ( ) ; ASSERT_EQ ( usage , MockCache :: marked_size_ ) ; ASSERT_GT ( pinned_usage , 0 ) ; value . Reset ( ) ; pinned_usage = table_options . block_cache -> GetPinnedUsage ( ) ; ASSERT_EQ ( pinned_usage , 0 ) ; } } } } } } } } } }
Block cache can contain raw data blocks as well as general objects.
Block cache can contain raw data blocks as well as general objects .
// The following are the compression library versions supporting compression // dictionaries. See the test case CacheCompressionDict in the // DBBlockCacheTest suite. // ZLIB // LZ4_VERSION_NUMBER >= 10400 // ZSTD_VERSION_NUMBER >= 500 // Create a table // big enough so we don't ever lose cached values. // Doing a read to make index/filter loaded into the cache // Close the table // The only usage must be for marked data blocks // There must be some pinned data since PinnableSlice has // not released them yet // Release pinnable slice reousrces // level