Skip to content

Commit 450b908

Browse files
committed
feat: edit readme
1 parent ef140c7 commit 450b908

File tree

4 files changed

+65
-15
lines changed

4 files changed

+65
-15
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "flat_rbtree"
3-
version = "0.1.5"
3+
version = "0.1.6"
44
edition = "2024"
55
authors = ["Matheus-git <mathiew0@gmail.com>"]
66
description = "A flat, index-based Red-Black Tree with no heap allocations. Ideal for performance-critical or memory-constrained environments."

README.md

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,46 @@ A fast, index-based Red-Black Tree with no heap allocations — ideal for system
88

99
- **Flat storage**: all nodes are stored in a `array`, avoiding pointer indirection.
1010
- **No allocations per node**: avoids `Box`, `Rc`, or `Arc`.
11-
- **No-std**: suitable for embedded environments.
12-
- **Preallocated with MaybeUninit**: minimizes runtime overhead and ensures memory safety.
11+
- **No-std**: works in embedded or bare-metal environments without relying on the Rust standard library..
12+
- **Preallocated with MaybeUninit**: memory for all nodes is allocated upfront, minimizing runtime overhead and ensuring safe initialization.
13+
- **Fixed capacity**: tree size is bounded at compile-time, making resource usage predictable.
1314

1415
## Usage
1516

1617
```rust
17-
let mut tree = RedBlackTree::<&str, i32, 1>::new();
18-
tree.insert("A", 1);
19-
tree.update("A", 2);
20-
tree.search(&"A"); // Some(&2)
21-
tree.remove("A");
18+
let mut tree = RedBlackTree::<i32, &str, 10>::new();
19+
20+
tree.insert(10, "A");
21+
tree.insert(20, "B");
22+
tree.insert(5, "C");
23+
24+
tree.update(10, "Updated A");
25+
26+
if let Some(value) = tree.search(&10) {
27+
println!("Key 10 has value: {}", value);
28+
}
29+
30+
for (key, value) in tree.iter() {
31+
println!("Key: {}, Value: {}", key, value);
32+
}
33+
34+
tree.remove(20);
35+
36+
if !tree.contains_key(&20) {
37+
println!("Key 20 successfully removed");
38+
}
2239
```
2340

2441
## Benchmark: flat_rbtree vs [rbtree](https://docs.rs/rbtree/latest/rbtree/) (10,000 operations)
2542

43+
Since all operations are at most O(log n), this benchmark is just to give an idea of the performance compared to a pointer-based implementation.
44+
2645
| Operation | flat_rbtree | [rbtree](https://docs.rs/rbtree/latest/rbtree/) |
2746
|-----------|----------------|---------------|
2847
| **Insert** | 1.14 ms | 1.34 ms |
2948
| **Remove** | 2.12 ns | 354 ps |
3049
| **Search** | 655 µs | 514 µs |
3150

32-
> It’s worth noting that `rbtree` is a pointer-based implementation, which tends to be more performant than an index-based implementation.
3351

3452
## 📝 License
3553

src/lib.rs

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
#![allow(warnings)]
2-
#![cfg_attr(not(test), no_std)]
2+
#![no_std]
33

44
//! A fast, index-based Red-Black Tree with no heap allocations.
55
//!
66
//! ## Features
7-
//! - No heap allocation
8-
//! - All nodes are stored in a `array`, avoiding pointers
9-
//! - Flat storage using `MaybeUninit`
10-
//! - Suitable for `no_std` environments
7+
//! - **Flat storage**: all nodes are stored in an `array`, avoiding pointer indirection.
8+
//! - **No allocations per node**: avoids `Box`, `Rc`, or `Arc`.
9+
//! - **No-std**: works in embedded or bare-metal environments without relying on the Rust standard library.
10+
//! - **Preallocated with `MaybeUninit`**: memory for all nodes is allocated upfront, minimizing runtime overhead and ensuring safe initialization.
11+
//! - **Fixed capacity**: tree size is bounded at compile-time, making resource usage predictable.
1112
//!
1213
use core::mem::MaybeUninit;
1314
use core::cmp::Ordering;
@@ -30,6 +31,7 @@ struct Node<K, V> {
3031
right: usize,
3132
}
3233

34+
/// An iterator over the entries of a `RedBlackTree`.
3335
pub struct RedBlackTreeIter<'a, K: Ord + 'a, V: 'a, const N: usize> {
3436
tree: &'a RedBlackTree<K, V, N>,
3537
index: usize,
@@ -38,6 +40,7 @@ pub struct RedBlackTreeIter<'a, K: Ord + 'a, V: 'a, const N: usize> {
3840
impl<'a, K: Ord + 'a, V: 'a, const N: usize> Iterator for RedBlackTreeIter<'a, K, V, N> {
3941
type Item = (&'a K, &'a V);
4042

43+
/// Advances the iterator and returns the next key-value pair in ascending order.
4144
fn next(&mut self) -> Option<Self::Item> {
4245
if self.index == SENTINEL {
4346
let next = self.tree.min_usize(self.tree.root);
@@ -60,6 +63,7 @@ impl<'a, K: Ord + 'a, V: 'a, const N: usize> Iterator for RedBlackTreeIter<'a, K
6063
}
6164

6265
impl<'a, K: Ord + 'a, V: 'a, const N: usize> DoubleEndedIterator for RedBlackTreeIter<'a, K, V, N> {
66+
/// Advances the iterator from the back and returns the previous key-value pair in descending order.
6367
fn next_back(&mut self) -> Option<Self::Item> {
6468
if self.index == SENTINEL {
6569
let next = self.tree.max_usize(self.tree.root);
@@ -720,6 +724,34 @@ mod tests {
720724
tree
721725
}
722726

727+
#[test]
728+
fn test_example() {
729+
let mut tree = RedBlackTree::<i32, &str, 10>::new();
730+
731+
tree.insert(10, "A");
732+
tree.insert(20, "B");
733+
tree.insert(5, "C");
734+
735+
tree.update(10, "Updated A");
736+
737+
assert_eq!(tree.search(&10), Some(&"Updated A"));
738+
assert_eq!(tree.search(&20), Some(&"B"));
739+
assert_eq!(tree.search(&5), Some(&"C"));
740+
assert_eq!(tree.contains_key(&20), true);
741+
assert_eq!(tree.contains_key(&100), false);
742+
743+
// Check iteration order (should be sorted by key)
744+
let mut iter = tree.iter();
745+
assert_eq!(iter.next(), Some((&5, &"C")));
746+
assert_eq!(iter.next(), Some((&10, &"Updated A")));
747+
assert_eq!(iter.next(), Some((&20, &"B")));
748+
assert_eq!(iter.next(), None);
749+
750+
tree.remove(20);
751+
assert_eq!(tree.search(&20), None);
752+
assert_eq!(tree.contains_key(&20), false);
753+
}
754+
723755
#[test]
724756
fn test_utils(){
725757
let mut tree = setup_small_tree();

0 commit comments

Comments
 (0)