|
@@ -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);
|
|
|
}
|
|
|
}
|