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> {
143 pub out: T,
146 pub update_weight: bool,
149 pub update_key: bool,
153 pub delete_item: bool,
156}
157
158pub(crate) struct ApplyOp<'a, C, U, I, T, E>
159where
160 C: TreapMapConfig,
161 U: FnOnce(&mut Node<C>) -> Result<ApplyOpOutcome<T>, E>,
162 I: FnOnce() -> Result<(Node<C>, T), E>,
163{
164 pub key: (&'a C::SortKey, &'a C::SearchKey),
165 pub ext_map: &'a mut C::ExtMap,
166 pub update: U,
167 pub insert: I,
168}
169
170impl<'a, C, U, I, T, E> TreapNodeUpdate<C> for ApplyOp<'a, C, U, I, T, E>
171where
172 C: TreapMapConfig,
173 U: FnOnce(&mut Node<C>) -> Result<ApplyOpOutcome<T>, E>,
174 I: FnOnce() -> Result<(Node<C>, T), E>,
175{
176 type DeleteRet = (T, bool);
177 type Ret = Result<(T, Option<Box<Node<C>>>), E>;
178
179 fn treap_key(&self) -> (&'a C::SortKey, &'a C::SearchKey) { self.key }
180
181 fn update_node(
182 self, maybe_node: Option<&mut Box<Node<C>>>,
183 ) -> OpResult<C, Self::Ret, Self::DeleteRet> {
184 use OpResult::*;
185 match maybe_node {
186 None => {
187 let (node, ret) = match (self.insert)() {
188 Ok(x) => x,
189 Err(err) => {
190 return Noop(Err(err));
191 }
192 };
193
194 self.ext_map
195 .view_update(self.key.1, Some(&node.value), None);
196 assert!(
197 C::next_node_dir(self.key, (&node.sort_key, &node.key))
198 .is_none(),
199 "Inserted node has inconsistent key"
200 );
201 InsertOnVacant {
202 insert: Box::new(node),
203 ret: Ok((ret, None)),
204 }
205 }
206 Some(node) => {
207 let old_value = node.value.clone();
208 let ApplyOpOutcome {
209 out,
210 update_weight,
211 update_key,
212 delete_item,
213 } = match (self.update)(node) {
214 Ok(x) => x,
215 Err(err) => {
216 return Noop(Err(err));
217 }
218 };
219 let new_value =
220 if delete_item { None } else { Some(&node.value) };
221 self.ext_map.view_update(
222 self.key.1,
223 new_value,
224 Some(&old_value),
225 );
226
227 if update_key || delete_item {
228 Delete((out, delete_item))
229 } else {
230 Updated {
231 update_weight,
232 ret: Ok((out, None)),
233 }
234 }
235 }
236 }
237 }
238
239 fn handle_delete(
240 deleted_node: Option<Box<Node<C>>>, (ret, delete_item): (T, bool),
241 ) -> Self::Ret {
242 let to_reinsert_node = if !delete_item {
243 Some(deleted_node.unwrap())
244 } else {
245 None
246 };
247 Ok((ret, to_reinsert_node))
248 }
249}