1use std::cmp::Ordering;
26
27pub(crate) const NIL: u32 = u32::MAX;
28
29pub struct Treap<K, V> {
30 pub(crate) nodes: Vec<Node<K, V>>,
31 free_head: u32,
35 pub(crate) root: u32,
36 len: usize,
37 rng_state: u64,
38}
39
40pub(crate) struct Node<K, V> {
41 pub(crate) key: K,
42 pub(crate) value: V,
43 pub(crate) priority: u64,
44 pub(crate) left: u32,
45 pub(crate) right: u32,
46}
47
48impl<K: Ord, V> Treap<K, V> {
49 pub fn new(seed: u64) -> Self {
50 Self {
51 nodes: Vec::new(),
52 free_head: NIL,
53 root: NIL,
54 len: 0,
55 rng_state: seed | 1,
56 }
57 }
58
59 pub fn with_capacity(seed: u64, capacity: usize) -> Self {
63 Self {
64 nodes: Vec::with_capacity(capacity),
65 free_head: NIL,
66 root: NIL,
67 len: 0,
68 rng_state: seed | 1,
69 }
70 }
71
72 pub fn len(&self) -> usize {
73 self.len
74 }
75 pub fn is_empty(&self) -> bool {
76 self.len == 0
77 }
78
79 pub fn insert(&mut self, key: K, value: V) -> Option<V> {
80 let priority = self.next_priority();
81 let (new_root, replaced) = self.ins(self.root, key, value, priority);
82 self.root = new_root;
83 if replaced.is_none() {
84 self.len += 1;
85 }
86 replaced
87 }
88
89 pub fn get(&self, key: &K) -> Option<&V> {
90 let mut cur = self.root;
91 while cur != NIL {
92 let node = &self.nodes[cur as usize];
93 match key.cmp(&node.key) {
94 Ordering::Less => cur = node.left,
95 Ordering::Greater => cur = node.right,
96 Ordering::Equal => return Some(&node.value),
97 }
98 }
99 None
100 }
101
102 pub fn remove(&mut self, key: &K) -> Option<V> {
103 let (new_root, removed) = self.rem(self.root, key);
104 self.root = new_root;
105 if removed.is_some() {
106 self.len -= 1;
107 }
108 removed
109 }
110
111 pub fn collect_in_order(&self) -> Vec<(&K, &V)> {
113 let mut out = Vec::with_capacity(self.len);
114 self.in_order(self.root, &mut out);
115 out
116 }
117
118 fn next_priority(&mut self) -> u64 {
119 self.rng_state = self
121 .rng_state
122 .wrapping_mul(6364136223846793005)
123 .wrapping_add(1442695040888963407);
124 let mut z = self.rng_state;
132 z = (z ^ (z >> 30)).wrapping_mul(0xbf58476d1ce4e5b9);
133 z = (z ^ (z >> 27)).wrapping_mul(0x94d049bb133111eb);
134 z ^ (z >> 31)
135 }
136
137 fn alloc(&mut self, key: K, value: V, priority: u64) -> u32 {
138 if self.free_head != NIL {
139 let idx = self.free_head;
140 let slot = &mut self.nodes[idx as usize];
141 self.free_head = slot.left;
143 slot.key = key;
144 slot.value = value;
145 slot.priority = priority;
146 slot.left = NIL;
147 slot.right = NIL;
148 idx
149 } else {
150 let idx = self.nodes.len() as u32;
151 self.nodes.push(Node {
152 key,
153 value,
154 priority,
155 left: NIL,
156 right: NIL,
157 });
158 idx
159 }
160 }
161
162 fn free(&mut self, idx: u32) {
163 self.nodes[idx as usize].left = self.free_head;
164 self.free_head = idx;
165 }
166
167 fn ins(&mut self, root: u32, key: K, value: V, priority: u64) -> (u32, Option<V>) {
168 if root == NIL {
169 return (self.alloc(key, value, priority), None);
170 }
171 let cmp = key.cmp(&self.nodes[root as usize].key);
172 match cmp {
173 Ordering::Equal => {
174 let old = std::mem::replace(&mut self.nodes[root as usize].value, value);
175 (root, Some(old))
176 }
177 Ordering::Less => {
178 let left = self.nodes[root as usize].left;
179 let (new_left, replaced) = self.ins(left, key, value, priority);
180 self.nodes[root as usize].left = new_left;
181 let new_left_pri = self.nodes[new_left as usize].priority;
182 let root_pri = self.nodes[root as usize].priority;
183 let r = if new_left_pri > root_pri {
184 self.rotate_right(root)
185 } else {
186 root
187 };
188 (r, replaced)
189 }
190 Ordering::Greater => {
191 let right = self.nodes[root as usize].right;
192 let (new_right, replaced) = self.ins(right, key, value, priority);
193 self.nodes[root as usize].right = new_right;
194 let new_right_pri = self.nodes[new_right as usize].priority;
195 let root_pri = self.nodes[root as usize].priority;
196 let r = if new_right_pri > root_pri {
197 self.rotate_left(root)
198 } else {
199 root
200 };
201 (r, replaced)
202 }
203 }
204 }
205
206 fn rem(&mut self, root: u32, key: &K) -> (u32, Option<V>) {
207 if root == NIL {
208 return (NIL, None);
209 }
210 let cmp = key.cmp(&self.nodes[root as usize].key);
211 match cmp {
212 Ordering::Less => {
213 let left = self.nodes[root as usize].left;
214 let (new_left, removed) = self.rem(left, key);
215 self.nodes[root as usize].left = new_left;
216 (root, removed)
217 }
218 Ordering::Greater => {
219 let right = self.nodes[root as usize].right;
220 let (new_right, removed) = self.rem(right, key);
221 self.nodes[root as usize].right = new_right;
222 (root, removed)
223 }
224 Ordering::Equal => {
225 let left = self.nodes[root as usize].left;
226 let right = self.nodes[root as usize].right;
227 let value = unsafe {
228 std::ptr::read(&self.nodes[root as usize].value)
231 };
232 let merged = self.merge_subtrees(left, right);
233 self.free(root);
234 (merged, Some(value))
235 }
236 }
237 }
238
239 fn merge_subtrees(&mut self, left: u32, right: u32) -> u32 {
240 if left == NIL {
241 return right;
242 }
243 if right == NIL {
244 return left;
245 }
246 let l_pri = self.nodes[left as usize].priority;
247 let r_pri = self.nodes[right as usize].priority;
248 if l_pri > r_pri {
249 let l_right = self.nodes[left as usize].right;
250 let merged = self.merge_subtrees(l_right, right);
251 self.nodes[left as usize].right = merged;
252 left
253 } else {
254 let r_left = self.nodes[right as usize].left;
255 let merged = self.merge_subtrees(left, r_left);
256 self.nodes[right as usize].left = merged;
257 right
258 }
259 }
260
261 fn rotate_right(&mut self, idx: u32) -> u32 {
262 let left = self.nodes[idx as usize].left;
263 debug_assert!(left != NIL, "rotate_right requires left child");
264 let left_right = self.nodes[left as usize].right;
265 self.nodes[idx as usize].left = left_right;
266 self.nodes[left as usize].right = idx;
267 left
268 }
269
270 fn rotate_left(&mut self, idx: u32) -> u32 {
271 let right = self.nodes[idx as usize].right;
272 debug_assert!(right != NIL, "rotate_left requires right child");
273 let right_left = self.nodes[right as usize].left;
274 self.nodes[idx as usize].right = right_left;
275 self.nodes[right as usize].left = idx;
276 right
277 }
278
279 fn in_order<'a>(&'a self, idx: u32, out: &mut Vec<(&'a K, &'a V)>) {
280 if idx == NIL {
281 return;
282 }
283 let node = &self.nodes[idx as usize];
284 self.in_order(node.left, out);
285 out.push((&node.key, &node.value));
286 self.in_order(node.right, out);
287 }
288}
289
290#[cfg(feature = "harness")]
291pub mod recipe;
292
293#[cfg(any(
297 feature = "range-query",
298 feature = "persistent",
299 feature = "merge-split",
300 feature = "concurrent-reads",
301))]
302pub mod features;
303
304#[cfg(feature = "concurrent-reads")]
305pub use features::concurrent_reads::TreapSnapshot;
306#[cfg(feature = "merge-split")]
307pub use features::merge_split::SplittableTreap;
308#[cfg(feature = "persistent")]
309pub use features::persistent::PersistentTreap;
310#[cfg(feature = "range-query")]
311pub use features::range_query::{RangeBound, RangeIter};