@@ -403,62 +403,6 @@ where
403403 }
404404}
405405
406- impl < Config , ConfigOverrides , RoleConfig , CommonConfig >
407- Role < Config , ConfigOverrides , RoleConfig , CommonConfig >
408- where
409- RoleConfig : Default + JsonSchema + Serialize ,
410- CommonConfig : Default + JsonSchema + Serialize ,
411- ConfigOverrides : Default + JsonSchema + Serialize ,
412- {
413- /// Returns [`Some<u32>`] in case the number of replicas is hard-coded to a certain value.
414- ///
415- /// This is the case when all `replicas` are set to [`Some<u16>`], in which case they are simply
416- /// summed.
417- ///
418- /// The argument `zero_replicas_counting` is a safety mechanism, which allows the caller to
419- /// decide if an explicit replica count of `0` should be treated as [`None`]. It also means that
420- /// [`None`] is returned in case no roleGroups are configured at all.
421- pub fn fixed_replica_count ( & self , zero_replicas_counting : ZeroReplicasCounting ) -> Option < u32 > {
422- // An empty role has no fixed replica count when zeros are treated as None.
423- if zero_replicas_counting == ZeroReplicasCounting :: TreatAsNone
424- && self . role_groups . is_empty ( )
425- {
426- return None ;
427- }
428-
429- self . role_groups
430- . values ( )
431- . map ( |rg| match rg. replicas {
432- None => None ,
433- Some ( 0 ) if zero_replicas_counting == ZeroReplicasCounting :: TreatAsNone => None ,
434- // The individual replicas are [`u16`]s, so a [`u32`] sum has plenty of space.
435- Some ( replicas) => Some ( u32:: from ( replicas) ) ,
436- } )
437- . sum ( )
438- }
439-
440- /// Returns the estimated total number of replicas across all role groups.
441- ///
442- /// Unlike [`Self::fixed_replica_count`], this always returns a value: a role group with an unset
443- /// (i.e. [`None`]) replica count is assumed to run a single replica. Use this when a best-effort
444- /// estimate is needed even though the exact number of replicas is not hard-coded.
445- pub fn estimated_replica_count ( & self ) -> u32 {
446- self . role_groups
447- . values ( )
448- . map ( |rg| u32:: from ( rg. replicas . unwrap_or ( 1 ) ) )
449- . sum ( )
450- }
451- }
452-
453- /// How explicit zero (`0`) replicas on a role group should be counted
454- #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
455- pub enum ZeroReplicasCounting {
456- /// Treat them as what they are: `Some(0)`.
457- TreatAsZero ,
458- /// Treat them as if the user configured [`None`].
459- TreatAsNone ,
460- }
461-
462406impl < Config , ConfigOverrides , RoleConfig >
463407 Role < Config , ConfigOverrides , RoleConfig , JavaCommonConfig >
464408where
@@ -594,6 +538,56 @@ impl<K: Resource> Display for RoleGroupRef<K> {
594538 }
595539}
596540
541+ /// Returns [`Some<u32>`] in case the number of replicas is hard-coded to a certain value.
542+ ///
543+ /// This is the case when all `replicas` are set to [`Some<u16>`], in which case they are simply
544+ /// summed.
545+ ///
546+ /// The argument `zero_replicas_counting` is a safety mechanism, which allows the caller to
547+ /// decide if an explicit replica count of `0` should be treated as [`None`]. It also means that
548+ /// [`None`] is returned in case no roleGroups are configured at all.
549+ pub fn fixed_replica_count < I : IntoIterator < Item = Option < u16 > > > (
550+ replicas : I ,
551+ zero_replicas_counting : ZeroReplicasCounting ,
552+ ) -> Option < u32 > {
553+ let mut replicas = replicas. into_iter ( ) . peekable ( ) ;
554+
555+ // An empty role has no fixed replica count when zeros are treated as None.
556+ if zero_replicas_counting == ZeroReplicasCounting :: TreatAsNone && replicas. peek ( ) . is_none ( ) {
557+ return None ;
558+ }
559+
560+ replicas
561+ . map ( |replicas| match replicas {
562+ None => None ,
563+ Some ( 0 ) if zero_replicas_counting == ZeroReplicasCounting :: TreatAsNone => None ,
564+ // The individual replicas are [`u16`]s, so a [`u32`] sum has plenty of space.
565+ Some ( replicas) => Some ( u32:: from ( replicas) ) ,
566+ } )
567+ . sum ( )
568+ }
569+
570+ /// Returns the estimated total number of replicas across all role groups.
571+ ///
572+ /// Unlike [`Self::fixed_replica_count`], this always returns a value: a role group with an unset
573+ /// (i.e. [`None`]) replica count is assumed to run a single replica. Use this when a best-effort
574+ /// estimate is needed even though the exact number of replicas is not hard-coded.
575+ pub fn estimated_replica_count < I : IntoIterator < Item = Option < u16 > > > ( replicas : I ) -> u32 {
576+ replicas
577+ . into_iter ( )
578+ . map ( |replicas| u32:: from ( replicas. unwrap_or ( 1 ) ) )
579+ . sum ( )
580+ }
581+
582+ /// How explicit zero (`0`) replicas on a role group should be counted
583+ #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
584+ pub enum ZeroReplicasCounting {
585+ /// Treat them as what they are: `Some(0)`.
586+ TreatAsZero ,
587+ /// Treat them as if the user configured [`None`].
588+ TreatAsNone ,
589+ }
590+
597591#[ cfg( test) ]
598592mod tests {
599593 use std:: collections:: HashSet ;
@@ -713,101 +707,77 @@ mod tests {
713707
714708 #[ test]
715709 fn replica_counts_with_all_replicas_set ( ) {
716- let role = construct_role_with_replicas ( [ Some ( 3 ) , Some ( 2 ) , Some ( 5 ) ] ) ;
710+ let replicas = [ Some ( 3 ) , Some ( 2 ) , Some ( 5 ) ] ;
717711
718712 assert_eq ! (
719- role . fixed_replica_count( ZeroReplicasCounting :: TreatAsZero ) ,
713+ fixed_replica_count( replicas , ZeroReplicasCounting :: TreatAsZero ) ,
720714 Some ( 10 )
721715 ) ;
722716 assert_eq ! (
723- role . fixed_replica_count( ZeroReplicasCounting :: TreatAsNone ) ,
717+ fixed_replica_count( replicas , ZeroReplicasCounting :: TreatAsNone ) ,
724718 Some ( 10 )
725719 ) ;
726- assert_eq ! ( role . estimated_replica_count( ) , 10 ) ;
720+ assert_eq ! ( estimated_replica_count( replicas ) , 10 ) ;
727721 }
728722
729723 #[ test]
730724 fn replica_counts_with_one_replica_unset ( ) {
731- let role = construct_role_with_replicas ( [ Some ( 3 ) , None , Some ( 2 ) ] ) ;
725+ let replicas = [ Some ( 3 ) , None , Some ( 2 ) ] ;
732726
733727 assert_eq ! (
734- role . fixed_replica_count( ZeroReplicasCounting :: TreatAsZero ) ,
728+ fixed_replica_count( replicas , ZeroReplicasCounting :: TreatAsZero ) ,
735729 None
736730 ) ;
737731 assert_eq ! (
738- role . fixed_replica_count( ZeroReplicasCounting :: TreatAsNone ) ,
732+ fixed_replica_count( replicas , ZeroReplicasCounting :: TreatAsNone ) ,
739733 None
740734 ) ;
741- assert_eq ! ( role . estimated_replica_count( ) , 6 ) ;
735+ assert_eq ! ( estimated_replica_count( replicas ) , 6 ) ;
742736 }
743737
744738 #[ test]
745739 fn replica_counts_with_a_zero_replica ( ) {
746- let role = construct_role_with_replicas ( [ Some ( 3 ) , Some ( 0 ) ] ) ;
740+ let replicas = [ Some ( 3 ) , Some ( 0 ) ] ;
747741
748742 assert_eq ! (
749- role . fixed_replica_count( ZeroReplicasCounting :: TreatAsZero ) ,
743+ fixed_replica_count( replicas , ZeroReplicasCounting :: TreatAsZero ) ,
750744 Some ( 3 )
751745 ) ;
752746 // With treat_zero_as_none the zero turns the whole count into None.
753747 assert_eq ! (
754- role . fixed_replica_count( ZeroReplicasCounting :: TreatAsNone ) ,
748+ fixed_replica_count( replicas , ZeroReplicasCounting :: TreatAsNone ) ,
755749 None
756750 ) ;
757- assert_eq ! ( role . estimated_replica_count( ) , 3 ) ;
751+ assert_eq ! ( estimated_replica_count( replicas ) , 3 ) ;
758752 }
759753
760754 #[ test]
761- fn replica_counts_with_a_single_zero_role_group ( ) {
762- let role = construct_role_with_replicas ( [ Some ( 0 ) ] ) ;
755+ fn replica_counts_with_a_single_zero_role_groups_group ( ) {
756+ let replicas = [ Some ( 0 ) ] ;
763757
764758 assert_eq ! (
765- role . fixed_replica_count( ZeroReplicasCounting :: TreatAsZero ) ,
759+ fixed_replica_count( replicas , ZeroReplicasCounting :: TreatAsZero ) ,
766760 Some ( 0 )
767761 ) ;
768762 assert_eq ! (
769- role . fixed_replica_count( ZeroReplicasCounting :: TreatAsNone ) ,
763+ fixed_replica_count( replicas , ZeroReplicasCounting :: TreatAsNone ) ,
770764 None
771765 ) ;
772- assert_eq ! ( role . estimated_replica_count( ) , 0 ) ;
766+ assert_eq ! ( estimated_replica_count( replicas ) , 0 ) ;
773767 }
774768
775769 #[ test]
776770 fn replica_counts_without_role_groups ( ) {
777- let role = construct_role_with_replicas ( vec ! [ ] ) ;
771+ let replicas = [ ] ;
778772
779773 assert_eq ! (
780- role . fixed_replica_count( ZeroReplicasCounting :: TreatAsZero ) ,
774+ fixed_replica_count( replicas , ZeroReplicasCounting :: TreatAsZero ) ,
781775 Some ( 0 )
782776 ) ;
783777 assert_eq ! (
784- role . fixed_replica_count( ZeroReplicasCounting :: TreatAsNone ) ,
778+ fixed_replica_count( replicas , ZeroReplicasCounting :: TreatAsNone ) ,
785779 None
786780 ) ;
787- assert_eq ! ( role. estimated_replica_count( ) , 0 ) ;
788- }
789-
790- /// Builds a [`Role`] with one role group per passed `replicas` entry, so tests only need to
791- /// care about the replica counts that [`Role::fixed_replica_count`] operates on.
792- fn construct_role_with_replicas (
793- replicas : impl IntoIterator < Item = Option < u16 > > ,
794- ) -> Role < ( ) , EmptyConfigOverrides , GenericRoleConfig , GenericCommonConfig > {
795- Role {
796- config : CommonConfiguration :: default ( ) ,
797- role_config : GenericRoleConfig :: default ( ) ,
798- role_groups : replicas
799- . into_iter ( )
800- . enumerate ( )
801- . map ( |( index, replicas) | {
802- (
803- format ! ( "role-group-{index}" ) ,
804- RoleGroup {
805- config : CommonConfiguration :: default ( ) ,
806- replicas,
807- } ,
808- )
809- } )
810- . collect ( ) ,
811- }
781+ assert_eq ! ( estimated_replica_count( replicas) , 0 ) ;
812782 }
813783}
0 commit comments