1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
pub mod persistent_array { use std::rc::Rc; const N: usize = 20; #[derive(Clone)] pub struct Node<T: Clone> { data: Option<T>, children: [Option<Rc<Node<T>>>; N], } impl<T: Clone> Node<T> { pub fn new(data: Option<T>, children: [Option<Rc<Node<T>>>; N]) -> Self { Self { data, children } } } impl<T: Clone> Default for Node<T> { fn default() -> Self { Self { data: None, children: Default::default(), } } } pub fn set<T: Clone>(index: usize, data: T, node: Option<Rc<Node<T>>>) -> Rc<Node<T>> { if index == 0 { match node { Some(node) => { let new_node = Node::new(Some(data), node.children.clone()); Rc::new(new_node) } None => Rc::new(Node::new(Some(data), Default::default())), } } else { let child = match node .as_ref() .and_then(|node| node.children[index % N].as_ref()) { Some(next_node) => set(index / N, data, Some(next_node.clone())), None => set(index / N, data, None), }; let mut new_node = match node { Some(node) => node.as_ref().clone(), None => Node::default(), }; new_node.children[index % N] = Some(child); Rc::new(new_node) } } pub fn get<T: Clone>(index: usize, node: &Rc<Node<T>>) -> Option<T> { if index == 0 { node.data.clone() } else { match node.children[index % N].as_ref() { Some(next_node) => get(index / N, next_node), None => None, } } } } #[cfg(test)] mod tests { use crate::data_structure::persistent_array::persistent_array::{get, set, Node}; use rand::distributions::Uniform; use rand::{thread_rng, Rng}; use std::rc::Rc; #[test] fn test_persistent_array() { let mut rng = thread_rng(); let n: usize = 20; let mut vs = vec![vec![None; n]]; let mut nodes = vec![Rc::new(Node::default())]; for _ in 0..10000 { let pick = rng.sample(Uniform::from(0..vs.len())); let mut new_vec = vs[pick].clone(); let node = nodes[pick].clone(); let pos = rng.sample(Uniform::from(0..n)); let value: i64 = rng.gen(); new_vec[pos] = Some(value); let new_node = set(pos, value, Some(node)); for i in 0..n { let expected = new_vec[i]; let actual = get(i, &new_node); assert_eq!(expected, actual); } vs.push(new_vec.clone()); nodes.push(new_node.clone()); let value: i64 = rng.gen(); new_vec[pos] = Some(value); let new_node = set(pos, value, Some(new_node)); for i in 0..n { let expected = new_vec[i]; let actual = get(i, &new_node); assert_eq!(expected, actual); } vs.push(new_vec.clone()); nodes.push(new_node); } } }