From 3254e79efde48d0b5ee19814aa0a7f5141260385 Mon Sep 17 00:00:00 2001 From: Chris Date: Sat, 24 Oct 2026 01:49:07 +0900 Subject: [PATCH] perf(scanner): transfer owned caches without redundant clones (#8849) --- crates/scanner/src/scanner_folder.rs | 2 +- crates/scanner/src/scanner_io/io_cache.rs | 47 ++++------------------- crates/scanner/src/scanner_io/io_cycle.rs | 3 +- 3 files changed, 11 insertions(+), 41 deletions(-) diff --git a/crates/scanner/src/scanner_folder.rs b/crates/scanner/src/scanner_folder.rs index e9fc06af9..9580c0ca1 100644 --- a/crates/scanner/src/scanner_folder.rs +++ b/crates/scanner/src/scanner_folder.rs @@ -1607,7 +1607,7 @@ impl FolderScanner { && let Some(ref updates) = self.updates { // Try to send without blocking - if let Err(e) = updates.send(flat.clone()).await { + if let Err(e) = updates.send(flat).await { error!( target: "rustfs::scanner::folder", event = EVENT_SCANNER_FOLDER_STATE, diff --git a/crates/scanner/src/scanner_io/io_cache.rs b/crates/scanner/src/scanner_io/io_cache.rs index acd6bd625..f85907713 100644 --- a/crates/scanner/src/scanner_io/io_cache.rs +++ b/crates/scanner/src/scanner_io/io_cache.rs @@ -1289,7 +1289,6 @@ impl ScannerIOCache for SetDisks { "Scanner disk bucket cache ready" ); - let before = cache.info.last_update; let (checkpoint_tx, mut checkpoint_rx) = mpsc::channel::(1); let scan_ctx = ctx_clone.child_token(); @@ -1297,7 +1296,7 @@ impl ScannerIOCache for SetDisks { scan_ctx.clone(), budget_clone.clone(), set_disk_inventory_clone.as_ref().clone(), - cache.clone(), + cache, None, ScannerDiskScanOptions { scan_mode, @@ -1453,40 +1452,11 @@ impl ScannerIOCache for SetDisks { ); } - if !cache_guard.is_lock_lost() - && let (Some(last_update), Some(before_update)) = (cache.info.last_update, before) - && last_update > before_update - { - let done_save = Metrics::time(Metric::SaveUsage); - if let Err(e) = cache - .save_with_revisions_for_epoch( - store_clone_clone.clone(), - cache_name.as_str(), - &revisions, - expected_publication_epoch_clone, - ) - .await - { - error!( - target: "rustfs::scanner::io", - event = EVENT_SCANNER_CACHE_PERSIST_STATE, - component = LOG_COMPONENT_SCANNER, - subsystem = LOG_SUBSYSTEM_IO, - bucket = %bucket.name, - cache_name = %cache_name, - state = "save_failed", - error = %e, - "Scanner bucket cache save failed" - ); - } - done_save(); - } - continue; } }; - let partial = match scan_outcome { + let (cache, partial) = match scan_outcome { ScannerDiskScanOutcome::Complete(mut completed_cache) => { // The sweep finished under its coverage plan; the // complete cache is current under the reuse plan, @@ -1495,10 +1465,9 @@ impl ScannerIOCache for SetDisks { if completed_cache.info.snapshot_complete { completed_cache.info.scan_plan_digest = Some(bucket_scan_plan_digest); } - cache = completed_cache; - None + (completed_cache, false) } - ScannerDiskScanOutcome::Partial(partial_cache) => Some((partial_cache, &partial_dirty_buckets_clone)), + ScannerDiskScanOutcome::Partial(partial_cache) => (partial_cache, true), ScannerDiskScanOutcome::NamespaceNotFound(_) => { if requeue_bucket_work(&bucket_tx_clone, &bucket, &mut work_guard).await { increment_disk_bucket_scans_queued( @@ -1521,13 +1490,13 @@ impl ScannerIOCache for SetDisks { break; } }; - if let Some((partial_cache, failure_buckets)) = partial { - record_partial_dirty_bucket(failure_buckets, &bucket.name).await; + if partial { + record_partial_dirty_bucket(&partial_dirty_buckets_clone, &bucket.name).await; let done_save = Metrics::time(Metric::SaveUsage); let partial_saved = if cache_guard.is_lock_lost() { false } else { - match partial_cache + match cache .save_with_revisions_for_epoch( store_clone_clone.clone(), cache_name.as_str(), @@ -1558,7 +1527,7 @@ impl ScannerIOCache for SetDisks { record_failed_dirty_bucket(&failed_dirty_buckets_clone, &bucket.name).await; } if partial_saved { - log_saved_partial_bucket_cache(&partial_cache, &cache_name); + log_saved_partial_bucket_cache(&cache, &cache_name); } continue; diff --git a/crates/scanner/src/scanner_io/io_cycle.rs b/crates/scanner/src/scanner_io/io_cycle.rs index 14876ee9d..938a77573 100644 --- a/crates/scanner/src/scanner_io/io_cycle.rs +++ b/crates/scanner/src/scanner_io/io_cycle.rs @@ -779,7 +779,8 @@ where let first_err = first_err_mutex.lock().await.take(); let has_set_failure = first_err.is_some(); - let results = results_mutex.lock().await.clone(); + // Every collector has joined; transfer the caches without duplicating their trees. + let results = std::mem::take(&mut *results_mutex.lock().await); let completed_all_sets = bucket_plan_complete && scanner_results_form_complete_snapshot(&results, &expected_sources); let result = finalize_nsscanner_result(&results, first_err); let failed_buckets = bucket_failures.hard.lock().await.clone();