Reinventing the wheel - Custom data structures optimized for specific use cases
Add this to your Cargo.toml:
[dependencies]
mywheel-rs = "0.1"
use mywheel_rs::dllist::Dllist;
use mywheel_rs::bpqueue::BPQueue;
use mywheel_rs::array_like::RepeatArray;
// Create a doubly linked list
let mut list = Dllist::new(0);
let mut node1 = list.head.next; // Get node from list
let mut node2 = list.head.next; // Another node
list.append(&mut node1);
list.append(&mut node2);
// Create a bounded priority queue
let mut bpq = BPQueue::<i32>::new(-5, 5);
let mut item = bpq.head.next.clone();
bpq.append(&mut item, 3);
// Create a memory-efficient constant array
let constant_array = RepeatArray::new(42, 1000);
assert_eq!(constant_array[0], 42);
assert_eq!(constant_array[999], 42);
mywheel-rs provides specialized data structures optimized for specific use cases:
| Structure | Description | Best For |
|---|---|---|
| Dllist | Non-owning doubly linked list with sentinel nodes | FM algorithm, shared nodes, graph partitioning |
| BPQueue | Bounded priority queue with O(1) operations | Small integer ranges, real-time scheduling |
| RepeatArray | Zero-allocation constant array | Large constant datasets, memory efficiency |
| ShiftArray | Offset-based array indexing | Circular buffers, sliding windows |
| MapAdapter | Vector-like adapter with sparse data support | Sparse datasets, vector API compatibility |
| Robin | Round-robin scheduler | Fair task scheduling, cyclic access |
use mywheel_rs::dllist::{Dllist, Dllink};
// Create a list with sentinel node
let mut list = Dllist::new(0);
// Create nodes that can be shared
let mut node_a = Dllink::new("A");
let mut node_b = Dllink::new("B");
// Append nodes to list
list.append(&mut node_a);
list.append(&mut node_b);
// Nodes can be detached and moved to another list
let mut list2 = Dllist::new(0);
list2.append(&mut node_a); // Same node in different list
Use when: You need to share nodes between multiple data structures, implementing FM algorithm, or need explicit memory control.
use mywheel_rs::bpqueue::BPQueue;
// Create queue for keys in range -5 to 5
let mut bpq = BPQueue::<i32>::new(-5, 5);
// Insert items with integer keys
let mut item1 = bpq.head.next.clone();
let mut item2 = bpq.head.next.clone();
bpq.append(&mut item1, 3);
bpq.append(&mut item2, -2);
// Extract maximum (O(1))
let max_item = bpq.get_max();
bpq.detach(max_item);
Use when: Keys are bounded integers (range < 1000), you need O(1) operations, or implementing FM algorithm with integer gains.
use mywheel_rs::array_like::RepeatArray;
// Create array with 1 million elements, all 42
let large_array = RepeatArray::new(42, 1_000_000);
// Access is O(1) and uses only 24 bytes total!
assert_eq!(large_array[0], 42);
assert_eq!(large_array[999_999], 42);
// Iterator support
for value in large_array.iter() {
assert_eq!(*value, 42);
}
Use when: You have large constant datasets, memory is constrained, or all operations are read-only.
use mywheel_rs::array_like::ShiftArray;
use std::ops::Index;
// Create array with offset starting at 100
let mut array = ShiftArray::new(100);
array.push("value0");
array.push("value1");
// Access with offset indexing
assert_eq!(array[100], "value0");
assert_eq!(array[101], "value1");
// Change offset for sliding window
array.set_start(101);
assert_eq!(array[101], "value0");
Use when: Implementing circular buffers, sliding windows, or data with natural cyclic access patterns.
| Structure | Operation | mywheel-rs | std::collections | Speedup |
|---|---|---|---|---|
| Dllist | Append | O(1) | O(1) | 2-3x faster |
| BPQueue | Insert | O(1) | O(log n) | 10-50x faster |
| RepeatArray | Access | O(1) | O(1) | Same, 100x less memory |
| ShiftArray | Access | O(1) | O(1) | Similar, better for cyclic |
| Structure | Per Element | For 1M Elements |
|---|---|---|
| Vec |
24 bytes | 24 MB |
| RepeatArray |
0 bytes | 24 bytes total |
| Dllist |
24 bytes | 24 MB + sentinel |
| BPQueue |
~2.4 bytes | ~2.4 MB |
See PERFORMANCE_COMPARISON.md for detailed benchmarks
β Performance is critical - You need 10-50x speedup for specific operations β Memory is constrained - You need to minimize memory usage β Bounded integer keys - Your priority queue uses small integer ranges β Shared nodes - You need to share data between multiple structures β Educational purposes - You want to understand data structure internals β FM algorithm - Youβre implementing graph partitioning algorithms
β General purpose - You need standard, well-tested implementations β Complex types - Your keys arenβt simple integers β Automatic memory management - You prefer owned data structures β Standard APIs - You need full compatibility with Rust ecosystem
cargo install mywheel-rs
[dependencies]
mywheel-rs = "0.1"
[dependencies]
mywheel-rs = { version = "0.1", features = ["std"] }
Run the full test suite:
cargo test --all-features --workspace
Run benchmarks:
cargo bench
mywheel-rs supports no_std environments, making it suitable for embedded systems and bare-metal applications.
[dependencies]
mywheel-rs = { version = "0.1", default-features = false }
The std feature enables logging support:
[dependencies]
mywheel-rs = { version = "0.1", features = ["std"] }
β All core data structures (Dllist, BPQueue, RepeatArray, ShiftArray, MapAdapter, Robin) β Full API functionality β Iterator implementations β Trait implementations (Debug, Clone, etc.)
β Logging module (requires std) β Environment variables and file I/O
Licensed under either of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
See CONTRIBUTING.md.