1use crate::KeyMngTrait;
2
3use super::{config::TreapMapConfig, node::Node};
4
5pub trait TreapNodeUpdate<C: TreapMapConfig> {
8 type Ret;
10 type DeleteRet;
12
13 fn treap_key(&self) -> (&C::SortKey, &C::SearchKey);
15
16 fn update_node(
24 self, maybe_node: Option<&mut Box<Node<C>>>,
25 ) -> OpResult<C, Self::Ret, Self::DeleteRet>;
26
27 fn handle_delete(
31 deleted_node: Option<Box<Node<C>>>, delete_ret: Self::DeleteRet,
32 ) -> Self::Ret;
33}
34
35pub enum OpResult<C: TreapMapConfig, R, DR> {
36 InsertOnVacant { insert: Box<Node<C>>, ret: R },
39 Updated { update_weight: bool, ret: R },
47 Noop(R),
50 Delete(DR),
52}
53
54pub(crate) struct InsertOp<'a, C: TreapMapConfig> {
55 pub node: Box<Node<C>>,
56 pub ext_map: &'a mut C::ExtMap,
57}
58
59impl<'a, C: TreapMapConfig> TreapNodeUpdate<C> for InsertOp<'a, C> {
60 type DeleteRet = ();
61 type Ret = Option<C::Value>;
62
63 fn treap_key(&self) -> (&C::SortKey, &C::SearchKey) {
64 (&self.node.sort_key, &self.node.key)
65 }
66
67 fn update_node(
68 self, maybe_node: Option<&mut Box<Node<C>>>,
69 ) -> OpResult<C, Self::Ret, Self::DeleteRet> {
70 use OpResult::*;
71
72 if let Some(node) = maybe_node {
73 let ret = Some(node.value.clone());
74 let update_weight = node.weight != self.node.weight;
75
76 self.ext_map.view_update(
77 &self.node.key,
78 Some(&self.node.value),
79 Some(&node.value),
80 );
81
82 node.value = self.node.value;
83 node.weight = self.node.weight;
84
85 Updated { ret, update_weight }
86 } else {
87 self.ext_map.view_update(
88 &self.node.key,
89 Some(&self.node.value),
90 None,
91 );
92 InsertOnVacant {
93 insert: self.node,
94 ret: None,
95 }
96 }
97 }
98
99 fn handle_delete(
100 _deleted_node: Option<Box<Node<C>>>, _delete_ret: (),
101 ) -> Self::Ret {
102 unreachable!()
104 }
105}
106
107pub(crate) struct RemoveOp<'a, C: TreapMapConfig> {
108 pub key: (&'a C::SortKey, &'a C::SearchKey),
109 pub ext_map: &'a mut C::ExtMap,
110}
111
112impl<'a, C: TreapMapConfig> TreapNodeUpdate<C> for RemoveOp<'a, C> {
113 type DeleteRet = ();
114 type Ret = Option<C::Value>;
115
116 fn treap_key(&self) -> (&C::SortKey, &C::SearchKey) { self.key }
117
118 fn update_node(
119 self, maybe_node: Option<&mut Box<Node<C>>>,
120 ) -> OpResult<C, Self::Ret, Self::DeleteRet> {
121 self.ext_map.view_update(
122 self.key.1,
123 None,
124 maybe_node.map(|x| &x.value),
125 );
126 OpResult::Delete(())
127 }
128
129 fn handle_delete(
130 deleted_node: Option<Box<Node<C>>>, _delete_ret: (),
131 ) -> Self::Ret {
132 deleted_node.map(|x| x.value)
133 }
134}
135
136pub struct ApplyOpOutcome<T> {
144 pub out: T,
147 pub update_weight: bool,
150 pub update_key: bool,
154 pub delete_item: bool,
157}
158
159pub(crate) struct ApplyOp<'a, C, U, I, T, E>
160where
161 C: TreapMapConfig,
162 U: FnOnce(&mut Node<C>) -> Result<ApplyOpOutcome<T>, E>,
163 I: FnOnce() -> Result<(Node<C>, T), E>,
164{
165 pub key: (&'a C::SortKey, &'a C::SearchKey),
166 pub ext_map: &'a mut C::ExtMap,
167 pub update: U,
168 pub insert: I,
169}
170
171impl<'a, 'b, C, U, I, T, E> TreapNodeUpdate<C> for ApplyOp<'a, C, U, I, T, E>
172where
173 C: TreapMapConfig,
174 U: FnOnce(&mut Node<C>) -> Result<ApplyOpOutcome<T>, E>,
175 I: FnOnce() -> Result<(Node<C>, T), E>,
176{
177 type DeleteRet = (T, bool);
178 type Ret = Result<(T, Option<Box<Node<C>>>), E>;
179
180 fn treap_key(&self) -> (&'a C::SortKey, &'a C::SearchKey) { self.key }
181
182 fn update_node(
183 self, maybe_node: Option<&mut Box<Node<C>>>,
184 ) -> OpResult<C, Self::Ret, Self::DeleteRet> {
185 use OpResult::*;
186 match maybe_node {
187 None => {
188 let (node, ret) = match (self.insert)() {
189 Ok(x) => x,
190 Err(err) => {
191 return Noop(Err(err));
192 }
193 };
194
195 self.ext_map
196 .view_update(&*self.key.1, Some(&node.value), None);
197 assert!(
198 C::next_node_dir(self.key, (&node.sort_key, &node.key))
199 .is_none(),
200 "Inserted node has inconsistent key"
201 );
202 InsertOnVacant {
203 insert: Box::new(node),
204 ret: Ok((ret, None)),
205 }
206 }
207 Some(node) => {
208 let old_value = node.value.clone();
209 let ApplyOpOutcome {
210 out,
211 update_weight,
212 update_key,
213 delete_item,
214 } = match (self.update)(node) {
215 Ok(x) => x,
216 Err(err) => {
217 return Noop(Err(err));
218 }
219 };
220 let new_value =
221 if delete_item { None } else { Some(&node.value) };
222 self.ext_map.view_update(
223 &*self.key.1,
224 new_value,
225 Some(&old_value),
226 );
227
228 if update_key || delete_item {
229 Delete((out, delete_item))
230 } else {
231 Updated {
232 update_weight,
233 ret: Ok((out, None)),
234 }
235 }
236 }
237 }
238 }
239
240 fn handle_delete(
241 deleted_node: Option<Box<Node<C>>>, (ret, delete_item): (T, bool),
242 ) -> Self::Ret {
243 let to_reinsert_node = if !delete_item {
244 Some(deleted_node.unwrap())
245 } else {
246 None
247 };
248 Ok((ret, to_reinsert_node))
249 }
250}