1 use crate::MediaTrackSettings; 2 3 pub(super) fn select_optimal_candidates<'a, I>(candidates: I) -> Vec<&'a MediaTrackSettings> 4 where 5 I: IntoIterator<Item = (&'a MediaTrackSettings, f64)>, 6 { 7 let mut optimal_candidates = vec![]; 8 let mut optimal_fitness_distance = f64::INFINITY; 9 10 for (candidate, fitness_distance) in candidates { 11 use std::cmp::Ordering; 12 13 #[cfg(feature = "total_cmp")] 14 let ordering = fitness_distance.total_cmp(&optimal_fitness_distance); 15 16 // TODO: remove fallback once MSRV has been bumped to 1.62 or later: 17 #[cfg(not(feature = "total_cmp"))] 18 let ordering = { 19 // See http://doc.rust-lang.org/1.65.0/core/primitive.f64.html#method.total_cmp: 20 21 let mut left = fitness_distance.to_bits() as i64; 22 let mut right = optimal_fitness_distance.to_bits() as i64; 23 24 left ^= (((left >> 63) as u64) >> 1) as i64; 25 right ^= (((right >> 63) as u64) >> 1) as i64; 26 27 left.cmp(&right) 28 }; 29 30 if ordering == Ordering::Less { 31 // Candidate is new optimal, so drop current selection: 32 optimal_candidates.clear(); 33 optimal_fitness_distance = fitness_distance; 34 } 35 36 if ordering != Ordering::Greater { 37 // Candidate is optimal, so add to selection: 38 optimal_candidates.push(candidate); 39 } 40 } 41 42 optimal_candidates 43 } 44 45 #[cfg(test)] 46 mod tests { 47 use crate::MediaTrackSettings; 48 49 use super::select_optimal_candidates; 50 51 #[test] 52 fn monotonic_increasing() { 53 let settings = vec![ 54 MediaTrackSettings::default(), 55 MediaTrackSettings::default(), 56 MediaTrackSettings::default(), 57 MediaTrackSettings::default(), 58 ]; 59 60 let candidates = vec![ 61 (&settings[0], 0.1), 62 (&settings[1], 0.1), 63 (&settings[2], 0.2), 64 (&settings[3], 0.3), 65 ]; 66 67 let actual = select_optimal_candidates(candidates); 68 69 let expected = vec![&settings[0], &settings[1]]; 70 71 assert_eq!(actual, expected); 72 } 73 74 #[test] 75 fn monotonic_decreasing() { 76 let settings = vec![ 77 MediaTrackSettings::default(), 78 MediaTrackSettings::default(), 79 MediaTrackSettings::default(), 80 MediaTrackSettings::default(), 81 ]; 82 83 let candidates = vec![ 84 (&settings[0], 0.3), 85 (&settings[1], 0.2), 86 (&settings[2], 0.1), 87 (&settings[3], 0.1), 88 ]; 89 90 let actual = select_optimal_candidates(candidates); 91 92 let expected = vec![&settings[2], &settings[3]]; 93 94 assert_eq!(actual, expected); 95 } 96 97 #[test] 98 fn alternating() { 99 let settings = vec![ 100 MediaTrackSettings::default(), 101 MediaTrackSettings::default(), 102 MediaTrackSettings::default(), 103 MediaTrackSettings::default(), 104 ]; 105 106 let candidates = vec![ 107 (&settings[0], 0.2), 108 (&settings[1], 0.1), 109 (&settings[2], 0.2), 110 (&settings[3], 0.1), 111 ]; 112 113 let actual = select_optimal_candidates(candidates); 114 115 let expected = vec![&settings[1], &settings[3]]; 116 117 assert_eq!(actual, expected); 118 } 119 } 120