persistent_stack/lib.rs
1use std::sync::Arc;
2
3struct PersistentStackNode<T> {
4 data: T,
5 parent: Option<Arc<PersistentStackNode<T>>>,
6}
7
8/// # Concurrent persistent stack
9/// Supportted operations:
10/// - clone *O*(1)
11/// - push *O*(1)
12/// - pop *O*(1)
13/// - iterate *O*(n)
14///
15/// ```rust
16/// use persistent_stack::PersistentStack;
17///
18/// let mut s1 = PersistentStack::new();
19/// s1.push(1);
20/// let mut s2 = s1.clone();
21/// std::thread::spawn(move || {
22/// s2.push(2);
23/// assert_eq!(s2.iter().copied().collect::<Vec<_>>(), vec![2, 1]);
24/// std::thread::sleep(std::time::Duration::from_millis(20));
25/// s2.push(4);
26/// assert_eq!(s2.iter().copied().collect::<Vec<_>>(), vec![4, 2, 1]);
27/// });
28/// s1.push(3);
29/// assert_eq!(s1.iter().copied().collect::<Vec<_>>(), vec![3, 1]);
30/// std::thread::sleep(std::time::Duration::from_millis(20));
31/// s1.push(5);
32/// assert_eq!(s1.iter().copied().collect::<Vec<_>>(), vec![5, 3, 1]);
33/// ```
34pub struct PersistentStack<T>(Option<Arc<PersistentStackNode<T>>>);
35
36impl<T> Default for PersistentStack<T> {
37 fn default() -> PersistentStack<T> {
38 PersistentStack(None)
39 }
40}
41
42impl<T> Clone for PersistentStack<T> {
43 fn clone(&self) -> Self {
44 PersistentStack(self.0.as_ref().map(|x| Arc::clone(x)))
45 }
46}
47
48#[derive(Debug, Clone, Copy, Eq, PartialEq)]
49pub enum PersistentStackPopError {
50 CantUnwrap,
51 RootIsReached,
52}
53
54impl<T> PersistentStack<T> {
55 /// Creates new empty persistent stack
56 ///
57 /// ```rust
58 /// use persistent_stack::PersistentStack;
59 ///
60 /// let s = PersistentStack::<i32>::new();
61 /// assert!(s.into_iter().next().is_none())
62 /// ```
63 pub fn new() -> PersistentStack<T> {
64 Self::default()
65 }
66
67 /// Pushes `data` to end of `self` (affects only current copy of stack)
68 ///
69 /// ```rust
70 /// use persistent_stack::PersistentStack;
71 /// use std::sync::Arc;
72 ///
73 /// let mut s1 = PersistentStack::new();
74 /// s1.push(1);
75 /// let mut s2 = s1.clone();
76 /// s2.push(2);
77 /// assert_eq!(s1.into_iter().collect::<Vec<_>>(), [&1]);
78 /// assert_eq!(s2.into_iter().collect::<Vec<_>>(), [&2, &1]);
79 pub fn push(&mut self, data: T) {
80 let node = PersistentStackNode {
81 data,
82 parent: self.0.as_ref().map(|x| Arc::clone(x)),
83 };
84 *self = PersistentStack(Some(Arc::new(node)));
85 }
86
87 /// Pops value from stack and tries to return it
88 ///
89 /// Returns `Ok(data)` if only this copy of stack owned `data`
90 ///
91 /// Returns `Err(CantUnwrap)` if there are other copies, which own `data`
92 ///
93 /// Returns `Err(RootIsReached)` if nothing to pop
94 ///
95 /// ```rust
96 /// use persistent_stack::{PersistentStack, PersistentStackPopError::*};
97 ///
98 /// let mut s1 = PersistentStack::new();
99 /// s1.push(1);
100 /// s1.push(2);
101 /// let mut s2 = s1.clone();
102 /// s1.push(3);
103 /// s2.push(4);
104 /// assert_eq!(s2.pop(), Ok(4)); // only s2 owned 4
105 /// assert_eq!(s2.pop(), Err(CantUnwrap)); // s1 also owns 2
106 /// let mut s3 = s2.clone();
107 /// assert_eq!(s2.pop(), Err(CantUnwrap)); // s1 also owns 1
108 /// assert_eq!(s2.pop(), Err(RootIsReached)); // There are no elements in s2
109 /// s3.push(5);
110 /// assert_eq!(s3.iter().copied().collect::<Vec<_>>(), vec![5, 1]); // s3 is cloned, when s2 was [1]
111 pub fn pop(&mut self) -> Result<T, PersistentStackPopError> {
112 let s = self.0.take();
113 s.map(|node| {
114 self.0 = node.parent.as_ref().cloned();
115 Arc::try_unwrap(node)
116 .map(|node| node.data)
117 .map_err(|_| PersistentStackPopError::CantUnwrap)
118 })
119 .unwrap_or(Err(PersistentStackPopError::RootIsReached))
120 }
121
122 /// Creates iterator over `self` by reference
123 ///
124 /// ```rust
125 /// use persistent_stack::PersistentStack;
126 ///
127 /// let mut s = PersistentStack::new();
128 /// s.push(1);
129 /// s.push(2);
130 /// s.push(3);
131 /// assert_eq!(s.iter().collect::<Vec<_>>(), [&3, &2, &1]);
132 /// s.push(4); // s didn't move out
133 pub fn iter(&self) -> PersistentStackIter<T> {
134 PersistentStackIter(self.0.as_deref())
135 }
136}
137
138/// Iterator over persistent stack
139pub struct PersistentStackIter<'a, T>(Option<&'a PersistentStackNode<T>>);
140
141impl<'a, T> IntoIterator for &'a PersistentStack<T> {
142 type IntoIter = PersistentStackIter<'a, T>;
143 type Item = &'a T;
144
145 fn into_iter(self) -> Self::IntoIter {
146 PersistentStackIter(self.0.as_deref())
147 }
148}
149
150impl<'a, T> Iterator for PersistentStackIter<'a, T> {
151 type Item = &'a T;
152
153 fn next(&mut self) -> Option<Self::Item> {
154 self.0.map(|node| {
155 self.0 = node.parent.as_deref();
156 &node.data
157 })
158 }
159}
160
161mod tests {
162 #[test]
163 fn test_persistent_stack() {
164 let mut s1 = crate::PersistentStack::new();
165 s1.push(1);
166 s1.push(2);
167 let mut s2 = s1.clone();
168 s1.push(3);
169 s2.push(4);
170 assert_eq!(s1.into_iter().map(|x| *x).collect::<Vec<_>>(), [3, 2, 1]);
171 assert_eq!(s2.into_iter().map(|x| *x).collect::<Vec<_>>(), [4, 2, 1]);
172 }
173
174 #[test]
175 fn readme_example() {
176 use crate::PersistentStack;
177
178 let mut s1 = PersistentStack::new();
179 s1.push(1);
180
181 let mut s2 = s1.clone(); // O(1) operation
182
183 std::thread::spawn(move || {
184 s2.push(2); // PersistentStack values can be shared safely
185 assert_eq!(s2.iter().copied().collect::<Vec<_>>(), vec![2, 1]);
186
187 std::thread::sleep(std::time::Duration::from_millis(20));
188
189 s2.push(4);
190 assert_eq!(s2.iter().copied().collect::<Vec<_>>(), vec![4, 2, 1]);
191
192 assert_eq!(s2.pop(), Ok(4)); // We can also pop values from stack
193 });
194
195 s1.push(3);
196 assert_eq!(s1.iter().copied().collect::<Vec<_>>(), vec![3, 1]);
197
198 std::thread::sleep(std::time::Duration::from_millis(20));
199
200 s1.push(5);
201 assert_eq!(s1.iter().copied().collect::<Vec<_>>(), vec![5, 3, 1]);
202 }
203}