1use std::cmp::Ordering;
19use std::rc::Rc;
20
21type Link<K, V> = Option<Rc<Node<K, V>>>;
22
23struct Node<K, V> {
24 key: K,
25 value: V,
26 priority: u64,
27 left: Link<K, V>,
28 right: Link<K, V>,
29}
30
31pub struct PersistentTreap<K, V> {
32 root: Link<K, V>,
33 len: usize,
34 rng_state: u64,
35}
36
37impl<K: Ord + Clone, V: Clone> PersistentTreap<K, V> {
38 pub fn new(seed: u64) -> Self {
39 Self {
40 root: None,
41 len: 0,
42 rng_state: seed | 1,
43 }
44 }
45
46 pub fn len(&self) -> usize {
47 self.len
48 }
49 pub fn is_empty(&self) -> bool {
50 self.len == 0
51 }
52
53 pub fn insert(&self, key: K, value: V) -> Self {
57 let mut next_rng = self.rng_state;
58 let priority = next_priority(&mut next_rng);
59 let (new_root, replaced) = ins(&self.root, key, value, priority);
60 let len = if replaced { self.len } else { self.len + 1 };
61 Self {
62 root: new_root,
63 len,
64 rng_state: next_rng,
65 }
66 }
67
68 pub fn remove(&self, key: &K) -> Self {
71 let (new_root, removed) = rem(&self.root, key);
72 let len = if removed { self.len - 1 } else { self.len };
73 Self {
74 root: new_root,
75 len,
76 rng_state: self.rng_state,
77 }
78 }
79
80 pub fn get(&self, key: &K) -> Option<&V> {
81 let mut cur = self.root.as_deref();
82 while let Some(node) = cur {
83 match key.cmp(&node.key) {
84 Ordering::Less => cur = node.left.as_deref(),
85 Ordering::Greater => cur = node.right.as_deref(),
86 Ordering::Equal => return Some(&node.value),
87 }
88 }
89 None
90 }
91
92 pub fn collect_in_order(&self) -> Vec<(K, V)> {
93 let mut out = Vec::with_capacity(self.len);
94 in_order(&self.root, &mut out);
95 out
96 }
97}
98
99impl<K, V> Clone for PersistentTreap<K, V> {
100 fn clone(&self) -> Self {
101 Self {
102 root: self.root.clone(),
103 len: self.len,
104 rng_state: self.rng_state,
105 }
106 }
107}
108
109fn next_priority(state: &mut u64) -> u64 {
110 *state = state
111 .wrapping_mul(6364136223846793005)
112 .wrapping_add(1442695040888963407);
113 let mut z = *state;
117 z = (z ^ (z >> 30)).wrapping_mul(0xbf58476d1ce4e5b9);
118 z = (z ^ (z >> 27)).wrapping_mul(0x94d049bb133111eb);
119 z ^ (z >> 31)
120}
121
122fn ins<K: Ord + Clone, V: Clone>(
123 link: &Link<K, V>,
124 key: K,
125 value: V,
126 priority: u64,
127) -> (Link<K, V>, bool) {
128 match link {
129 None => (
130 Some(Rc::new(Node {
131 key,
132 value,
133 priority,
134 left: None,
135 right: None,
136 })),
137 false,
138 ),
139 Some(node) => match key.cmp(&node.key) {
140 Ordering::Equal => (
141 Some(Rc::new(Node {
142 key,
143 value,
144 priority: node.priority,
145 left: node.left.clone(),
146 right: node.right.clone(),
147 })),
148 true,
149 ),
150 Ordering::Less => {
151 let (new_left, replaced) = ins(&node.left, key, value, priority);
152 let new_left_pri = new_left.as_ref().unwrap().priority;
153 let rebuilt = Rc::new(Node {
154 key: node.key.clone(),
155 value: node.value.clone(),
156 priority: node.priority,
157 left: new_left,
158 right: node.right.clone(),
159 });
160 let rooted = if new_left_pri > node.priority {
161 rotate_right(&rebuilt)
162 } else {
163 rebuilt
164 };
165 (Some(rooted), replaced)
166 }
167 Ordering::Greater => {
168 let (new_right, replaced) = ins(&node.right, key, value, priority);
169 let new_right_pri = new_right.as_ref().unwrap().priority;
170 let rebuilt = Rc::new(Node {
171 key: node.key.clone(),
172 value: node.value.clone(),
173 priority: node.priority,
174 left: node.left.clone(),
175 right: new_right,
176 });
177 let rooted = if new_right_pri > node.priority {
178 rotate_left(&rebuilt)
179 } else {
180 rebuilt
181 };
182 (Some(rooted), replaced)
183 }
184 },
185 }
186}
187
188fn rem<K: Ord + Clone, V: Clone>(link: &Link<K, V>, key: &K) -> (Link<K, V>, bool) {
189 match link {
190 None => (None, false),
191 Some(node) => match key.cmp(&node.key) {
192 Ordering::Less => {
193 let (new_left, removed) = rem(&node.left, key);
194 let rebuilt = Rc::new(Node {
195 key: node.key.clone(),
196 value: node.value.clone(),
197 priority: node.priority,
198 left: new_left,
199 right: node.right.clone(),
200 });
201 (Some(rebuilt), removed)
202 }
203 Ordering::Greater => {
204 let (new_right, removed) = rem(&node.right, key);
205 let rebuilt = Rc::new(Node {
206 key: node.key.clone(),
207 value: node.value.clone(),
208 priority: node.priority,
209 left: node.left.clone(),
210 right: new_right,
211 });
212 (Some(rebuilt), removed)
213 }
214 Ordering::Equal => (merge_subtrees(&node.left, &node.right), true),
215 },
216 }
217}
218
219fn merge_subtrees<K: Clone, V: Clone>(left: &Link<K, V>, right: &Link<K, V>) -> Link<K, V> {
220 match (left, right) {
221 (None, r) => r.clone(),
222 (l, None) => l.clone(),
223 (Some(l), Some(r)) => {
224 if l.priority > r.priority {
225 let merged = merge_subtrees(&l.right, right);
226 Some(Rc::new(Node {
227 key: l.key.clone(),
228 value: l.value.clone(),
229 priority: l.priority,
230 left: l.left.clone(),
231 right: merged,
232 }))
233 } else {
234 let merged = merge_subtrees(left, &r.left);
235 Some(Rc::new(Node {
236 key: r.key.clone(),
237 value: r.value.clone(),
238 priority: r.priority,
239 left: merged,
240 right: r.right.clone(),
241 }))
242 }
243 }
244 }
245}
246
247fn rotate_right<K: Clone, V: Clone>(node: &Rc<Node<K, V>>) -> Rc<Node<K, V>> {
248 let left = node.left.as_ref().expect("rotate_right needs left child");
249 let new_right = Rc::new(Node {
250 key: node.key.clone(),
251 value: node.value.clone(),
252 priority: node.priority,
253 left: left.right.clone(),
254 right: node.right.clone(),
255 });
256 Rc::new(Node {
257 key: left.key.clone(),
258 value: left.value.clone(),
259 priority: left.priority,
260 left: left.left.clone(),
261 right: Some(new_right),
262 })
263}
264
265fn rotate_left<K: Clone, V: Clone>(node: &Rc<Node<K, V>>) -> Rc<Node<K, V>> {
266 let right = node.right.as_ref().expect("rotate_left needs right child");
267 let new_left = Rc::new(Node {
268 key: node.key.clone(),
269 value: node.value.clone(),
270 priority: node.priority,
271 left: node.left.clone(),
272 right: right.left.clone(),
273 });
274 Rc::new(Node {
275 key: right.key.clone(),
276 value: right.value.clone(),
277 priority: right.priority,
278 left: Some(new_left),
279 right: right.right.clone(),
280 })
281}
282
283fn in_order<K: Clone, V: Clone>(link: &Link<K, V>, out: &mut Vec<(K, V)>) {
284 if let Some(node) = link {
285 in_order(&node.left, out);
286 out.push((node.key.clone(), node.value.clone()));
287 in_order(&node.right, out);
288 }
289}
290
291#[cfg(test)]
292#[path = "persistent_tests.rs"]
293mod tests;