diff --git a/benches/rpds_vector.rs b/benches/rpds_vector.rs index 4a7fd95..c208fcd 100644 --- a/benches/rpds_vector.rs +++ b/benches/rpds_vector.rs @@ -11,7 +11,10 @@ extern crate rpds; mod utils; +use std::rc::Rc; + use rpds::Vector; +use rpds::sequence::vector::SharedVector; use utils::BencherNoDrop; use utils::iterations; use bencher::{black_box, Bencher}; @@ -30,6 +33,20 @@ fn vector_push_back(bench: &mut Bencher) -> () { }); } +fn vector_push_back_rc(bench: &mut Bencher) -> () { + let limit = iterations(100_000); + + bench.iter_no_drop(|| { + let mut vector: SharedVector> = SharedVector::new(); + + for i in 0..limit { + vector = vector.push_back(i); + } + + vector + }); +} + fn vector_push_back_mut(bench: &mut Bencher) -> () { let limit = iterations(100_000); @@ -44,6 +61,20 @@ fn vector_push_back_mut(bench: &mut Bencher) -> () { }); } +fn vector_push_back_mut_rc(bench: &mut Bencher) -> () { + let limit = iterations(100_000); + + bench.iter_no_drop(|| { + let mut vector: SharedVector> = SharedVector::new(); + + for i in 0..limit { + vector.push_back_mut(i); + } + + vector + }); +} + fn vector_drop_last(bench: &mut Bencher) -> () { let limit = iterations(100_000); let mut full_vector: Vector = Vector::new(); @@ -115,7 +146,9 @@ fn vector_iterate(bench: &mut Bencher) -> () { benchmark_group!( benches, vector_push_back, + vector_push_back_rc, vector_push_back_mut, + vector_push_back_mut_rc, vector_drop_last, vector_drop_last_mut, vector_get, diff --git a/src/sequence/vector/mod.rs b/src/sequence/vector/mod.rs index 37db8e3..170826c 100644 --- a/src/sequence/vector/mod.rs +++ b/src/sequence/vector/mod.rs @@ -13,8 +13,65 @@ use std::ops::Index; use std::iter::FromIterator; use std::mem::size_of; +use std::rc::Rc; +use std::ops::Deref; + +pub trait RefPtr: Clone + Deref { + fn new(value: Self::Target) -> Self; + fn make_mut(self_: &mut Self) -> &mut Self::Target + where + Self::Target: Clone; +} + +impl RefPtr for Rc { + fn new(value: Self::Target) -> Self { + Rc::new(value) + } + fn make_mut(self_: &mut Self) -> &mut Self::Target + where + T: Clone, + { + Rc::make_mut(self_) + } +} + +impl RefPtr for Arc { + fn new(value: Self::Target) -> Self { + Arc::new(value) + } + fn make_mut(self_: &mut Self) -> &mut Self::Target + where + T: Clone, + { + Arc::make_mut(self_) + } +} + +pub trait Shared { + type Ptr: RefPtr; + + fn new(value: ::Target) -> Self::Ptr { + Self::Ptr::new(value) + } + + fn make_mut(self_: &mut Self::Ptr) -> &mut ::Target + where + T: Clone, + { + Self::Ptr::make_mut(self_) + } +} + +impl Shared for Rc<()> { + type Ptr = Rc; +} + +impl Shared for Arc<()> { + type Ptr = Arc; +} + // TODO Use impl trait instead of this when available. -pub type Iter<'a, T> = ::std::iter::Map, fn(&Arc) -> &T>; +pub type Iter<'a, T, P> = ::std::iter::Map, fn(&

>::Ptr) -> &T>; const DEFAULT_BITS: u8 = 5; @@ -91,25 +148,70 @@ macro_rules! vector { /// This vector is implemented as described in /// [Understanding Persistent Vector Part 1](http://hypirion.com/musings/understanding-persistent-vector-pt-1) /// and [Understanding Persistent Vector Part 2](http://hypirion.com/musings/understanding-persistent-vector-pt-2). -#[derive(Debug)] -pub struct Vector { - root: Arc>, +pub struct SharedVector +where + P: Shared> + Shared, +{ + root:

>>::Ptr, bits: u8, length: usize, } -#[derive(Debug, PartialEq, Eq)] -enum Node { - Branch(Vec>>), - Leaf(Vec>), +impl ::std::fmt::Debug for SharedVector +where + P: Shared> + Shared, + T: ::std::fmt::Debug, +{ + fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + unimplemented!() + } +} + +pub type Vector = SharedVector>; + +#[doc(hidden)] +pub enum Node +where + P: Shared> + Shared, +{ + Branch(Vec<

>>::Ptr>), + Leaf(Vec<

>::Ptr>), +} + +impl ::std::fmt::Debug for Node +where + P: Shared> + Shared, + T: Display, +{ + fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + unimplemented!() + } +} + +impl Eq for Node +where + P: Shared> + Shared, +{ +} + +impl PartialEq for Node +where + P: Shared> + Shared, +{ + fn eq(&self, other: &Node) -> bool { + unimplemented!() + } } -impl Node { - fn new_empty_branch() -> Node { +impl Node +where + P: Shared> + Shared, +{ + fn new_empty_branch() -> Node { Node::Branch(Vec::new()) } - fn new_empty_leaf() -> Node { + fn new_empty_leaf() -> Node { Node::Leaf(Vec::new()) } @@ -120,7 +222,7 @@ impl Node { Node::Branch(ref a) => a[b].get(index, height - 1, bucket), Node::Leaf(ref a) => { debug_assert_eq!(height, 0); - a[b].as_ref() + &a[b] } } } @@ -132,10 +234,11 @@ impl Node { Node::Leaf(ref mut a) => { debug_assert_eq!(height, 0, "cannot have a leaf at this height"); + let value =

>::new(value); if a.len() == b { - a.push(Arc::new(value)); + a.push(value); } else { - a[b] = Arc::new(value); + a[b] = value; } } @@ -143,7 +246,7 @@ impl Node { debug_assert!(height > 0, "cannot have a branch at this height"); if let Some(subtree) = a.get_mut(b) { - Arc::make_mut(subtree).assoc(value, height - 1, bucket); +

>>::make_mut(subtree).assoc(value, height - 1, bucket); return; } let mut subtree = if height > 1 { @@ -153,7 +256,7 @@ impl Node { }; subtree.assoc(value, height - 1, bucket); - a.push(Arc::new(subtree)); + a.push(

>>::new(subtree)); } } } @@ -190,12 +293,14 @@ impl Node { a.pop(); } - Node::Branch(ref mut a) => match Arc::make_mut(a.last_mut().unwrap()).drop_last() { - Some(()) => (), - None => { - a.pop(); + Node::Branch(ref mut a) => { + match

>>::Ptr::make_mut(a.last_mut().unwrap()).drop_last() { + Some(()) => (), + None => { + a.pop(); + } } - }, + } } if self.is_empty() { @@ -206,8 +311,11 @@ impl Node { } } -impl Clone for Node { - fn clone(&self) -> Node { +impl Clone for Node +where + P: Shared> + Shared, +{ + fn clone(&self) -> Node { match *self { Node::Branch(ref a) => Node::Branch(Vec::clone(a)), Node::Leaf(ref a) => Node::Leaf(Vec::clone(a)), @@ -215,16 +323,19 @@ impl Clone for Node { } } -impl Vector { - pub fn new() -> Vector { - Vector::new_with_bits(DEFAULT_BITS) +impl SharedVector +where + P: Shared> + Shared, +{ + pub fn new() -> SharedVector { + SharedVector::new_with_bits(DEFAULT_BITS) } - pub fn new_with_bits(bits: u8) -> Vector { + pub fn new_with_bits(bits: u8) -> SharedVector { assert!(bits > 0, "number of bits for the vector must be positive"); - Vector { - root: Arc::new(Node::new_empty_leaf()), + SharedVector { + root:

>>::new(Node::new_empty_leaf()), bits, length: 0, } @@ -285,7 +396,7 @@ impl Vector { } } - pub fn set(&self, index: usize, v: T) -> Option> { + pub fn set(&self, index: usize, v: T) -> Option> { let mut self_ = self.clone(); self_.set_mut(index, v).map(|()| self_) } @@ -312,7 +423,8 @@ impl Vector { let height = self.height(); let bits = self.bits; - Arc::make_mut(&mut self.root).assoc(v, height, |height| Self::bucket2(bits, index, height)); +

>>::make_mut(&mut self.root) + .assoc(v, height, |height| Self::bucket2(bits, index, height)); let adds_item: bool = index >= self.length; self.bits = bits; @@ -336,7 +448,7 @@ impl Vector { self.length == self.root_max_capacity() } - pub fn push_back(&self, v: T) -> Vector { + pub fn push_back(&self, v: T) -> SharedVector { let mut self_ = self.clone(); self_.push_back_mut(v); self_ @@ -344,15 +456,15 @@ impl Vector { pub fn push_back_mut(&mut self, v: T) { if self.is_root_full() { - let mut new_root: Node = Node::new_empty_branch(); + let mut new_root: Node = Node::new_empty_branch(); match new_root { - Node::Branch(ref mut values) => values.push(Arc::clone(&self.root)), + Node::Branch(ref mut values) => values.push(self.root.clone()), _ => unreachable!("expected a branch"), } let length = self.length; - self.root = Arc::new(new_root); + self.root =

>>::new(new_root); self.length += 1; self.assoc(length, v) @@ -367,14 +479,14 @@ impl Vector { /// /// The trie must always have a compressed root. #[cfg(test)] - fn compress_root(mut root: Node) -> Arc> { + fn compress_root(mut root: Node) ->

>>::Ptr { match Self::compress_root_mut(&mut root) { Some(new_root) => new_root, - None => Arc::new(root), + None =>

>>::new(root), } } - fn compress_root_mut(root: &mut Node) -> Option>> { + fn compress_root_mut(root: &mut Node) -> Option<

>>::Ptr> { match *root { Node::Leaf(_) => None, Node::Branch(_) => if root.is_singleton() { @@ -389,7 +501,7 @@ impl Vector { } } - pub fn drop_last(&self) -> Option> { + pub fn drop_last(&self) -> Option> { let mut self_ = self.clone(); self_.drop_last_mut().map(|()| self_) } @@ -400,10 +512,10 @@ impl Vector { } let new_root = { - let root = Arc::make_mut(&mut self.root); + let root =

>>::make_mut(&mut self.root); root.drop_last(); self.length -= 1; - Vector::compress_root_mut(root) + SharedVector::compress_root_mut(root) }; if let Some(new_root) = new_root { @@ -423,16 +535,19 @@ impl Vector { self.len() == 0 } - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter { self.iter_arc().map(|v| v.borrow()) } - fn iter_arc(&self) -> IterArc { + fn iter_arc(&self) -> IterArc { IterArc::new(self) } } -impl Index for Vector { +impl Index for SharedVector +where + P: Shared> + Shared, +{ type Output = T; fn index(&self, index: usize) -> &T { @@ -441,33 +556,52 @@ impl Index for Vector { } } -impl Default for Vector { - fn default() -> Vector { - Vector::new() +impl Default for SharedVector +where + P: Shared> + Shared, +{ + fn default() -> SharedVector { + Self::new() } } -impl PartialEq for Vector { - fn eq(&self, other: &Vector) -> bool { +impl PartialEq for SharedVector +where + P: Shared> + Shared, +{ + fn eq(&self, other: &SharedVector) -> bool { self.length == other.length && self.iter().eq(other.iter()) } } -impl Eq for Vector {} +impl Eq for SharedVector +where + P: Shared> + Shared, +{ +} -impl> PartialOrd> for Vector { - fn partial_cmp(&self, other: &Vector) -> Option { +impl PartialOrd for SharedVector +where + P: Shared> + Shared, +{ + fn partial_cmp(&self, other: &SharedVector) -> Option { self.iter().partial_cmp(other.iter()) } } -impl Ord for Vector { - fn cmp(&self, other: &Vector) -> Ordering { +impl Ord for SharedVector +where + P: Shared> + Shared, +{ + fn cmp(&self, other: &SharedVector) -> Ordering { self.iter().cmp(other.iter()) } } -impl Hash for Vector { +impl Hash for SharedVector +where + P: Shared> + Shared, +{ fn hash(&self, state: &mut H) -> () { // Add the hash of length so that if two collections are added one after the other it doesn't // hash to the same thing as a single collection with the same elements in the same order. @@ -479,19 +613,23 @@ impl Hash for Vector { } } -impl Clone for Vector { - fn clone(&self) -> Vector { - Vector { - root: Arc::clone(&self.root), +impl Clone for SharedVector +where + P: Shared> + Shared, +{ + fn clone(&self) -> SharedVector { + SharedVector { + root: self.root.clone(), bits: self.bits, length: self.length, } } } -impl Display for Vector +impl Display for SharedVector where T: Display, + P: Shared> + Shared, { fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { let mut first = true; @@ -510,24 +648,33 @@ where } } -impl<'a, T> IntoIterator for &'a Vector { +impl<'a, T, P> IntoIterator for &'a SharedVector +where + P: Shared> + Shared, +{ type Item = &'a T; - type IntoIter = Iter<'a, T>; + type IntoIter = Iter<'a, T, P>; - fn into_iter(self) -> Iter<'a, T> { + fn into_iter(self) -> Iter<'a, T, P> { self.iter() } } -impl FromIterator for Vector { - fn from_iter>(into_iter: I) -> Vector { - let mut vector = Vector::new(); +impl FromIterator for SharedVector +where + P: Shared> + Shared, +{ + fn from_iter>(into_iter: I) -> SharedVector { + let mut vector = SharedVector::new(); vector.extend(into_iter); vector } } -impl Extend for Vector { +impl Extend for SharedVector +where + P: Shared> + Shared, +{ fn extend>(&mut self, iter: I) { for elem in iter { self.push_back_mut(elem); @@ -535,23 +682,32 @@ impl Extend for Vector { } } -pub struct IterArc<'a, T: 'a> { - vector: &'a Vector, +pub struct IterArc<'a, T: 'a, P> +where + P: Shared> + Shared + 'a, +{ + vector: &'a SharedVector, - stack_forward: Option>>, - stack_backward: Option>>, + stack_forward: Option>>, + stack_backward: Option>>, left_index: usize, // inclusive right_index: usize, // exclusive } -struct IterStackElement<'a, T: 'a> { - node: &'a Node, +struct IterStackElement<'a, T: 'a, P> +where + P: Shared> + Shared + 'a, +{ + node: &'a Node, index: isize, } -impl<'a, T> IterStackElement<'a, T> { - fn new(node: &Node, backwards: bool) -> IterStackElement { +impl<'a, T, P> IterStackElement<'a, T, P> +where + P: Shared> + Shared, +{ + fn new(node: &Node, backwards: bool) -> IterStackElement { IterStackElement { node, index: if backwards { @@ -562,14 +718,14 @@ impl<'a, T> IterStackElement<'a, T> { } } - fn current_node(&self) -> &'a Node { + fn current_node(&self) -> &'a Node { match *self.node { - Node::Branch(ref a) => a[self.index as usize].as_ref(), + Node::Branch(ref a) => &a[self.index as usize], Node::Leaf(_) => panic!("called current node of a branch"), } } - fn current_elem(&self) -> &'a Arc { + fn current_elem(&self) -> &'a

>::Ptr { match *self.node { Node::Leaf(ref a) => &a[self.index as usize], Node::Branch(_) => panic!("called current element of a branch"), @@ -589,8 +745,11 @@ impl<'a, T> IterStackElement<'a, T> { } } -impl<'a, T> IterArc<'a, T> { - fn new(vector: &Vector) -> IterArc { +impl<'a, T, P> IterArc<'a, T, P> +where + P: Shared> + Shared, +{ + fn new(vector: &SharedVector) -> IterArc { IterArc { vector, @@ -602,8 +761,8 @@ impl<'a, T> IterArc<'a, T> { } } - fn dig(stack: &mut Vec>, backwards: bool) -> () { - let next_node: &Node = { + fn dig(stack: &mut Vec>, backwards: bool) -> () { + let next_node: &Node = { let stack_top = stack.last().unwrap(); if let Node::Leaf(_) = *stack_top.node { @@ -626,7 +785,8 @@ impl<'a, T> IterArc<'a, T> { }; if stack_field.is_none() { - let mut stack: Vec> = Vec::with_capacity(self.vector.height() + 1); + let mut stack: Vec> = + Vec::with_capacity(self.vector.height() + 1); stack.push(IterStackElement::new(self.vector.root.borrow(), backwards)); @@ -636,7 +796,7 @@ impl<'a, T> IterArc<'a, T> { } } - fn advance(stack: &mut Vec>, backwards: bool) -> () { + fn advance(stack: &mut Vec>, backwards: bool) -> () { match stack.pop() { Some(mut stack_element) => { let finished = stack_element.advance(backwards); @@ -654,7 +814,7 @@ impl<'a, T> IterArc<'a, T> { } #[inline] - fn current(stack: &[IterStackElement<'a, T>]) -> Option<&'a Arc> { + fn current(stack: &[IterStackElement<'a, T, P>]) -> Option<&'a

>::Ptr> { stack.last().map(|e| e.current_elem()) } @@ -671,7 +831,7 @@ impl<'a, T> IterArc<'a, T> { } } - fn current_forward(&self) -> Option<&'a Arc> { + fn current_forward(&self) -> Option<&'a

>::Ptr> { if self.non_empty() { IterArc::current(self.stack_forward.as_ref().unwrap()) } else { @@ -687,7 +847,7 @@ impl<'a, T> IterArc<'a, T> { } } - fn current_backward(&self) -> Option<&'a Arc> { + fn current_backward(&self) -> Option<&'a

>::Ptr> { if self.non_empty() { IterArc::current(self.stack_backward.as_ref().unwrap()) } else { @@ -696,10 +856,13 @@ impl<'a, T> IterArc<'a, T> { } } -impl<'a, T> Iterator for IterArc<'a, T> { - type Item = &'a Arc; +impl<'a, T, P> Iterator for IterArc<'a, T, P> +where + P: Shared> + Shared, +{ + type Item = &'a

>::Ptr; - fn next(&mut self) -> Option<&'a Arc> { + fn next(&mut self) -> Option<&'a

>::Ptr> { self.init_if_needed(false); let current = self.current_forward(); @@ -716,8 +879,11 @@ impl<'a, T> Iterator for IterArc<'a, T> { } } -impl<'a, T> DoubleEndedIterator for IterArc<'a, T> { - fn next_back(&mut self) -> Option<&'a Arc> { +impl<'a, T, P> DoubleEndedIterator for IterArc<'a, T, P> +where + P: Shared> + Shared, +{ + fn next_back(&mut self) -> Option<&'a

>::Ptr> { self.init_if_needed(true); let current = self.current_backward(); @@ -728,7 +894,11 @@ impl<'a, T> DoubleEndedIterator for IterArc<'a, T> { } } -impl<'a, T> ExactSizeIterator for IterArc<'a, T> {} +impl<'a, T, P> ExactSizeIterator for IterArc<'a, T, P> +where + P: Shared> + Shared, +{ +} #[cfg(feature = "serde")] pub mod serde { @@ -738,7 +908,7 @@ pub mod serde { use std::marker::PhantomData; use std::fmt; - impl Serialize for Vector + impl Serialize for SharedVector where T: Serialize, { @@ -747,11 +917,11 @@ pub mod serde { } } - impl<'de, T> Deserialize<'de> for Vector + impl<'de, T, P> Deserialize<'de> for SharedVector where T: Deserialize<'de>, { - fn deserialize>(deserializer: D) -> Result, D::Error> { + fn deserialize>(deserializer: D) -> Result, D::Error> { deserializer.deserialize_seq(VectorVisitor { phantom: PhantomData, }) @@ -766,17 +936,17 @@ pub mod serde { where T: Deserialize<'de>, { - type Value = Vector; + type Value = SharedVector; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a sequence") } - fn visit_seq(self, mut seq: A) -> Result, A::Error> + fn visit_seq(self, mut seq: A) -> Result, A::Error> where A: SeqAccess<'de>, { - let mut vector = Vector::new(); + let mut vector = SharedVector::new(); while let Some(value) = seq.next_element()? { vector.push_back_mut(value); diff --git a/src/sequence/vector/test.rs b/src/sequence/vector/test.rs index a990d62..0e3945e 100644 --- a/src/sequence/vector/test.rs +++ b/src/sequence/vector/test.rs @@ -10,7 +10,7 @@ mod node { #[test] fn test_new_empty_branch() -> () { - let node: Node = Node::new_empty_branch(); + let node: Node> = Node::new_empty_branch(); match node { Node::Branch(a) => { @@ -23,7 +23,7 @@ mod node { #[test] fn test_new_empty_leaf() -> () { - let node: Node = Node::new_empty_leaf(); + let node: Node> = Node::new_empty_leaf(); match node { Node::Leaf(a) => { @@ -36,10 +36,10 @@ mod node { #[test] fn test_drop_last_single_level() -> () { - let mut empty_leaf: Node = Node::new_empty_leaf(); - let mut empty_branch: Node = Node::new_empty_branch(); - let mut singleton_node: Node = Vector::new().push_back(0).root.as_ref().clone(); - let mut one_level_node: Node = Vector::new() + let mut empty_leaf: Node> = Node::new_empty_leaf(); + let mut empty_branch: Node> = Node::new_empty_branch(); + let mut singleton_node: Node = Vector::new().push_back(0).root.as_ref().clone(); + let mut one_level_node: Node = Vector::new() .push_back(0) .push_back(1) .root @@ -55,14 +55,14 @@ mod node { #[test] fn test_drop_last_multi_level() -> () { - let mut node_three: Node = Vector::new_with_bits(1) + let mut node_three: Node = Vector::new_with_bits(1) .push_back(0) .push_back(1) .push_back(2) .root .as_ref() .clone(); - let mut node_four: Node = Vector::new_with_bits(1) + let mut node_four: Node = Vector::new_with_bits(1) .push_back(0) .push_back(1) .push_back(2) @@ -344,10 +344,10 @@ mod internal { #[test] fn test_compress_root() -> () { - let empty_leaf: Node = Node::new_empty_leaf(); - let empty_branch: Node = Node::new_empty_branch(); - let singleton_leaf: Node = Vector::new().push_back(0).root.as_ref().clone(); - let compressed_branch: Node = Vector::new_with_bits(1) + let empty_leaf: Node = Node::new_empty_leaf(); + let empty_branch: Node = Node::new_empty_branch(); + let singleton_leaf: Node = Vector::new().push_back(0).root.as_ref().clone(); + let compressed_branch: Node = Vector::new_with_bits(1) .push_back(0) .push_back(1) .push_back(3)