use std::rc::Rc;
const BRANCHING: usize = 32;
const BITS: usize = 5;
const MASK: usize = BRANCHING - 1;
#[derive(Clone)]
enum RrbNode {
Leaf(Vec<u64>),
Internal(Vec<Rc<RrbNode>>),
}
impl RrbNode {
fn get(&self, index: usize, height: usize) -> Option<u64> {
match self {
RrbNode::Leaf(data) => data.get(index).copied(),
RrbNode::Internal(children) => {
let shift = height * BITS;
let child_idx = (index >> shift) & MASK;
let remainder = index & ((1 << shift) - 1);
children
.get(child_idx)
.and_then(|c| c.get(remainder, height - 1))
}
}
}
fn update(&self, index: usize, value: u64, height: usize) -> Option<Rc<RrbNode>> {
match self {
RrbNode::Leaf(data) => {
if index >= data.len() {
return None;
}
let mut new_data = data.clone();
new_data[index] = value;
Some(Rc::new(RrbNode::Leaf(new_data)))
}
RrbNode::Internal(children) => {
let shift = height * BITS;
let child_idx = (index >> shift) & MASK;
let remainder = index & ((1 << shift) - 1);
let new_child = children
.get(child_idx)
.and_then(|c| c.update(remainder, value, height - 1))?;
let mut new_children = children.clone();
new_children[child_idx] = new_child;
Some(Rc::new(RrbNode::Internal(new_children)))
}
}
}
fn collect(&self, out: &mut Vec<u64>) {
match self {
RrbNode::Leaf(data) => out.extend_from_slice(data),
RrbNode::Internal(children) => {
for c in children {
c.collect(out);
}
}
}
}
}
#[derive(Clone)]
pub struct RrbVec {
root: Option<Rc<RrbNode>>,
length: usize,
height: usize,
}
impl Default for RrbVec {
fn default() -> Self {
Self::new()
}
}
impl std::fmt::Debug for RrbVec {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("RrbVec")
.field("length", &self.length)
.field("height", &self.height)
.finish()
}
}
impl RrbVec {
pub fn new() -> Self {
RrbVec {
root: None,
length: 0,
height: 0,
}
}
pub fn from_slice(data: &[u64]) -> Self {
let mut v = RrbVec::new();
for &x in data {
v = v.push_back(x);
}
v
}
pub fn len(&self) -> usize {
self.length
}
pub fn is_empty(&self) -> bool {
self.length == 0
}
pub fn get(&self, index: usize) -> Option<u64> {
if index >= self.length {
return None;
}
self.root.as_ref().and_then(|r| r.get(index, self.height))
}
pub fn push_back(&self, value: u64) -> Self {
let new_root = match &self.root {
None => {
Rc::new(RrbNode::Leaf(vec![value]))
}
Some(root) => {
match push_node(root, self.length, self.height, value) {
PushResult::Inserted(new_root) => new_root,
PushResult::NeedsNewRoot(sibling) => {
Rc::new(RrbNode::Internal(vec![Rc::clone(root), sibling]))
}
}
}
};
RrbVec {
root: Some(new_root),
length: self.length + 1,
height: if self.root.is_none() {
0
} else {
new_height_after_push(self.length + 1, self.height)
},
}
}
pub fn update(&self, index: usize, value: u64) -> Option<Self> {
if index >= self.length {
return None;
}
let new_root = self
.root
.as_ref()
.and_then(|r| r.update(index, value, self.height))?;
Some(RrbVec {
root: Some(new_root),
length: self.length,
height: self.height,
})
}
pub fn iter(&self) -> RrbVecIter<'_> {
RrbVecIter { vec: self, pos: 0 }
}
pub fn to_vec(&self) -> Vec<u64> {
let mut out = Vec::with_capacity(self.length);
if let Some(root) = &self.root {
root.collect(&mut out);
}
out
}
}
pub struct RrbVecIter<'a> {
vec: &'a RrbVec,
pos: usize,
}
impl<'a> Iterator for RrbVecIter<'a> {
type Item = u64;
fn next(&mut self) -> Option<Self::Item> {
if self.pos >= self.vec.length {
return None;
}
let val = self.vec.get(self.pos);
self.pos += 1;
val
}
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = self.vec.length - self.pos;
(remaining, Some(remaining))
}
}
impl<'a> ExactSizeIterator for RrbVecIter<'a> {}
enum PushResult {
Inserted(Rc<RrbNode>),
NeedsNewRoot(Rc<RrbNode>),
}
fn subtree_capacity(height: usize) -> usize {
BRANCHING.pow((height + 1) as u32)
}
fn push_node(node: &Rc<RrbNode>, length: usize, height: usize, value: u64) -> PushResult {
if height == 0 {
match node.as_ref() {
RrbNode::Leaf(data) => {
if data.len() < BRANCHING {
let mut new_data = data.clone();
new_data.push(value);
PushResult::Inserted(Rc::new(RrbNode::Leaf(new_data)))
} else {
PushResult::NeedsNewRoot(Rc::new(RrbNode::Leaf(vec![value])))
}
}
RrbNode::Internal(_) => unreachable!("height 0 must be a leaf"),
}
} else {
match node.as_ref() {
RrbNode::Internal(children) => {
let child_cap = subtree_capacity(height - 1);
let last_child_idx = if children.is_empty() {
return PushResult::NeedsNewRoot(make_path(height, value));
} else {
children.len() - 1
};
let last_child_len = length - last_child_idx * child_cap;
match push_node(&children[last_child_idx], last_child_len, height - 1, value) {
PushResult::Inserted(new_child) => {
let mut new_children = children.clone();
new_children[last_child_idx] = new_child;
PushResult::Inserted(Rc::new(RrbNode::Internal(new_children)))
}
PushResult::NeedsNewRoot(sibling) => {
if children.len() < BRANCHING {
let mut new_children = children.clone();
new_children.push(sibling);
PushResult::Inserted(Rc::new(RrbNode::Internal(new_children)))
} else {
PushResult::NeedsNewRoot(make_path(height, value))
}
}
}
}
RrbNode::Leaf(_) => unreachable!("height > 0 must be internal"),
}
}
}
fn make_path(height: usize, value: u64) -> Rc<RrbNode> {
if height == 0 {
Rc::new(RrbNode::Leaf(vec![value]))
} else {
Rc::new(RrbNode::Internal(vec![make_path(height - 1, value)]))
}
}
fn new_height_after_push(n: usize, old_height: usize) -> usize {
let mut h = old_height;
while subtree_capacity(h) < n {
h += 1;
}
h
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_empty_vec() {
let v = RrbVec::new();
assert_eq!(v.len(), 0);
assert!(v.is_empty());
assert_eq!(v.get(0), None);
}
#[test]
fn test_push_back_sequential_0_to_99() {
let mut v = RrbVec::new();
for i in 0..100u64 {
v = v.push_back(i);
}
assert_eq!(v.len(), 100);
for i in 0..100u64 {
assert_eq!(v.get(i as usize), Some(i), "mismatch at index {}", i);
}
}
#[test]
fn test_get_after_push() {
let v = RrbVec::new().push_back(42).push_back(99).push_back(7);
assert_eq!(v.get(0), Some(42));
assert_eq!(v.get(1), Some(99));
assert_eq!(v.get(2), Some(7));
assert_eq!(v.get(3), None);
}
#[test]
fn test_update_does_not_modify_original() {
let v1 = RrbVec::from_slice(&[10, 20, 30]);
let v2 = v1.update(1, 999).expect("update failed");
assert_eq!(v1.get(1), Some(20));
assert_eq!(v2.get(1), Some(999));
assert_eq!(v2.get(0), Some(10));
assert_eq!(v2.get(2), Some(30));
}
#[test]
fn test_iter_matches_to_vec() {
let data: Vec<u64> = (0..50).collect();
let v = RrbVec::from_slice(&data);
let from_iter: Vec<u64> = v.iter().collect();
assert_eq!(from_iter, v.to_vec());
assert_eq!(from_iter, data);
}
#[test]
fn test_from_slice_and_iter() {
let data = vec![100u64, 200, 300, 400, 500];
let v = RrbVec::from_slice(&data);
assert_eq!(v.len(), 5);
let out: Vec<u64> = v.iter().collect();
assert_eq!(out, data);
}
#[test]
fn test_large_vector_1000_elements() {
let mut v = RrbVec::new();
for i in 0..1000u64 {
v = v.push_back(i * 3 + 7);
}
assert_eq!(v.len(), 1000);
for i in 0..1000u64 {
let expected = i * 3 + 7;
assert_eq!(v.get(i as usize), Some(expected), "mismatch at {}", i);
}
}
#[test]
fn test_structural_sharing_update_creates_new_vec_original_unchanged() {
let original = RrbVec::from_slice(&[1, 2, 3, 4, 5]);
let updated = original.update(2, 99).expect("update failed");
assert_eq!(updated.get(2), Some(99));
assert_eq!(original.get(2), Some(3));
for i in [0, 1, 3, 4] {
assert_eq!(original.get(i), updated.get(i), "element {} differs", i);
}
}
}