| use super::parents::*; |
| use super::rank::Rank; |
| |
| pub struct ObjectiveFunction0; |
| |
| pub(crate) trait ObjectiveFunction { |
| const OCP: u16; |
| |
| /// Return the new calculated Rank, based on information from the parent. |
| fn rank(current_rank: Rank, parent_rank: Rank) -> Rank; |
| |
| /// Return the preferred parent from a given parent set. |
| fn preferred_parent(parent_set: &ParentSet) -> Option<&Parent>; |
| } |
| |
| impl ObjectiveFunction0 { |
| const OCP: u16 = 0; |
| |
| const RANK_STRETCH: u16 = 0; |
| const RANK_FACTOR: u16 = 1; |
| const RANK_STEP: u16 = 3; |
| |
| fn rank_increase(parent_rank: Rank) -> u16 { |
| (Self::RANK_FACTOR * Self::RANK_STEP + Self::RANK_STRETCH) |
| * parent_rank.min_hop_rank_increase |
| } |
| } |
| |
| impl ObjectiveFunction for ObjectiveFunction0 { |
| const OCP: u16 = 0; |
| |
| fn rank(_: Rank, parent_rank: Rank) -> Rank { |
| assert_ne!(parent_rank, Rank::INFINITE); |
| |
| Rank::new( |
| parent_rank.value + Self::rank_increase(parent_rank), |
| parent_rank.min_hop_rank_increase, |
| ) |
| } |
| |
| fn preferred_parent(parent_set: &ParentSet) -> Option<&Parent> { |
| let mut pref_parent: Option<&Parent> = None; |
| |
| for (_, parent) in parent_set.parents() { |
| if pref_parent.is_none() || parent.rank() < pref_parent.unwrap().rank() { |
| pref_parent = Some(parent); |
| } |
| } |
| |
| pref_parent |
| } |
| } |
| |
| #[cfg(test)] |
| mod tests { |
| use crate::iface::rpl::consts::DEFAULT_MIN_HOP_RANK_INCREASE; |
| |
| use super::*; |
| |
| #[test] |
| fn rank_increase() { |
| // 256 (root) + 3 * 256 |
| assert_eq!( |
| ObjectiveFunction0::rank(Rank::INFINITE, Rank::ROOT), |
| Rank::new(256 + 3 * 256, DEFAULT_MIN_HOP_RANK_INCREASE) |
| ); |
| |
| // 1024 + 3 * 256 |
| assert_eq!( |
| ObjectiveFunction0::rank( |
| Rank::INFINITE, |
| Rank::new(1024, DEFAULT_MIN_HOP_RANK_INCREASE) |
| ), |
| Rank::new(1024 + 3 * 256, DEFAULT_MIN_HOP_RANK_INCREASE) |
| ); |
| } |
| |
| #[test] |
| #[should_panic] |
| fn rank_increase_infinite() { |
| assert_eq!( |
| ObjectiveFunction0::rank(Rank::INFINITE, Rank::INFINITE), |
| Rank::INFINITE |
| ); |
| } |
| |
| #[test] |
| fn empty_set() { |
| assert_eq!( |
| ObjectiveFunction0::preferred_parent(&ParentSet::default()), |
| None |
| ); |
| } |
| |
| #[test] |
| fn non_empty_set() { |
| use crate::wire::Ipv6Address; |
| |
| let mut parents = ParentSet::default(); |
| |
| parents.add( |
| Ipv6Address::default(), |
| Parent::new(0, Rank::ROOT, Default::default(), Ipv6Address::default()), |
| ); |
| |
| let mut address = Ipv6Address::default(); |
| address.0[15] = 1; |
| |
| parents.add( |
| address, |
| Parent::new( |
| 0, |
| Rank::new(1024, DEFAULT_MIN_HOP_RANK_INCREASE), |
| Default::default(), |
| Ipv6Address::default(), |
| ), |
| ); |
| |
| assert_eq!( |
| ObjectiveFunction0::preferred_parent(&parents), |
| Some(&Parent::new( |
| 0, |
| Rank::ROOT, |
| Default::default(), |
| Ipv6Address::default(), |
| )) |
| ); |
| } |
| } |