Skip to content

Commit f05dcd7

Browse files
committed
Add method to get mutable reference of nodes
Add several methods to get mutable reference to data in the interval tree. Signed-off-by: Liu Jiang <gerry@linux.alibaba.com>
1 parent 8a32f2c commit f05dcd7

File tree

1 file changed

+86
-7
lines changed

1 file changed

+86
-7
lines changed

src/interval_tree.rs

Lines changed: 86 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,14 @@ impl<T> NodeState<T> {
202202
}
203203
}
204204

205+
fn as_mut(&mut self) -> NodeState<&mut T> {
206+
match self {
207+
NodeState::<T>::Valued(ref mut x) => NodeState::<&mut T>::Valued(x),
208+
NodeState::<T>::Allocated => NodeState::<&mut T>::Allocated,
209+
NodeState::<T>::Free => NodeState::<&mut T>::Free,
210+
}
211+
}
212+
205213
fn is_free(&self) -> bool {
206214
if let NodeState::<T>::Free = self {
207215
true
@@ -273,7 +281,7 @@ impl<T> Node<T> {
273281
}
274282
}
275283

276-
/// Returns the node covers full range of the `key`.
284+
/// Returns a shared reference to the node covers full range of the `key`.
277285
fn search_superset(&self, key: &Range) -> Option<&Self> {
278286
if self.0.key.contain(key) {
279287
Some(self)
@@ -288,6 +296,21 @@ impl<T> Node<T> {
288296
}
289297
}
290298

299+
/// Returns a mutable reference to the node covers full range of the `key`.
300+
fn search_superset_mut(&mut self, key: &Range) -> Option<&mut Self> {
301+
if self.0.key.contain(key) {
302+
Some(self)
303+
} else if key.max < self.0.key.min && self.0.left.is_some() {
304+
// Safe to unwrap() because we have just checked it.
305+
self.0.left.as_mut().unwrap().search_superset_mut(key)
306+
} else if key.min > self.0.key.max && self.0.right.is_some() {
307+
// Safe to unwrap() because we have just checked it.
308+
self.0.right.as_mut().unwrap().search_superset_mut(key)
309+
} else {
310+
None
311+
}
312+
}
313+
291314
/// Insert a new (key, data) pair into the subtree.
292315
///
293316
/// Note: it will panic if the new key intersects with existing nodes.
@@ -587,7 +610,7 @@ impl<T> IntervalTree<T> {
587610
}
588611
}
589612

590-
/// Get the node fully covering the entire key range.
613+
/// Get a shared reference to the node fully covering the entire key range.
591614
///
592615
/// # Examples
593616
/// ```rust
@@ -613,7 +636,33 @@ impl<T> IntervalTree<T> {
613636
}
614637
}
615638

616-
/// Get the value associated with the id.
639+
/// Get a mutable reference to the node fully covering the entire key range.
640+
///
641+
/// # Examples
642+
/// ```rust
643+
/// extern crate vm_allocator;
644+
/// use vm_allocator::{IntervalTree, Range, NodeState};
645+
///
646+
/// let mut tree = IntervalTree::<u64>::new();
647+
/// tree.insert(Range::new(0x100u32, 0x100u32), Some(1));
648+
/// tree.insert(Range::new(0x200u32, 0x2ffu32), None);
649+
/// assert_eq!(tree.get_superset_mut(&Range::new(0x100u32, 0x100u32)),
650+
/// Some((&Range::new(0x100u32, 0x100u32), NodeState::Valued(&mut 1))));
651+
/// assert_eq!(tree.get_superset_mut(&Range::new(0x210u32, 0x210u32)),
652+
/// Some((&Range::new(0x200u32, 0x2ffu32), NodeState::Free)));
653+
/// assert_eq!(tree.get_superset_mut(&Range::new(0x2ffu32, 0x2ffu32)),
654+
/// Some((&Range::new(0x200u32, 0x2ffu32), NodeState::Free)));
655+
/// ```
656+
pub fn get_superset_mut(&mut self, key: &Range) -> Option<(&Range, NodeState<&mut T>)> {
657+
match self.root {
658+
None => None,
659+
Some(ref mut node) => node
660+
.search_superset_mut(key)
661+
.map(|n| (&n.0.key, n.0.data.as_mut())),
662+
}
663+
}
664+
665+
/// Get a shared reference to the value associated with the id.
617666
///
618667
/// # Examples
619668
/// ```rust
@@ -623,11 +672,11 @@ impl<T> IntervalTree<T> {
623672
/// let mut tree = IntervalTree::<u32>::new();
624673
/// tree.insert(Range::new(0x100u16, 0x100u16), Some(1));
625674
/// tree.insert(Range::new(0x200u16, 0x2ffu16), None);
626-
/// assert_eq!(tree.get_value_by_id(0x100u16), Some(&1));
627-
/// assert_eq!(tree.get_value_by_id(0x210u32), None);
628-
/// assert_eq!(tree.get_value_by_id(0x2ffu64), None);
675+
/// assert_eq!(tree.get_by_id(0x100u16), Some(&1));
676+
/// assert_eq!(tree.get_by_id(0x210u32), None);
677+
/// assert_eq!(tree.get_by_id(0x2ffu64), None);
629678
/// ```
630-
pub fn get_value_by_id<U>(&self, id: U) -> Option<&T>
679+
pub fn get_by_id<U>(&self, id: U) -> Option<&T>
631680
where
632681
u64: From<U>,
633682
{
@@ -643,6 +692,36 @@ impl<T> IntervalTree<T> {
643692
}
644693
}
645694

695+
/// Get a mutable reference to the value associated with the id.
696+
///
697+
/// # Examples
698+
/// ```rust
699+
/// extern crate vm_allocator;
700+
/// use vm_allocator::{IntervalTree, Range, NodeState};
701+
///
702+
/// let mut tree = IntervalTree::<u32>::new();
703+
/// tree.insert(Range::new(0x100u16, 0x100u16), Some(1));
704+
/// tree.insert(Range::new(0x200u16, 0x2ffu16), None);
705+
/// assert_eq!(tree.get_by_id_mut(0x100u16), Some(&mut 1));
706+
/// assert_eq!(tree.get_by_id_mut(0x210u32), None);
707+
/// assert_eq!(tree.get_by_id_mut(0x2ffu64), None);
708+
/// ```
709+
pub fn get_by_id_mut<U>(&mut self, id: U) -> Option<&mut T>
710+
where
711+
u64: From<U>,
712+
{
713+
match self.root {
714+
None => None,
715+
Some(ref mut node) => {
716+
let key = Range::new_point(id);
717+
match node.search_superset_mut(&key) {
718+
Some(node) => node.0.data.as_mut().into(),
719+
None => None,
720+
}
721+
}
722+
}
723+
}
724+
646725
/// Insert the (key, data) pair into the interval tree, panic if intersects with existing nodes.
647726
///
648727
/// # Examples

0 commit comments

Comments
 (0)