Ordered set and map data structures via an arena-based scapegoat tree (memory-efficient, self-balancing binary search tree).
This library is #![no_std]
compatible by default, strictly #![forbid(unsafe_code)]
, and verified using differential fuzzing.
Three APIs:
Strives for two properties:
Maximal safety: strong memory safety guarantees.
unsafe
(no raw pointer dereference, etc.).debug_assert!
for logical invariants exercised in testing.Rc<RefCell<T>>
's runtime check).Minimal footprint: small binary with low resource use.
Other features:
Ord
trait.SGMap
non-exhaustive API example (would work identically for std::collections::BTreeMap
):
```rust use scapegoat::SGMap;
let mut example = SGMap::new();
example.insert(3, String::from("the")); example.insert(2, String::from("don't blame")); example.insert(1, String::from("Please")); example.insert(4, String::from("borrow checker"));
asserteq!(
example.iter().map(|(, v)| v).collect::
assert_eq!(example[&3], "the");
let pleasetuple = example.popfirst().unwrap(); asserteq!(pleasetuple, (1, String::from("Please")));
example.insert(5, String::from("! :P"));
let dontblame = example.getmut(&2).unwrap(); dontblame.remove(0); dontblame.insert(0, 'D');
asserteq!(
example.intoiter().map(|(_, v)| v).collect::
The maximum number of stack-stored elements (set) or key-value pairs (map/tree) is determined at compile-time, via the environment variable SG_MAX_STACK_ELEMS
.
Valid values are in the range [0, 32]
and powers of 2 up to 1,048,576
.
For example, to store up to 2048
items on the stack:
bash
export SG_MAX_STACK_ELEMS=2048
cargo build --release
Please note:
SG_MAX_STACK_ELEMS
environment variable is not set, it will default to 1024
.SG_MAX_STACK_ELEMS
is a hard maximum - attempting to insert beyond this limit will cause a panic.SG_MAX_STACK_ELEMS
elements are stack-allocated and the remainder will be automatically heap-allocated (no panic).This library has two dependencies, each of which have no dependencies of their own (e.g. exactly two total dependencies). Both dependencies were carefully chosen.
smallvec
- !#[no_std]
compatible Vec
alternative. Used in Mozilla's Servo browser engine.libm
- !#[no_std]
compatible math operations. Maintained by the Rust Language Team.This project is an exercise in safe data structure design.
It's not as mature, fast, or memory efficient as the standard library's BTreeMap
/BTreeSet
.
It does, however, offer:
* Best-effort Compatibility: APIs are a subset of BTreeMap
's/BTreeSet
's, making it a somewhat "drop-in" replacement for !#[no_std]
systems. Please open an issue if an API you need isn't yet supported!
* Dynamic Verification: Coverage-guided differential fuzzing is used to verify that this implementation is logically equivalent and equally reliable.