mywheel-rs

πŸ›ž mywheel-rs

Reinventing the wheel - Custom data structures optimized for specific use cases

Crates.io Docs.rs CI codecov License

πŸš€ Quick Start

Add this to your Cargo.toml:

[dependencies]
mywheel-rs = "0.1"

Basic Usage

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

✨ Features

mywheel-rs provides specialized data structures optimized for specific use cases:

πŸ“Š Data Structures

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

🎯 Key Benefits

πŸ“š Usage Examples

Dllist: Non-owning Doubly Linked List

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.

BPQueue: Bounded Priority Queue

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.

RepeatArray: Memory-Efficient Constant Array

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.

ShiftArray: Offset-Based Indexing

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.

🏎️ Performance Comparison

Benchmark Summary

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

Memory Usage

Structure Per Element For 1M Elements
Vec 24 bytes 24 MB
RepeatArray 0 bytes 24 bytes total
Dllist 24 bytes 24 MB + sentinel
BPQueue (range 0-10) ~2.4 bytes ~2.4 MB

See PERFORMANCE_COMPARISON.md for detailed benchmarks

πŸ€” When to Use mywheel-rs

Use mywheel-rs when:

βœ… 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

Use std::collections when:

βœ… 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

πŸ“– Documentation

πŸ› οΈ Installation

πŸ“¦ Cargo

cargo install mywheel-rs

Add to Project

[dependencies]
mywheel-rs = "0.1"

Features

[dependencies]
mywheel-rs = { version = "0.1", features = ["std"] }

πŸ§ͺ Testing

Run the full test suite:

cargo test --all-features --workspace

Run benchmarks:

cargo bench

πŸ”§ no_std Support

mywheel-rs supports no_std environments, making it suitable for embedded systems and bare-metal applications.

no_std Configuration

[dependencies]
mywheel-rs = { version = "0.1", default-features = false }

std Feature

The std feature enables logging support:

[dependencies]
mywheel-rs = { version = "0.1", features = ["std"] }

Available in no_std Mode

βœ… All core data structures (Dllist, BPQueue, RepeatArray, ShiftArray, MapAdapter, Robin) βœ… Full API functionality βœ… Iterator implementations βœ… Trait implementations (Debug, Clone, etc.)

Not Available in no_std Mode

❌ Logging module (requires std) ❌ Environment variables and file I/O

πŸ“œ License

Licensed under either of

at your option.

🀝 Contribution

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.