@@ -434,6 +434,18 @@ where
434434 } )
435435 . sum ( )
436436 }
437+
438+ /// Returns the estimated total number of replicas across all role groups.
439+ ///
440+ /// Unlike [`Self::fixed_replica_count`], this always returns a value: a role group with an unset
441+ /// (i.e. [`None`]) replica count is assumed to run a single replica. Use this when a best-effort
442+ /// estimate is needed even though the exact number of replicas is not hard-coded.
443+ pub fn estimated_replica_count ( & self ) -> u32 {
444+ self . role_groups
445+ . values ( )
446+ . map ( |rg| u32:: from ( rg. replicas . unwrap_or ( 1 ) ) )
447+ . sum ( )
448+ }
437449}
438450
439451impl < Config , ConfigOverrides , RoleConfig >
@@ -689,44 +701,49 @@ mod tests {
689701 }
690702
691703 #[ test]
692- fn fixed_replica_count_sums_all_set_replicas ( ) {
704+ fn replica_counts_with_all_replicas_set ( ) {
693705 let role = construct_role_with_replicas ( [ Some ( 3 ) , Some ( 2 ) , Some ( 5 ) ] ) ;
694706
695707 assert_eq ! ( role. fixed_replica_count( false ) , Some ( 10 ) ) ;
696708 assert_eq ! ( role. fixed_replica_count( true ) , Some ( 10 ) ) ;
709+ assert_eq ! ( role. estimated_replica_count( ) , 10 ) ;
697710 }
698711
699712 #[ test]
700- fn fixed_replica_count_is_none_if_any_replica_is_unset ( ) {
713+ fn replica_counts_with_one_replica_unset ( ) {
701714 let role = construct_role_with_replicas ( [ Some ( 3 ) , None , Some ( 2 ) ] ) ;
702715
703716 assert_eq ! ( role. fixed_replica_count( false ) , None ) ;
704717 assert_eq ! ( role. fixed_replica_count( true ) , None ) ;
718+ assert_eq ! ( role. estimated_replica_count( ) , 6 ) ;
705719 }
706720
707721 #[ test]
708- fn fixed_replica_count_treats_zero_according_to_flag ( ) {
722+ fn replica_counts_with_a_zero_replica ( ) {
709723 let role = construct_role_with_replicas ( [ Some ( 3 ) , Some ( 0 ) ] ) ;
710724
711725 assert_eq ! ( role. fixed_replica_count( false ) , Some ( 3 ) ) ;
712726 // With treat_zero_as_none the zero turns the whole count into None.
713727 assert_eq ! ( role. fixed_replica_count( true ) , None ) ;
728+ assert_eq ! ( role. estimated_replica_count( ) , 3 ) ;
714729 }
715730
716731 #[ test]
717- fn fixed_replica_count_of_single_zero_role_group ( ) {
732+ fn replica_counts_with_a_single_zero_role_group ( ) {
718733 let role = construct_role_with_replicas ( [ Some ( 0 ) ] ) ;
719734
720735 assert_eq ! ( role. fixed_replica_count( false ) , Some ( 0 ) ) ;
721736 assert_eq ! ( role. fixed_replica_count( true ) , None ) ;
737+ assert_eq ! ( role. estimated_replica_count( ) , 0 ) ;
722738 }
723739
724740 #[ test]
725- fn fixed_replica_count_of_role_without_role_groups_is_zero ( ) {
741+ fn replica_counts_without_role_groups ( ) {
726742 let role = construct_role_with_replicas ( vec ! [ ] ) ;
727743
728744 assert_eq ! ( role. fixed_replica_count( false ) , Some ( 0 ) ) ;
729745 assert_eq ! ( role. fixed_replica_count( true ) , None ) ;
746+ assert_eq ! ( role. estimated_replica_count( ) , 0 ) ;
730747 }
731748
732749 /// Builds a [`Role`] with one role group per passed `replicas` entry, so tests only need to
0 commit comments