@@ -38,6 +38,7 @@ use crate::builtins::IntDictScheme;
3838use crate :: ctx:: CompressorContext ;
3939use crate :: estimate:: CompressionEstimate ;
4040use crate :: estimate:: DeferredEstimate ;
41+ use crate :: estimate:: EstimateFn ;
4142use crate :: estimate:: EstimateVerdict ;
4243use crate :: estimate:: estimate_compression_ratio_with_sampling;
4344use crate :: estimate:: is_better_ratio;
@@ -72,13 +73,15 @@ const TARGET_CASCADE: &str = "vortex_compressor::cascade";
7273/// Emits a structured `scheme.evaluated` trace event on [`TARGET_SELECT`] for one scheme's
7374/// initial estimation verdict.
7475///
75- /// For `Ratio(r)` the numeric estimate is recorded directly. For `Sample` and `Estimate`
76- /// the ratio is not yet known at this point; a follow-up `scheme.evaluated.resolved` event
77- /// is emitted by the caller after the deferred computation finishes.
76+ /// For [`CompressionEstimate::Verdict(EstimateVerdict::Ratio)`] the numeric estimate is recorded
77+ /// directly as a typed `f64`, so JSON subscribers get a proper number. For all other variants the
78+ /// `ratio` field is omitted entirely. The `kind` field distinguishes the variants. For deferred
79+ /// estimates a follow-up `scheme.evaluated.resolved` event is emitted by the caller once the
80+ /// deferred computation finishes.
7881///
79- /// Defined as a standalone helper (rather than inlined) because the `match` expression that
80- /// extracts `kind` and the optional `ratio` field is the only repetition worth factoring out
81- /// of [`CascadingCompressor::choose_best_scheme`].
82+ /// Defined as a standalone helper (rather than inlined) because the `match` expression
83+ /// that extracts `kind` is the only repetition worth factoring out of
84+ /// [`CascadingCompressor::choose_best_scheme`].
8285fn emit_scheme_evaluated ( scheme : & ' static dyn Scheme , estimate : & CompressionEstimate ) {
8386 let kind: & ' static str = match estimate {
8487 CompressionEstimate :: Verdict ( EstimateVerdict :: Skip ) => "Skip" ,
@@ -542,7 +545,6 @@ impl CascadingCompressor {
542545 /// registration order (earlier in the list wins).
543546 ///
544547 /// [`expected_compression_ratio`]: Scheme::expected_compression_ratio
545- #[ allow( clippy:: cognitive_complexity, reason = "tracing sometimes enabled" ) ]
546548 fn choose_best_scheme (
547549 & self ,
548550 schemes : & [ & ' static dyn Scheme ] ,
@@ -571,53 +573,16 @@ impl CascadingCompressor {
571573 }
572574 }
573575 CompressionEstimate :: Deferred ( DeferredEstimate :: Sample ) => {
574- let sample_ratio = estimate_compression_ratio_with_sampling (
575- scheme,
576- self ,
577- data. array ( ) ,
578- ctx. clone ( ) ,
579- ) ?;
580-
581- tracing:: trace!(
582- target: TARGET_SELECT ,
583- scheme = %scheme. id( ) ,
584- kind = "Sample" ,
585- ratio = sample_ratio,
586- "scheme.evaluated.resolved" ,
587- ) ;
588-
589- if is_better_ratio ( sample_ratio, & best) {
590- best = Some ( ( scheme, sample_ratio) ) ;
591- }
576+ self . check_sample_scheme ( data, & ctx, & mut best, scheme) ?;
592577 }
593578 CompressionEstimate :: Deferred ( DeferredEstimate :: Callback ( estimate_callback) ) => {
594- let verdict = estimate_callback ( self , data, ctx. clone ( ) ) ?;
595- let resolved_kind = match verdict {
596- EstimateVerdict :: Skip => "Skip" ,
597- EstimateVerdict :: AlwaysUse => "AlwaysUse" ,
598- EstimateVerdict :: Ratio ( _) => "Ratio" ,
599- } ;
600- if let EstimateVerdict :: Ratio ( ratio) = verdict {
601- tracing:: trace!(
602- target: TARGET_SELECT ,
603- scheme = %scheme. id( ) ,
604- kind = "Estimate" ,
605- resolved_kind,
606- ratio,
607- "scheme.evaluated.resolved" ,
608- ) ;
609- } else {
610- tracing:: trace!(
611- target: TARGET_SELECT ,
612- scheme = %scheme. id( ) ,
613- kind = "Estimate" ,
614- resolved_kind,
615- "scheme.evaluated.resolved" ,
616- ) ;
617- }
618- if let Some ( winner_estimate) =
619- Self :: check_and_update_estimate_verdict ( & mut best, scheme, verdict)
620- {
579+ if let Some ( winner_estimate) = self . check_estimate_callback (
580+ data,
581+ & ctx,
582+ & mut best,
583+ scheme,
584+ estimate_callback,
585+ ) ? {
621586 return Ok ( Some ( ( scheme, winner_estimate) ) ) ;
622587 }
623588 }
@@ -627,6 +592,71 @@ impl CascadingCompressor {
627592 Ok ( best. map ( |( scheme, ratio) | ( scheme, WinnerEstimate :: Ratio ( ratio) ) ) )
628593 }
629594
595+ /// Helper function for sampling a scheme to get an estimated compression ratio.
596+ fn check_sample_scheme (
597+ & self ,
598+ data : & mut ArrayAndStats ,
599+ ctx : & CompressorContext ,
600+ best : & mut Option < ( & ' static dyn Scheme , f64 ) > ,
601+ scheme : & ' static dyn Scheme ,
602+ ) -> VortexResult < ( ) > {
603+ let sample_ratio =
604+ estimate_compression_ratio_with_sampling ( scheme, self , data. array ( ) , ctx. clone ( ) ) ?;
605+
606+ tracing:: trace!(
607+ target: TARGET_SELECT ,
608+ scheme = %scheme. id( ) ,
609+ kind = "Sample" ,
610+ ratio = sample_ratio,
611+ "scheme.evaluated.resolved" ,
612+ ) ;
613+
614+ if is_better_ratio ( sample_ratio, & * best) {
615+ * best = Some ( ( scheme, sample_ratio) ) ;
616+ }
617+
618+ Ok ( ( ) )
619+ }
620+
621+ /// Helper function for running a custom compression ratio estimation callback for a scheme.
622+ fn check_estimate_callback (
623+ & self ,
624+ data : & mut ArrayAndStats ,
625+ ctx : & CompressorContext ,
626+ best : & mut Option < ( & ' static dyn Scheme , f64 ) > ,
627+ scheme : & ' static dyn Scheme ,
628+ estimate_callback : Box < EstimateFn > ,
629+ ) -> VortexResult < Option < WinnerEstimate > > {
630+ let verdict = estimate_callback ( self , data, ctx. clone ( ) ) ?;
631+ let resolved_kind = match verdict {
632+ EstimateVerdict :: Skip => "Skip" ,
633+ EstimateVerdict :: AlwaysUse => "AlwaysUse" ,
634+ EstimateVerdict :: Ratio ( _) => "Ratio" ,
635+ } ;
636+ if let EstimateVerdict :: Ratio ( ratio) = verdict {
637+ tracing:: trace!(
638+ target: TARGET_SELECT ,
639+ scheme = %scheme. id( ) ,
640+ kind = "Estimate" ,
641+ resolved_kind,
642+ ratio,
643+ "scheme.evaluated.resolved" ,
644+ ) ;
645+ } else {
646+ tracing:: trace!(
647+ target: TARGET_SELECT ,
648+ scheme = %scheme. id( ) ,
649+ kind = "Estimate" ,
650+ resolved_kind,
651+ "scheme.evaluated.resolved" ,
652+ ) ;
653+ }
654+
655+ Ok ( Self :: check_and_update_estimate_verdict (
656+ best, scheme, verdict,
657+ ) )
658+ }
659+
630660 /// Updates `best` from a terminal estimate verdict.
631661 fn check_and_update_estimate_verdict (
632662 best : & mut Option < ( & ' static dyn Scheme , f64 ) > ,
0 commit comments