1use crate::{
2 balancing::rebalance,
3 node::{Address, Offset},
4 utils::Array,
5 Node, M,
6};
7use core::fmt;
8use std::{cmp::Ordering, ptr::NonNull};
9
10pub unsafe trait Storage<T>: Default {
30 type Node: Copy + PartialEq + core::fmt::Debug;
32
33 type Dropper: Dropper<T, Self>;
35
36 fn allocate_node(&mut self, node: Node<T, Self>) -> Self::Node;
38
39 unsafe fn release_node(&mut self, id: Self::Node) -> Node<T, Self>;
43
44 fn start_dropping(&self) -> Option<Self::Dropper>;
49
50 unsafe fn get(&self, id: Self::Node) -> &Node<T, Self>;
54
55 unsafe fn get_mut(&mut self, id: Self::Node) -> &mut Node<T, Self>;
62
63 unsafe fn insert_node(&mut self, node: Node<T, Self>) -> Self::Node {
69 let children: Array<Self::Node, M> = node.children().collect();
70 let id = self.allocate_node(node);
71 for child_id in children {
72 self.get_mut(child_id).set_parent(Some(id));
73 }
74
75 id
76 }
77
78 unsafe fn normalize(&self, mut addr: Address<Self::Node>) -> Option<Address<Self::Node>> {
84 loop {
85 let node = self.get(addr.node);
86 if addr.offset >= node.item_count() {
87 match node.parent() {
88 Some(parent_id) => {
89 addr.offset = self.get(parent_id).child_index(addr.node).unwrap().into();
90 addr.node = parent_id;
91 }
92 None => break None,
93 }
94 } else {
95 break Some(addr);
96 }
97 }
98 }
99
100 #[inline]
106 unsafe fn leaf_address(&self, mut addr: Address<Self::Node>) -> Address<Self::Node> {
107 loop {
108 let node = self.get(addr.node);
109 match node.child_id_opt(addr.offset.unwrap()) {
110 Some(child_id) => {
112 addr.node = child_id;
113 addr.offset = self.get(child_id).item_count().into()
114 }
115 None => break,
116 }
117 }
118
119 addr
120 }
121
122 #[inline]
128 unsafe fn previous_item_address(
129 &self,
130 mut addr: Address<Self::Node>,
131 ) -> Option<Address<Self::Node>> {
132 loop {
133 let node = self.get(addr.node);
134
135 match node.child_id_opt(addr.offset.unwrap()) {
136 Some(child_id) => {
138 addr.offset = self.get(child_id).item_count().into();
139 addr.node = child_id;
140 }
141 None => loop {
142 if addr.offset > 0 {
143 addr.offset.decr();
144 return Some(addr);
145 }
146
147 match self.get(addr.node).parent() {
148 Some(parent_id) => {
149 addr.offset =
150 self.get(parent_id).child_index(addr.node).unwrap().into();
151 addr.node = parent_id;
152 }
153 None => return None,
154 }
155 },
156 }
157 }
158 }
159
160 #[inline]
166 unsafe fn previous_front_address(
167 &self,
168 mut addr: Address<Self::Node>,
169 ) -> Option<Address<Self::Node>> {
170 loop {
171 let node = self.get(addr.node);
172 match addr.offset.value() {
173 Some(offset) => {
174 let index = if offset < node.item_count() {
175 offset
176 } else {
177 node.item_count()
178 };
179
180 match node.child_id_opt(index) {
181 Some(child_id) => {
182 addr.offset = (self.get(child_id).item_count()).into();
183 addr.node = child_id;
184 }
185 None => {
186 addr.offset.decr();
187 break;
188 }
189 }
190 }
191 None => match node.parent() {
192 Some(parent_id) => {
193 addr.offset = self.get(parent_id).child_index(addr.node).unwrap().into();
194 addr.offset.decr();
195 addr.node = parent_id;
196 break;
197 }
198 None => return None,
199 },
200 }
201 }
202
203 Some(addr)
204 }
205
206 #[inline]
212 unsafe fn next_item_address(
213 &self,
214 mut addr: Address<Self::Node>,
215 ) -> Option<Address<Self::Node>> {
216 let item_count = self.get(addr.node).item_count();
217 match addr.offset.partial_cmp(&item_count) {
218 Some(std::cmp::Ordering::Less) => {
219 addr.offset.incr();
220 }
221 Some(std::cmp::Ordering::Greater) => {
222 return None;
223 }
224 _ => (),
225 }
226
227 loop {
230 let node = self.get(addr.node);
231
232 match node.child_id_opt(addr.offset.unwrap()) {
233 Some(child_id) => {
235 addr.offset = 0.into();
236 addr.node = child_id;
237 }
238 None => {
239 loop {
240 let node = self.get(addr.node);
241
242 if addr.offset < node.item_count() {
243 return Some(addr);
244 }
245
246 match node.parent() {
247 Some(parent_id) => {
248 addr.offset =
249 self.get(parent_id).child_index(addr.node).unwrap().into();
250 addr.node = parent_id;
251 }
252 None => {
253 return None;
255 }
256 }
257 }
258 }
259 }
260 }
261 }
262
263 #[inline]
269 unsafe fn next_back_address(
270 &self,
271 mut addr: Address<Self::Node>,
272 ) -> Option<Address<Self::Node>> {
273 loop {
274 let node = self.get(addr.node);
275 let index = match addr.offset.value() {
276 Some(offset) => offset + 1,
277 None => 0,
278 };
279
280 if index <= node.item_count() {
281 match node.child_id_opt(index) {
282 Some(child_id) => {
283 addr.offset = Offset::before();
284 addr.node = child_id;
285 }
286 None => {
287 addr.offset = index.into();
288 break;
289 }
290 }
291 } else {
292 match node.parent() {
293 Some(parent_id) => {
294 addr.offset = self.get(parent_id).child_index(addr.node).unwrap().into();
295 addr.node = parent_id;
296 break;
297 }
298 None => return None,
299 }
300 }
301 }
302
303 Some(addr)
304 }
305
306 #[inline]
313 unsafe fn next_item_or_back_address(
314 &self,
315 mut addr: Address<Self::Node>,
316 ) -> Option<Address<Self::Node>> {
317 let item_count = self.get(addr.node).item_count();
318 match addr.offset.partial_cmp(&item_count) {
319 Some(std::cmp::Ordering::Less) => {
320 addr.offset.incr();
321 }
322 Some(std::cmp::Ordering::Greater) => {
323 return None;
324 }
325 _ => (),
326 }
327
328 let original_addr_shifted = addr;
329
330 loop {
331 let node = self.get(addr.node);
332
333 match node.child_id_opt(addr.offset.unwrap()) {
334 Some(child_id) => {
336 addr.offset = 0.into();
337 addr.node = child_id;
338 }
339 None => loop {
340 let node = self.get(addr.node);
341
342 if addr.offset < node.item_count() {
343 return Some(addr);
344 }
345
346 match node.parent() {
347 Some(parent_id) => {
348 addr.offset =
349 self.get(parent_id).child_index(addr.node).unwrap().into();
350 addr.node = parent_id;
351 }
352 None => return Some(original_addr_shifted),
353 }
354 },
355 }
356 }
357 }
358
359 unsafe fn address_in<Q: ?Sized>(
363 &self,
364 mut id: Self::Node,
365 cmp: impl Fn(&T, &Q) -> Ordering,
366 key: &Q,
367 ) -> Result<Address<Self::Node>, Address<Self::Node>> {
368 loop {
369 match self.get(id).offset_of(&cmp, key) {
370 Ok(offset) => return Ok(Address { node: id, offset }),
371 Err((offset, None)) => return Err(Address::new(id, offset.into())),
372 Err((_, Some(child_id))) => {
373 id = child_id;
374 }
375 }
376 }
377 }
378
379 unsafe fn insert_at(
385 &mut self,
386 root: Option<Self::Node>,
387 addr: Option<Address<Self::Node>>,
388 item: T,
389 ) -> (Option<Self::Node>, Option<Address<Self::Node>>) {
390 self.insert_exactly_at(root, addr.map(|addr| self.leaf_address(addr)), item, None)
391 }
392
393 unsafe fn insert_exactly_at(
399 &mut self,
400 root: Option<Self::Node>,
401 addr: Option<Address<Self::Node>>,
402 item: T,
403 opt_right_id: Option<Self::Node>,
404 ) -> (Option<Self::Node>, Option<Address<Self::Node>>) {
405 match addr {
406 Some(addr) => {
407 self.get_mut(addr.node)
408 .insert(addr.offset, item, opt_right_id);
409 rebalance(self, root, addr.node, addr)
410 }
411 None => {
412 let new_root = Node::leaf(None, item);
413 let id = self.insert_node(new_root);
414 let addr = Address {
415 node: id,
416 offset: 0.into(),
417 };
418 (Some(id), Some(addr))
419 }
420 }
421 }
422
423 unsafe fn replace_at(&mut self, addr: Address<Self::Node>, item: T) -> T {
429 std::mem::replace(self.get_mut(addr.node).item_mut(addr.offset).unwrap(), item)
430 }
431
432 #[inline]
436 unsafe fn remove_at(
437 &mut self,
438 root: Option<Self::Node>,
439 addr: Address<Self::Node>,
440 ) -> Option<RemovedItem<T, Self>> {
441 match self.get_mut(addr.node).leaf_remove(addr.offset) {
442 Some(Ok(item)) => {
443 let (new_root, new_addr) = rebalance(self, root, addr.node, addr);
445 Some(RemovedItem {
446 new_root,
447 item,
448 new_addr,
449 })
450 }
451 Some(Err(left_child_id)) => {
452 let new_addr = self.next_item_or_back_address(addr).unwrap();
454 let (separator, leaf_id) = self.remove_rightmost_leaf_of(left_child_id);
455 let item = self.get_mut(addr.node).replace(addr.offset, separator);
456 let (new_root, new_addr) = rebalance(self, root, leaf_id, new_addr);
457 Some(RemovedItem {
458 new_root,
459 item,
460 new_addr,
461 })
462 }
463 None => None,
464 }
465 }
466
467 #[inline]
473 unsafe fn remove_rightmost_leaf_of(&mut self, mut id: Self::Node) -> (T, Self::Node) {
474 loop {
475 match self.get_mut(id).remove_rightmost_leaf() {
476 Ok(result) => return (result, id),
477 Err(child_id) => {
478 id = child_id;
479 }
480 }
481 }
482 }
483}
484
485pub struct RemovedItem<T, S: Storage<T>> {
486 pub new_root: Option<S::Node>,
487 pub item: T,
488 pub new_addr: Option<Address<S::Node>>,
489}
490
491pub unsafe trait Dropper<T, S: Storage<T>>: Sized {
499 unsafe fn drop_node(&mut self, id: S::Node);
507}
508
509#[derive(Default)]
510pub struct BoxStorage;
511
512pub struct BoxPtr<T>(NonNull<Node<T, BoxStorage>>); unsafe impl<T: Send> Send for BoxPtr<T> {}
515unsafe impl<T: Sync> Sync for BoxPtr<T> {}
516
517unsafe impl<T> Storage<T> for BoxStorage {
518 type Node = BoxPtr<T>;
519
520 type Dropper = BoxDrop;
521
522 fn allocate_node(&mut self, node: Node<T, Self>) -> Self::Node {
523 let b = Box::new(node);
524 BoxPtr(NonNull::new(Box::into_raw(b)).unwrap())
525 }
526
527 unsafe fn release_node(&mut self, id: Self::Node) -> Node<T, Self> {
528 let b = Box::from_raw(id.0.as_ptr());
529 *b
530 }
531
532 fn start_dropping(&self) -> Option<Self::Dropper> {
533 Some(BoxDrop)
534 }
535
536 unsafe fn get(&self, id: Self::Node) -> &Node<T, Self> {
537 &*id.0.as_ptr()
538 }
539
540 unsafe fn get_mut(&mut self, id: Self::Node) -> &mut Node<T, Self> {
541 &mut *id.0.as_ptr()
542 }
543}
544
545impl<T> fmt::Debug for BoxPtr<T> {
546 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
547 self.0.fmt(f)
548 }
549}
550
551impl<T> Clone for BoxPtr<T> {
552 fn clone(&self) -> Self {
553 *self
554 }
555}
556
557impl<T> Copy for BoxPtr<T> {}
558
559impl<T> PartialEq for BoxPtr<T> {
560 fn eq(&self, other: &Self) -> bool {
561 self.0 == other.0
562 }
563}
564
565impl<T> Eq for BoxPtr<T> {}
566
567impl<T> From<BoxPtr<T>> for usize {
568 fn from(value: BoxPtr<T>) -> Self {
569 value.0.as_ptr() as usize
570 }
571}
572
573pub struct BoxDrop;
574
575unsafe impl<T> Dropper<T, BoxStorage> for BoxDrop {
576 unsafe fn drop_node(&mut self, id: BoxPtr<T>) {
577 let _ = Box::from_raw(id.0.as_ptr());
578 }
579}