Skip to content

Commit e601f1b

Browse files
wedsonafojeda
authored andcommitted
rust: rbtree: add iterator
- Add Iterator implementation for `RBTree`, allowing iteration over (key, value) pairs in key order. - Add individual `keys()` and `values()` functions to iterate over keys or values alone. - Update doctests to use iteration instead of explicitly getting items. Iteration is needed by the binder driver to enumerate all values in a tree for oneway spam detection [1]. Link: https://lore.kernel.org/rust-for-linux/[email protected]/ [1] Signed-off-by: Wedson Almeida Filho <[email protected]> Reviewed-by: Alice Ryhl <[email protected]> Tested-by: Alice Ryhl <[email protected]> Reviewed-by: Benno Lossin <[email protected]> Reviewed-by: Boqun Feng <[email protected]> Signed-off-by: Matt Gilbride <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Miguel Ojeda <[email protected]>
1 parent a0d13aa commit e601f1b

File tree

1 file changed

+112
-18
lines changed

1 file changed

+112
-18
lines changed

rust/kernel/rbtree.rs

Lines changed: 112 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,34 +42,53 @@ use core::{
4242
/// assert_eq!(tree.get(&30).unwrap(), &300);
4343
/// }
4444
///
45+
/// // Iterate over the nodes we just inserted.
46+
/// {
47+
/// let mut iter = tree.iter();
48+
/// assert_eq!(iter.next().unwrap(), (&10, &100));
49+
/// assert_eq!(iter.next().unwrap(), (&20, &200));
50+
/// assert_eq!(iter.next().unwrap(), (&30, &300));
51+
/// assert!(iter.next().is_none());
52+
/// }
53+
///
54+
/// // Print all elements.
55+
/// for (key, value) in &tree {
56+
/// pr_info!("{} = {}\n", key, value);
57+
/// }
58+
///
4559
/// // Replace one of the elements.
4660
/// tree.try_create_and_insert(10, 1000, flags::GFP_KERNEL)?;
4761
///
4862
/// // Check that the tree reflects the replacement.
4963
/// {
50-
/// assert_eq!(tree.get(&10).unwrap(), &1000);
51-
/// assert_eq!(tree.get(&20).unwrap(), &200);
52-
/// assert_eq!(tree.get(&30).unwrap(), &300);
64+
/// let mut iter = tree.iter();
65+
/// assert_eq!(iter.next().unwrap(), (&10, &1000));
66+
/// assert_eq!(iter.next().unwrap(), (&20, &200));
67+
/// assert_eq!(iter.next().unwrap(), (&30, &300));
68+
/// assert!(iter.next().is_none());
5369
/// }
5470
///
5571
/// // Change the value of one of the elements.
5672
/// *tree.get_mut(&30).unwrap() = 3000;
5773
///
5874
/// // Check that the tree reflects the update.
5975
/// {
60-
/// assert_eq!(tree.get(&10).unwrap(), &1000);
61-
/// assert_eq!(tree.get(&20).unwrap(), &200);
62-
/// assert_eq!(tree.get(&30).unwrap(), &3000);
76+
/// let mut iter = tree.iter();
77+
/// assert_eq!(iter.next().unwrap(), (&10, &1000));
78+
/// assert_eq!(iter.next().unwrap(), (&20, &200));
79+
/// assert_eq!(iter.next().unwrap(), (&30, &3000));
80+
/// assert!(iter.next().is_none());
6381
/// }
6482
///
6583
/// // Remove an element.
6684
/// tree.remove(&10);
6785
///
6886
/// // Check that the tree reflects the removal.
6987
/// {
70-
/// assert_eq!(tree.get(&10), None);
71-
/// assert_eq!(tree.get(&20).unwrap(), &200);
72-
/// assert_eq!(tree.get(&30).unwrap(), &3000);
88+
/// let mut iter = tree.iter();
89+
/// assert_eq!(iter.next().unwrap(), (&20, &200));
90+
/// assert_eq!(iter.next().unwrap(), (&30, &3000));
91+
/// assert!(iter.next().is_none());
7392
/// }
7493
///
7594
/// # Ok::<(), Error>(())
@@ -109,19 +128,22 @@ use core::{
109128
///
110129
/// // Check the nodes we just inserted.
111130
/// {
112-
/// assert_eq!(tree.get(&10).unwrap(), &100);
113-
/// assert_eq!(tree.get(&20).unwrap(), &200);
114-
/// assert_eq!(tree.get(&30).unwrap(), &300);
131+
/// let mut iter = tree.iter();
132+
/// assert_eq!(iter.next().unwrap(), (&10, &100));
133+
/// assert_eq!(iter.next().unwrap(), (&20, &200));
134+
/// assert_eq!(iter.next().unwrap(), (&30, &300));
135+
/// assert!(iter.next().is_none());
115136
/// }
116137
///
117138
/// // Remove a node, getting back ownership of it.
118139
/// let existing = tree.remove(&30).unwrap();
119140
///
120141
/// // Check that the tree reflects the removal.
121142
/// {
122-
/// assert_eq!(tree.get(&10).unwrap(), &100);
123-
/// assert_eq!(tree.get(&20).unwrap(), &200);
124-
/// assert_eq!(tree.get(&30), None);
143+
/// let mut iter = tree.iter();
144+
/// assert_eq!(iter.next().unwrap(), (&10, &100));
145+
/// assert_eq!(iter.next().unwrap(), (&20, &200));
146+
/// assert!(iter.next().is_none());
125147
/// }
126148
///
127149
/// // Create a preallocated reservation that we can re-use later.
@@ -133,9 +155,11 @@ use core::{
133155
///
134156
/// // Check that the tree reflect the new insertion.
135157
/// {
136-
/// assert_eq!(tree.get(&10).unwrap(), &100);
137-
/// assert_eq!(tree.get(&15).unwrap(), &150);
138-
/// assert_eq!(tree.get(&20).unwrap(), &200);
158+
/// let mut iter = tree.iter();
159+
/// assert_eq!(iter.next().unwrap(), (&10, &100));
160+
/// assert_eq!(iter.next().unwrap(), (&15, &150));
161+
/// assert_eq!(iter.next().unwrap(), (&20, &200));
162+
/// assert!(iter.next().is_none());
139163
/// }
140164
///
141165
/// # Ok::<(), Error>(())
@@ -167,6 +191,26 @@ impl<K, V> RBTree<K, V> {
167191
_p: PhantomData,
168192
}
169193
}
194+
195+
/// Returns an iterator over the tree nodes, sorted by key.
196+
pub fn iter(&self) -> Iter<'_, K, V> {
197+
// INVARIANT: `bindings::rb_first` returns a valid pointer to a tree node given a valid pointer to a tree root.
198+
Iter {
199+
_tree: PhantomData,
200+
// SAFETY: `self.root` is a valid pointer to the tree root.
201+
next: unsafe { bindings::rb_first(&self.root) },
202+
}
203+
}
204+
205+
/// Returns an iterator over the keys of the nodes in the tree, in sorted order.
206+
pub fn keys(&self) -> impl Iterator<Item = &'_ K> {
207+
self.iter().map(|(k, _)| k)
208+
}
209+
210+
/// Returns an iterator over the values of the nodes in the tree, sorted by key.
211+
pub fn values(&self) -> impl Iterator<Item = &'_ V> {
212+
self.iter().map(|(_, v)| v)
213+
}
170214
}
171215

172216
impl<K, V> RBTree<K, V>
@@ -358,6 +402,56 @@ impl<K, V> Drop for RBTree<K, V> {
358402
}
359403
}
360404

405+
impl<'a, K, V> IntoIterator for &'a RBTree<K, V> {
406+
type Item = (&'a K, &'a V);
407+
type IntoIter = Iter<'a, K, V>;
408+
409+
fn into_iter(self) -> Self::IntoIter {
410+
self.iter()
411+
}
412+
}
413+
414+
/// An iterator over the nodes of a [`RBTree`].
415+
///
416+
/// Instances are created by calling [`RBTree::iter`].
417+
///
418+
/// # Invariants
419+
/// - `self.next` is a valid pointer.
420+
/// - `self.next` points to a node stored inside of a valid `RBTree`.
421+
pub struct Iter<'a, K, V> {
422+
_tree: PhantomData<&'a RBTree<K, V>>,
423+
next: *mut bindings::rb_node,
424+
}
425+
426+
// SAFETY: The [`Iter`] gives out immutable references to K and V, so it has the same
427+
// thread safety requirements as immutable references.
428+
unsafe impl<'a, K: Sync, V: Sync> Send for Iter<'a, K, V> {}
429+
430+
// SAFETY: The [`Iter`] gives out immutable references to K and V, so it has the same
431+
// thread safety requirements as immutable references.
432+
unsafe impl<'a, K: Sync, V: Sync> Sync for Iter<'a, K, V> {}
433+
434+
impl<'a, K, V> Iterator for Iter<'a, K, V> {
435+
type Item = (&'a K, &'a V);
436+
437+
fn next(&mut self) -> Option<Self::Item> {
438+
if self.next.is_null() {
439+
return None;
440+
}
441+
442+
// SAFETY: By the type invariant of `Iter`, `self.next` is a valid node in an `RBTree`,
443+
// and by the type invariant of `RBTree`, all nodes point to the links field of `Node<K, V>` objects.
444+
let cur = unsafe { container_of!(self.next, Node<K, V>, links) };
445+
446+
// SAFETY: `self.next` is a valid tree node by the type invariants.
447+
self.next = unsafe { bindings::rb_next(self.next) };
448+
449+
// SAFETY: By the same reasoning above, it is safe to dereference the node. Additionally,
450+
// it is ok to return a reference to members because the iterator must outlive it.
451+
Some(unsafe { (&(*cur).key, &(*cur).value) })
452+
}
453+
}
454+
361455
/// A memory reservation for a red-black tree node.
362456
///
363457
///

0 commit comments

Comments
 (0)