1use crate::{
2 utils::{binary_search_min, Array},
3 Storage, M,
4};
5use std::cmp::Ordering;
6
7use super::{Balance, Children, ChildrenWithSeparators, Offset, WouldUnderflow};
8
9const UNDERFLOW: usize = M / 2 - 1;
13
14#[derive(Clone)]
18pub struct Branch<T, S: Storage<T>> {
19 pub item: T,
21
22 pub child: S::Node,
24}
25
26impl<T, S: Storage<T>> AsRef<T> for Branch<T, S> {
27 fn as_ref(&self) -> &T {
28 &self.item
29 }
30}
31
32pub struct InsertionError<T, S: Storage<T>> {
43 pub item: T,
45
46 pub child_offset: usize,
48
49 pub child_id: S::Node,
51}
52
53pub struct Internal<T, S: Storage<T>> {
58 parent: Option<S::Node>,
59 first_child: S::Node,
60 other_children: Array<Branch<T, S>, M>,
61}
62
63impl<T, S: Storage<T>> Internal<T, S> {
64 pub fn new(
65 parent: Option<S::Node>,
66 first_child: S::Node,
67 other_children: Array<Branch<T, S>, M>,
68 ) -> Self {
69 Self {
70 parent,
71 first_child,
72 other_children,
73 }
74 }
75
76 #[inline]
78 pub fn binary(
79 parent: Option<S::Node>,
80 left_id: S::Node,
81 median: T,
82 right_id: S::Node,
83 ) -> Internal<T, S> {
84 let mut other_children = Array::new();
85 other_children.push(Branch {
86 item: median,
87 child: right_id,
88 });
89
90 Internal {
91 parent,
92 first_child: left_id,
93 other_children,
94 }
95 }
96
97 pub fn forget(&mut self) {
101 std::mem::forget(std::mem::take(&mut self.other_children))
102 }
103
104 #[inline]
106 pub fn balance(&self) -> Balance {
107 if self.is_overflowing() {
108 Balance::Overflow
109 } else if self.is_underflowing() {
110 Balance::Underflow(self.other_children.is_empty())
111 } else {
112 Balance::Balanced
113 }
114 }
115
116 #[inline]
117 pub fn is_overflowing(&self) -> bool {
118 self.item_count() >= M
119 }
120
121 #[inline]
122 pub fn is_underflowing(&self) -> bool {
123 self.item_count() < UNDERFLOW
124 }
125
126 #[inline]
127 pub fn parent(&self) -> Option<S::Node> {
128 self.parent
129 }
130
131 #[inline]
132 pub fn set_parent(&mut self, p: Option<S::Node>) {
133 self.parent = p
134 }
135
136 #[inline]
137 pub fn item_count(&self) -> usize {
138 self.other_children.len()
139 }
140
141 #[inline]
142 pub fn child_count(&self) -> usize {
143 1usize + self.item_count()
144 }
145
146 #[inline]
147 pub fn first_child_id(&self) -> S::Node {
148 self.first_child
149 }
150
151 #[inline]
152 pub fn branches(&self) -> &[Branch<T, S>] {
153 self.other_children.as_ref()
154 }
155
156 #[inline]
157 pub fn child_index(&self, id: S::Node) -> Option<usize> {
158 if self.first_child == id {
159 Some(0)
160 } else {
161 for i in 0..self.other_children.len() {
162 if self.other_children[i].child == id {
163 return Some(i + 1);
164 }
165 }
166
167 None
168 }
169 }
170
171 #[inline]
172 pub fn child_id(&self, index: usize) -> S::Node {
173 if index == 0 {
174 self.first_child
175 } else {
176 self.other_children[index - 1].child
177 }
178 }
179
180 #[inline]
181 pub fn child_id_opt(&self, index: usize) -> Option<S::Node> {
182 if index == 0 {
183 Some(self.first_child)
184 } else {
185 self.other_children.get(index - 1).map(|b| b.child)
186 }
187 }
188
189 #[inline]
190 pub fn separators(&self, index: usize) -> (Option<&T>, Option<&T>) {
191 let min = if index > 0 {
192 Some(&self.other_children[index - 1].item)
193 } else {
194 None
195 };
196
197 let max = if index < self.other_children.len() {
198 Some(&self.other_children[index].item)
199 } else {
200 None
201 };
202
203 (min, max)
204 }
205
206 #[inline]
207 pub fn get<Q: ?Sized>(&self, cmp: impl Fn(&T, &Q) -> Ordering, key: &Q) -> Result<&T, S::Node> {
208 match binary_search_min(|a, b| cmp(&a.item, b), &self.other_children, key) {
209 Some((offset, eq)) => {
210 let b = &self.other_children[offset];
211 if eq {
212 Ok(&b.item)
213 } else {
214 Err(b.child)
215 }
216 }
217 None => Err(self.first_child),
218 }
219 }
220
221 #[inline]
222 pub fn get_mut<Q: ?Sized>(
223 &mut self,
224 cmp: impl Fn(&T, &Q) -> Ordering,
225 key: &Q,
226 ) -> Result<&mut T, &mut S::Node> {
227 match binary_search_min(|a, b| cmp(&a.item, b), &self.other_children, key) {
228 Some((offset, eq)) => {
229 let b = &mut self.other_children[offset];
230 if eq {
231 Ok(&mut b.item)
232 } else {
233 Err(&mut b.child)
234 }
235 }
236 None => Err(&mut self.first_child),
237 }
238 }
239
240 #[inline]
245 pub fn offset_of<Q: ?Sized>(
246 &self,
247 cmp: impl Fn(&T, &Q) -> Ordering,
248 key: &Q,
249 ) -> Result<Offset, (usize, S::Node)> {
250 match binary_search_min(|a, b| cmp(&a.item, b), &self.other_children, key) {
251 Some((offset, eq)) => {
252 if eq {
253 Ok(offset.into())
254 } else {
255 let id = self.other_children[offset].child;
256 Err((offset + 1, id))
257 }
258 }
259 None => Err((0, self.first_child)),
260 }
261 }
262
263 #[inline]
264 pub fn children(&self) -> Children<T, S> {
265 Children::Internal(Some(self.first_child), self.other_children.as_ref().iter())
266 }
267
268 #[inline]
269 pub fn children_with_separators(&self) -> ChildrenWithSeparators<T, S> {
270 ChildrenWithSeparators::Internal(
271 Some(self.first_child),
272 None,
273 self.other_children.as_ref().iter().peekable(),
274 )
275 }
276
277 #[inline]
278 pub fn item(&self, offset: Offset) -> Option<&T> {
279 match self.other_children.get(offset.unwrap()) {
280 Some(b) => Some(&b.item),
281 None => None,
282 }
283 }
284
285 #[inline]
286 pub fn item_mut(&mut self, offset: Offset) -> Option<&mut T> {
287 match self.other_children.get_mut(offset.unwrap()) {
288 Some(b) => Some(&mut b.item),
289 None => None,
290 }
291 }
292
293 #[inline]
295 pub fn insert_by_key(
296 &mut self,
297 cmp: impl Fn(&T, &T) -> Ordering,
298 mut item: T,
299 ) -> Result<(Offset, T), InsertionError<T, S>> {
300 match binary_search_min(|a, b| cmp(&a.item, b), &self.other_children, &item) {
301 Some((i, eq)) => {
302 if eq {
303 std::mem::swap(&mut item, &mut self.other_children[i].item);
304 Ok((i.into(), item))
305 } else {
306 Err(InsertionError {
307 item,
308 child_offset: i + 1,
309 child_id: self.other_children[i].child,
310 })
311 }
312 }
313 None => Err(InsertionError {
314 item,
315 child_offset: 0,
316 child_id: self.first_child,
317 }),
318 }
319 }
320
321 #[inline]
340 pub fn insert(&mut self, offset: Offset, item: T, right_node_id: S::Node) {
341 self.other_children.insert(
342 offset.unwrap(),
343 Branch {
344 item,
345 child: right_node_id,
346 },
347 );
348 }
349
350 #[inline]
352 pub fn replace(&mut self, offset: Offset, mut item: T) -> T {
353 std::mem::swap(&mut item, &mut self.other_children[offset.unwrap()].item);
354 item
355 }
356
357 #[inline]
361 pub fn remove(&mut self, offset: Offset) -> (S::Node, T, S::Node) {
362 let offset = offset.unwrap();
363 let b = self.other_children.remove(offset).unwrap();
364 let left_child_id = self.child_id(offset);
365 (left_child_id, b.item, b.child)
366 }
367
368 #[inline]
369 pub fn split(&mut self) -> (usize, T, Internal<T, S>) {
370 assert!(self.is_overflowing()); let median_i = (self.other_children.len() - 1) / 2; let right_other_children = self.other_children.drain(median_i + 1..).collect();
376 let median = self.other_children.pop().unwrap();
377
378 let right_node = Internal {
379 parent: self.parent,
380 first_child: median.child,
381 other_children: right_other_children,
382 };
383
384 assert!(!self.is_underflowing());
385 assert!(!right_node.is_underflowing());
386
387 (self.other_children.len(), median.item, right_node)
388 }
389
390 #[inline]
397 pub fn merge(&mut self, left_index: usize) -> (usize, S::Node, S::Node, T, Balance) {
398 let branch = self.other_children.remove(left_index).unwrap();
401 let left_id = self.child_id(left_index);
402 let right_id = branch.child;
403 (left_index, left_id, right_id, branch.item, self.balance())
404 }
405
406 #[inline]
407 pub fn push_left(&mut self, item: T, mut child_id: S::Node) {
408 std::mem::swap(&mut self.first_child, &mut child_id);
409 self.other_children.insert(
410 0,
411 Branch {
412 item,
413 child: child_id,
414 },
415 );
416 }
417
418 #[inline]
419 pub fn pop_left(&mut self) -> Result<(T, S::Node), WouldUnderflow> {
420 if self.item_count() <= UNDERFLOW {
421 Err(WouldUnderflow)
422 } else {
423 let first = self.other_children.remove(0).unwrap();
424 let child_id = std::mem::replace(&mut self.first_child, first.child);
425 Ok((first.item, child_id))
426 }
427 }
428
429 #[inline]
430 pub fn push_right(&mut self, item: T, child_id: S::Node) -> Offset {
431 let offset = self.other_children.len();
432 self.other_children.push(Branch {
433 item,
434 child: child_id,
435 });
436 offset.into()
437 }
438
439 #[inline]
440 pub fn pop_right(&mut self) -> Result<RightBranch<T, S>, WouldUnderflow> {
441 if self.item_count() <= UNDERFLOW {
442 Err(WouldUnderflow)
443 } else {
444 let offset = self.other_children.len();
445 let last = self.other_children.pop().unwrap();
446 Ok(RightBranch {
447 offset: offset.into(),
448 item: last.item,
449 child: last.child,
450 })
451 }
452 }
453
454 #[inline]
455 pub fn append(&mut self, separator: T, mut other: Internal<T, S>) -> Offset {
456 let offset = self.other_children.len();
457 self.other_children.push(Branch {
458 item: separator,
459 child: other.first_child,
460 });
461
462 self.other_children.append(&mut other.other_children);
463 offset.into()
464 }
465
466 #[cfg(feature = "dot")]
470 #[inline]
471 pub fn dot_write_label<W: std::io::Write>(&self, f: &mut W) -> std::io::Result<()>
472 where
473 T: std::fmt::Display,
474 {
475 write!(f, "<c0> |")?;
476 let mut i = 1;
477 for branch in &self.other_children {
478 write!(f, "{{{}|<c{}>}} |", branch.item, i)?;
479 i += 1;
480 }
481
482 Ok(())
483 }
484
485 #[cfg(debug_assertions)]
486 pub fn validate(
487 &self,
488 cmp: impl Fn(&T, &T) -> Ordering,
489 parent: Option<S::Node>,
490 min: Option<&T>,
491 max: Option<&T>,
492 ) {
493 if self.parent() != parent {
494 panic!("wrong parent")
495 }
496
497 if min.is_some() || max.is_some() {
498 match self.balance() {
500 Balance::Overflow => panic!("internal node is overflowing"),
501 Balance::Underflow(_) => panic!("internal node is underflowing"),
502 _ => (),
503 }
504 } else if self.item_count() == 0 {
505 panic!("root node is empty")
506 }
507
508 if !self
509 .other_children
510 .windows(2)
511 .all(|w| cmp(&w[0].item, &w[1].item).is_lt())
512 {
513 panic!("internal node items are not sorted")
514 }
515
516 if let Some(min) = min {
517 if let Some(b) = self.other_children.first() {
518 if cmp(min, &b.item).is_ge() {
519 panic!("internal node item key is greater than right separator")
520 }
521 }
522 }
523
524 if let Some(max) = max {
525 if let Some(b) = self.other_children.last() {
526 if cmp(max, &b.item).is_le() {
527 panic!("internal node item key is less than left separator")
528 }
529 }
530 }
531 }
532}
533
534pub struct RightBranch<T, S: Storage<T>> {
535 pub offset: Offset,
536 pub item: T,
537 pub child: S::Node,
538}