@@ -498,6 +498,127 @@ TEST_F(BlockFileCacheTest, clear_retains_meta_directory_and_clears_meta_entries)
498498 }
499499}
500500
501+ TEST_F (BlockFileCacheTest, HandleAlreadyLoadedBlockUpdatesSizeAndTablet) {
502+ config::enable_evict_file_cache_in_advance = false ;
503+ if (fs::exists (cache_base_path)) {
504+ fs::remove_all (cache_base_path);
505+ }
506+ fs::create_directories (cache_base_path);
507+
508+ io::FileCacheSettings settings;
509+ settings.ttl_queue_size = 5000000 ;
510+ settings.ttl_queue_elements = 50000 ;
511+ settings.query_queue_size = 5000000 ;
512+ settings.query_queue_elements = 50000 ;
513+ settings.index_queue_size = 5000000 ;
514+ settings.index_queue_elements = 50000 ;
515+ settings.disposable_queue_size = 5000000 ;
516+ settings.disposable_queue_elements = 50000 ;
517+ settings.capacity = 20000000 ;
518+ settings.max_file_block_size = 100000 ;
519+ settings.max_query_cache_size = 30 ;
520+
521+ io::BlockFileCache cache (cache_base_path, settings);
522+ ASSERT_TRUE (cache.initialize ());
523+ for (int i = 0 ; i < 100 ; ++i) {
524+ if (cache.get_async_open_success ()) {
525+ break ;
526+ }
527+ std::this_thread::sleep_for (std::chrono::milliseconds (10 ));
528+ }
529+ ASSERT_TRUE (cache.get_async_open_success ());
530+
531+ io::CacheContext context;
532+ ReadStatistics rstats;
533+ context.stats = &rstats;
534+ context.cache_type = io::FileCacheType::NORMAL;
535+ context.query_id .hi = 11 ;
536+ context.query_id .lo = 12 ;
537+ context.tablet_id = 0 ;
538+ auto key = io::BlockFileCache::hash (" sync_cached_block_meta_key" );
539+
540+ constexpr size_t kOriginalSize = 100000 ;
541+ auto holder = cache.get_or_set (key, 0 , kOriginalSize , context);
542+ auto blocks = fromHolder (holder);
543+ ASSERT_EQ (blocks.size (), 1 );
544+ ASSERT_TRUE (blocks[0 ]->get_or_set_downloader () == io::FileBlock::get_caller_id ());
545+ download (blocks[0 ], kOriginalSize );
546+ blocks.clear ();
547+
548+ auto * fs_storage = dynamic_cast <FSFileCacheStorage*>(cache._storage .get ());
549+ ASSERT_NE (fs_storage, nullptr ) << " Expected FSFileCacheStorage but got different storage type" ;
550+
551+ constexpr size_t kNewSize = 2 * kOriginalSize ;
552+ constexpr int64_t kTabletId = 4242 ;
553+ bool handled = false ;
554+ {
555+ SCOPED_CACHE_LOCK (cache._mutex , (&cache));
556+ handled = fs_storage->handle_already_loaded_block (&cache, key, 0 , kNewSize , kTabletId ,
557+ cache_lock);
558+ }
559+
560+ ASSERT_TRUE (handled);
561+ auto & cell = cache._files [key][0 ];
562+ EXPECT_EQ (cell.file_block ->tablet_id (), kTabletId );
563+ EXPECT_EQ (cache._cur_cache_size , kNewSize );
564+ EXPECT_EQ (cache._normal_queue .get_capacity_unsafe (), kNewSize );
565+
566+ if (fs::exists (cache_base_path)) {
567+ fs::remove_all (cache_base_path);
568+ }
569+ }
570+
571+ TEST_F (BlockFileCacheTest, estimate_file_count_skips_removed_directory) {
572+ std::string test_dir = cache_base_path + " /estimate_file_count_removed_dir" ;
573+ if (fs::exists (test_dir)) {
574+ fs::remove_all (test_dir);
575+ }
576+ auto keep_dir = fs::path (test_dir) / " keep" ;
577+ auto remove_dir = fs::path (test_dir) / " remove" ;
578+ fs::create_directories (keep_dir);
579+ fs::create_directories (remove_dir);
580+
581+ auto keep_file = keep_dir / " data.bin" ;
582+ std::string one_mb (1024 * 1024 , ' d' );
583+ {
584+ std::ofstream ofs (keep_file, std::ios::binary);
585+ ASSERT_TRUE (ofs.good ());
586+ for (int i = 0 ; i < 3 ; ++i) {
587+ ofs.write (one_mb.data (), one_mb.size ());
588+ ASSERT_TRUE (ofs.good ());
589+ }
590+ }
591+
592+ FSFileCacheStorage storage;
593+ storage._cache_base_path = test_dir;
594+
595+ const std::string sync_point_name =
596+ " FSFileCacheStorage::estimate_file_count_from_statfs::OnDirectory" ;
597+ auto * sync_point = doris::SyncPoint::get_instance ();
598+ doris::SyncPoint::CallbackGuard guard (sync_point_name);
599+ sync_point->set_call_back (
600+ sync_point_name,
601+ [remove_dir](std::vector<std::any>&& args) {
602+ auto * path = doris::try_any_cast<std::filesystem::path*>(args[0 ]);
603+ if (*path == remove_dir) {
604+ fs::remove_all (remove_dir);
605+ }
606+ },
607+ &guard);
608+ sync_point->enable_processing ();
609+
610+ size_t estimated_files = storage.estimate_file_count_from_statfs ();
611+
612+ sync_point->disable_processing ();
613+
614+ ASSERT_EQ (3 , estimated_files);
615+ ASSERT_FALSE (fs::exists (remove_dir));
616+
617+ if (fs::exists (test_dir)) {
618+ fs::remove_all (test_dir);
619+ }
620+ }
621+
501622// TODO(zhengyu): check lazy load
502623// TODO(zhengyu): check version2 start
503624// TODO(zhengyu): check version2 version3 mixed start
0 commit comments