In memory locality aware b+ tree, faster for ordered access.
While developing poly2tri-rs, I need a better datastructure to maintain "Sweeping Front/Advancing Front". It should:
Why not splaytree
Splaytree is binary tree, so it has relative large number of nodes, which is bad for cache locality.
Why not std btree
std::collections::BTreeMap's Cursor support is not stablized yet.
Also I couldn't come up a proper cache mechanism for BTree. BTree's value is stored in all nodes, that makes cache invalidate more frequently.
```rust use sweep_bptree::{BPlusTree, NodeStoreVec};
// create a nodestore with u64
as key, (f64, f64)
as value, inner node size 64, child size 65, leaf node size 64
let mut nodestore = NodeStoreVec::
// insert new value assert!(tree.insert(3, (0., 0.)).is_none());
// update by insert again assert_eq!(tree.insert(3, (1., 1.)).unwrap(), (0., 0.));
// remove the value assert_eq!(tree.remove(&3).unwrap(), (1.0, 1.0));
assert!(tree.is_empty()); ```
``` rust
use sweepbptree::{BPlusTree, NodeStoreVec};
let mut nodestore = NodeStoreVec::
for i in 0..100 { tree.insert(i, (i as f64, i as f64)); }
let cursor0 = tree.cursorfirst().unwrap(); let cursor1 = tree.cursorfirst().unwrap();
// remove the key 0 tree.remove(&0);
// cursor's value should be empty now assert!(cursor0.value(&tree).isnone());
// move to next let cursornext = cursor0.next(&tree).unwrap(); asserteq!(*cursornext.key(), 1); asserteq!(cursornext.value(&tree).unwrap().0, 1.);
// insert a new value to key 0 tree.insert(0, (100., 100.));
// now cursor1 should retrieve the new value asserteq!(cursor_1.value(&tree).unwrap().0, 100.); ```
Data collected on macbook pro m1. NOTE: The underlying code didn't tuned yet, there is a big space to improve.
bash
group base
----- ----
bptree cursor 1000 1.00 6.1±1.18µs ? ?/sec
bptree cursor 10000 1.00 59.3±7.64µs ? ?/sec
bptree insert 1000 1.00 34.0±0.34µs ? ?/sec
bptree insert 10000 1.00 547.4±32.76µs ? ?/sec
bptree iter 1000 1.00 498.5±4.37ns ? ?/sec
bptree iter 10000 1.00 8.7±0.07µs ? ?/sec
bptree ordered_get 1000 1.00 17.9±5.75µs ? ?/sec
bptree ordered_get 10000 1.00 168.7±3.42µs ? ?/sec
bptree random_get 1000 1.00 55.3±5.13µs ? ?/sec
bptree random_get 10000 1.00 1174.1±15.75µs ? ?/sec
bptree remove 1000 1.00 82.9±0.64µs ? ?/sec
bptree remove 10000 1.00 959.4±8.39µs ? ?/sec
btree insert 1000 1.00 50.0±1.00µs ? ?/sec
btree insert 10000 1.00 728.4±12.75µs ? ?/sec
btree iter 1000 1.00 1187.7±9.63ns ? ?/sec
btree iter 10000 1.00 12.6±0.15µs ? ?/sec
btree ordered_get 1000 1.00 42.3±4.07µs ? ?/sec
btree ordered_get 10000 1.00 587.1±15.16µs ? ?/sec
btree random_get 1000 1.00 25.8±5.20µs ? ?/sec
btree random_get 10000 1.00 630.2±6.60µs ? ?/sec
btree remove 1000 1.00 35.4±0.31µs ? ?/sec
btree remove 10000 1.00 413.6±10.69µs ? ?/sec
vec get 1000 1.00 31.2±2.66µs ? ?/sec
vec get 10000 1.00 444.7±5.95µs ? ?/sec
vec insert 1000 1.00 13.2±0.11µs ? ?/sec
vec insert 10000 1.00 202.0±3.64µs ? ?/sec
vec iter 1000 1.00 319.4±2.79ns ? ?/sec
vec iter 10000 1.00 3.1±0.03µs ? ?/sec
vec remove 1000 1.00 405.3±3.57µs ? ?/sec
vec remove 10000 1.00 56.0±0.47ms ? ?/sec