@@ -697,6 +697,10 @@ impl<'a> PDB {
697697
698698 /// Remove the Model specified.
699699 ///
700+ /// ## Complexity
701+ /// * **Time**: amortized O(n) where n is the number of models, best case O(1) if model is the last one.
702+ /// * **Memory**: O(1)
703+ ///
700704 /// ## Arguments
701705 /// * `index` - the index of the Model to remove
702706 ///
@@ -709,43 +713,49 @@ impl<'a> PDB {
709713 /// Remove all Models except for models
710714 /// specified by idxs.
711715 ///
716+ /// ## Complexity
717+ /// * **Time**: O(n) where n is the number of models.
718+ /// * **Memory**: O(k) where k is the number of models to keep.
719+ ///
712720 /// ## Arguments
713721 /// * `idxs` - the indices of the Models to keep
714722 ///
715723 /// ## Returns
716724 /// `None` if any of the indices are out of bounds.
717725 /// `Some(usize)` the number of models removed.
718726 pub fn remove_models_except ( & mut self , idxs : & [ usize ] ) -> Option < usize > {
727+ if self . models . is_empty ( ) {
728+ #[ cfg( debug_assertions) ]
729+ eprint ! ( "remove_models_except: no models to remove" ) ;
730+ return None ;
731+ }
732+
719733 let start_count = self . model_count ( ) ;
720- let mut removed = 0_usize ;
721734
722735 // bounds check the idxs
723736 if idxs. iter ( ) . max ( ) ? >= & start_count {
724737 return None ;
725738 }
726739
727- let idxs = ( 0 ..start_count) . filter ( |idx| !idxs. contains ( idx) ) ;
728-
729- for idx in idxs {
730- self . models . swap ( idx - removed, start_count - 1 ) ;
731- removed += 1 ;
732- }
740+ let retained: Vec < _ > = self
741+ . models
742+ . drain ( ..)
743+ . enumerate ( )
744+ . filter ( |( i, _) | idxs. contains ( i) )
745+ . map ( |( _, m) | m)
746+ . collect ( ) ;
733747
734- self . models . truncate ( start_count - removed) ;
748+ let removed = start_count - retained. len ( ) ;
749+ self . models . clear ( ) ;
750+ self . models . extend ( retained) ;
735751
736752 Some ( removed)
737753 }
738754
739755 /// Remove all Models except for the first one.
740756 ///
741- /// ## Panics
742- /// Panics if there are no models.
743- pub fn remove_all_models_except_first ( & mut self ) {
744- if self . model_count ( ) <= 1 {
745- return ;
746- }
747-
748- self . remove_models_except ( & [ 0 ] ) ;
757+ pub fn remove_all_models_except_first ( & mut self ) -> Option < usize > {
758+ self . remove_models_except ( & [ 0 ] )
749759 }
750760
751761 /// Remove the Model specified. It returns `true` if it found a matching Model and removed it.
0 commit comments