瀏覽代碼

Merge pull request #804 from thvdveld/rpl-parents-use-linear-map

rpl: use LinearMap for the ParentSet
Thibaut Vandervelden 1 年之前
父節點
當前提交
6831e867d2
共有 2 個文件被更改,包括 62 次插入77 次删除
  1. 12 14
      src/iface/rpl/of0.rs
  2. 50 63
      src/iface/rpl/parents.rs

+ 12 - 14
src/iface/rpl/of0.rs

@@ -41,7 +41,7 @@ impl ObjectiveFunction for ObjectiveFunction0 {
     fn preferred_parent(parent_set: &ParentSet) -> Option<&Parent> {
         let mut pref_parent: Option<&Parent> = None;
 
-        for parent in parent_set.parents() {
+        for (_, parent) in parent_set.parents() {
             if pref_parent.is_none() || parent.rank() < pref_parent.unwrap().rank() {
                 pref_parent = Some(parent);
             }
@@ -98,29 +98,27 @@ mod tests {
 
         let mut parents = ParentSet::default();
 
-        parents.add(Parent::new(
+        parents.add(
             Ipv6Address::default(),
-            0,
-            Rank::ROOT,
-            Default::default(),
-            Ipv6Address::default(),
-        ));
+            Parent::new(0, Rank::ROOT, Default::default(), Ipv6Address::default()),
+        );
 
         let mut address = Ipv6Address::default();
         address.0[15] = 1;
 
-        parents.add(Parent::new(
+        parents.add(
             address,
-            0,
-            Rank::new(1024, DEFAULT_MIN_HOP_RANK_INCREASE),
-            Default::default(),
-            Ipv6Address::default(),
-        ));
+            Parent::new(
+                0,
+                Rank::new(1024, DEFAULT_MIN_HOP_RANK_INCREASE),
+                Default::default(),
+                Ipv6Address::default(),
+            ),
+        );
 
         assert_eq!(
             ObjectiveFunction0::preferred_parent(&parents),
             Some(&Parent::new(
-                Ipv6Address::default(),
                 0,
                 Rank::ROOT,
                 Default::default(),

+ 50 - 63
src/iface/rpl/parents.rs

@@ -6,7 +6,6 @@ use crate::config::RPL_PARENTS_BUFFER_COUNT;
 #[derive(Debug, Clone, Copy, PartialEq)]
 pub(crate) struct Parent {
     rank: Rank,
-    address: Ipv6Address,
     preference: u8,
     version_number: SequenceCounter,
     dodag_id: Ipv6Address,
@@ -15,7 +14,6 @@ pub(crate) struct Parent {
 impl Parent {
     /// Create a new parent.
     pub(crate) fn new(
-        address: Ipv6Address,
         preference: u8,
         rank: Rank,
         version_number: SequenceCounter,
@@ -23,7 +21,6 @@ impl Parent {
     ) -> Self {
         Self {
             rank,
-            address,
             preference,
             version_number,
             dodag_id,
@@ -38,57 +35,47 @@ impl Parent {
 
 #[derive(Debug, Default)]
 pub(crate) struct ParentSet {
-    parents: heapless::Vec<Parent, { RPL_PARENTS_BUFFER_COUNT }>,
+    parents: heapless::LinearMap<Ipv6Address, Parent, { RPL_PARENTS_BUFFER_COUNT }>,
 }
 
 impl ParentSet {
     /// Add a new parent to the parent set. The Rank of the new parent should be lower than the
     /// Rank of the node that holds this parent set.
-    pub(crate) fn add(&mut self, parent: Parent) {
-        if let Some(p) = self.find_mut(parent.address) {
-            // Update information
+    pub(crate) fn add(&mut self, address: Ipv6Address, parent: Parent) {
+        if let Some(p) = self.parents.get_mut(&address) {
             *p = parent;
-        } else if let Err(p) = self.parents.push(parent) {
-            // Look for the worst parent
-            if let Some(worst) = self.worst_parent() {
-                if worst.rank().dag_rank() > parent.rank().dag_rank() {
-                    *worst = parent;
+        } else if let Err(p) = self.parents.insert(address, parent) {
+            if let Some((w_a, w_p)) = self.worst_parent() {
+                if w_p.rank.dag_rank() > parent.rank.dag_rank() {
+                    self.parents.remove(&w_a.clone()).unwrap();
+                    self.parents.insert(address, parent).unwrap();
                 } else {
-                    net_debug!("could not add parent");
+                    net_debug!("could not add {} to parent set, buffer is full", address);
                 }
             } else {
-                // WARNING: there should be a worst parent, since the list of parents is not empty
-                unreachable!();
+                unreachable!()
             }
         }
     }
 
     /// Find a parent based on its address.
-    pub(crate) fn find(&self, address: Ipv6Address) -> Option<&Parent> {
-        self.parents.iter().find(|p| p.address == address)
+    pub(crate) fn find(&self, address: &Ipv6Address) -> Option<&Parent> {
+        self.parents.get(address)
     }
 
     /// Find a mutable parent based on its address.
-    pub(crate) fn find_mut(&mut self, address: Ipv6Address) -> Option<&mut Parent> {
-        self.parents.iter_mut().find(|p| p.address == address)
+    pub(crate) fn find_mut(&mut self, address: &Ipv6Address) -> Option<&mut Parent> {
+        self.parents.get_mut(address)
     }
 
     /// Return a slice to the parent set.
-    pub(crate) fn parents(&self) -> &[Parent] {
-        &self.parents
+    pub(crate) fn parents(&self) -> impl Iterator<Item = (&Ipv6Address, &Parent)> {
+        self.parents.iter()
     }
 
     /// Find the worst parent that is currently in the parent set.
-    fn worst_parent(&mut self) -> Option<&mut Parent> {
-        let mut worst: Option<&mut Parent> = None;
-
-        for p in self.parents.iter_mut() {
-            if worst.is_none() || worst.as_mut().unwrap().rank.dag_rank() < p.rank.dag_rank() {
-                worst = Some(p);
-            }
-        }
-
-        worst
+    fn worst_parent(&self) -> Option<(&Ipv6Address, &Parent)> {
+        self.parents.iter().max_by_key(|(k, v)| v.rank.dag_rank())
     }
 }
 
@@ -99,18 +86,14 @@ mod tests {
     #[test]
     fn add_parent() {
         let mut set = ParentSet::default();
-        set.add(Parent::new(
-            Default::default(),
-            0,
-            Rank::ROOT,
+        set.add(
             Default::default(),
-            Default::default(),
-        ));
+            Parent::new(0, Rank::ROOT, Default::default(), Default::default()),
+        );
 
         assert_eq!(
-            set.find(Default::default()),
+            set.find(&Default::default()),
             Some(&Parent::new(
-                Default::default(),
                 0,
                 Rank::ROOT,
                 Default::default(),
@@ -131,18 +114,19 @@ mod tests {
             address.0[15] = i as u8;
             last_address = address;
 
-            set.add(Parent::new(
-                address,
-                0,
-                Rank::new(256 * i, DEFAULT_MIN_HOP_RANK_INCREASE),
-                Default::default(),
+            set.add(
                 address,
-            ));
+                Parent::new(
+                    0,
+                    Rank::new(256 * i, DEFAULT_MIN_HOP_RANK_INCREASE),
+                    Default::default(),
+                    address,
+                ),
+            );
 
             assert_eq!(
-                set.find(address),
+                set.find(&address),
                 Some(&Parent::new(
-                    address,
                     0,
                     Rank::new(256 * i, DEFAULT_MIN_HOP_RANK_INCREASE),
                     Default::default(),
@@ -155,35 +139,38 @@ mod tests {
         // set.
         let mut address = Ipv6Address::default();
         address.0[15] = 8;
-        set.add(Parent::new(
-            address,
-            0,
-            Rank::new(256 * 8, DEFAULT_MIN_HOP_RANK_INCREASE),
-            Default::default(),
+        set.add(
             address,
-        ));
-        assert_eq!(set.find(address), None);
+            Parent::new(
+                0,
+                Rank::new(256 * 8, DEFAULT_MIN_HOP_RANK_INCREASE),
+                Default::default(),
+                address,
+            ),
+        );
+        assert_eq!(set.find(&address), None);
 
         /// This Parent has a better rank than the last one in the set.
         let mut address = Ipv6Address::default();
         address.0[15] = 9;
-        set.add(Parent::new(
+        set.add(
             address,
-            0,
-            Rank::new(0, DEFAULT_MIN_HOP_RANK_INCREASE),
-            Default::default(),
-            address,
-        ));
+            Parent::new(
+                0,
+                Rank::new(0, DEFAULT_MIN_HOP_RANK_INCREASE),
+                Default::default(),
+                address,
+            ),
+        );
         assert_eq!(
-            set.find(address),
+            set.find(&address),
             Some(&Parent::new(
-                address,
                 0,
                 Rank::new(0, DEFAULT_MIN_HOP_RANK_INCREASE),
                 Default::default(),
                 address
             ))
         );
-        assert_eq!(set.find(last_address), None);
+        assert_eq!(set.find(&last_address), None);
     }
 }