content_tree/
mutations.rs

1use std::{mem, ptr};
2use std::hint::unreachable_unchecked;
3use std::pin::Pin;
4use std::ptr::NonNull;
5
6use smallvec::SmallVec;
7
8use super::*;
9use rle::AppendRle;
10
11/// This file contains the core code for content-tree's mutation operations.
12
13impl<E: ContentTraits, I: TreeMetrics<E>, const IE: usize, const LE: usize> ContentTreeRaw<E, I, IE, LE> {
14    /// Insert item(s) at the position pointed to by the cursor. If the item is split, the remainder
15    /// is returned. The cursor is modified in-place to point after the inserted items.
16    ///
17    /// If the cursor points in the middle of an item, the item is split.
18    ///
19    /// The list of items must have a maximum length of 3, so we can always insert all the new items
20    /// in half of a leaf node. (This is a somewhat artificial constraint, but its fine here.)
21    unsafe fn insert_internal<F>(mut items: &[E], cursor: &mut UnsafeCursor<E, I, IE, LE>, flush_marker: &mut I::Update, notify: &mut F)
22        where F: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>)
23    {
24        if items.is_empty() { return; }
25        assert!(items.len() <= 3);
26
27        // cursor.get_node_mut() would be better but it would borrow the cursor.
28        let mut node = &mut *cursor.node.as_ptr();
29
30        let remainder = if cursor.offset == usize::MAX {
31            debug_assert_eq!(cursor.idx, 0);
32            debug_assert_eq!(node.num_entries, 0);
33            // We're inserting into the start of a tree. I could short circuit here, but the
34            // complexity isn't worth the performance boost given it just happens once per tree.
35            cursor.offset = 0;
36            None
37        } else if cursor.offset == 0 && cursor.idx > 0 {
38            // We'll roll the cursor back to opportunistically see if we can append.
39            cursor.idx -= 1;
40            cursor.offset = node.data[cursor.idx].len(); // blerp could be cleaner.
41            None
42        } else {
43            // We could also roll back if cursor.offset == 0 and cursor.idx == 0 but when I tried it it
44            // didn't make any difference in practice because insert() is always called with stick_end.
45
46            // Remainder is the trimmed off returned value.
47            if cursor.offset == node.data[cursor.idx].len() || cursor.offset == 0 {
48                None
49            } else {
50                // splice the item into the current cursor location.
51                let entry: &mut E = &mut node.data[cursor.idx];
52                let remainder = entry.truncate(cursor.offset);
53                I::decrement_marker(flush_marker, &remainder);
54                // flush_marker -= (seq_len - cursor.offset) as isize;
55                // We don't need to update cursor since its already where it needs to be.
56
57                Some(remainder)
58            }
59        };
60
61        // If we prepend to the start of the following tree node, the cursor will need to be
62        // adjusted accordingly.
63        let mut trailing_offset = 0;
64
65        if cursor.offset != 0 {
66            // We're at the end of an element. Try and append as much as we can here.
67            debug_assert_eq!(cursor.offset, node.data[cursor.idx].len());
68            // Try and append as much as we can after the current entry
69            let mut items_idx = 0;
70            let cur_entry: &mut E = &mut node.data[cursor.idx];
71            while items_idx < items.len() { // There's probably a cleaner way to write this loop.
72                let next = items[items_idx];
73                if cur_entry.can_append(&next) {
74                    I::increment_marker(flush_marker, &next);
75                    // flush_marker += next.content_len() as isize;
76                    notify(next, cursor.node);
77                    cur_entry.append(next);
78
79                    cursor.offset = cur_entry.len();
80                    items_idx += 1;
81                } else { break; }
82            }
83            if items_idx == items.len() && remainder.is_none() {
84                return; // We're done here. Cursor is at the end of the previous entry.
85            }
86            items = &items[items_idx..];
87            // Note items might be empty now. We might just have remainder left.
88
89            cursor.offset = 0;
90            cursor.idx += 1; // NOTE: Cursor might point past the end of the node.
91
92            if remainder.is_none() && !items.is_empty() && cursor.idx < node.len_entries() {
93                // We'll also try to *prepend* some content on the front of the subsequent element
94                // I'm sure there's a way to do this using iterators, but I'm not sure it would be
95                // cleaner.
96
97                // This optimization improves performance when the user hits backspace. We end up
98                // merging all the deleted elements together. This adds complexity in exchange for
99                // making the tree simpler. For real edit sequences (like the automerge-perf data
100                // set) this gives about an 8% performance increase.
101
102                // It may be worth being more aggressive here. We're currently not trying this trick
103                // when the cursor is at the end of the current node. That might be worth trying!
104                let mut end_idx = items.len() - 1;
105                let cur_entry = &mut node.data[cursor.idx];
106                loop {
107                    let next = items[end_idx];
108                    if next.can_append(cur_entry) {
109                        I::increment_marker(flush_marker, &next);
110                        notify(next, cursor.node);
111                        trailing_offset += next.len();
112                        cur_entry.prepend(next);
113                    } else { break; }
114
115                    if end_idx == 0 {
116                        cursor.offset = trailing_offset;
117                        return; // We've prepended everything.
118                    } else { end_idx -= 1; }
119                }
120                items = &items[..=end_idx];
121            }
122        }
123
124        debug_assert_eq!(cursor.offset, 0);
125
126        // Step 2: Make room in the leaf for the new items.
127        // I'm setting up node again to work around a borrow checker issue.
128        // let mut node = unsafe { cursor.node.as_mut() };
129        let space_needed = items.len() + remainder.is_some() as usize;
130        let num_filled = node.len_entries();
131        debug_assert!(space_needed > 0);
132        assert!(space_needed <= LE / 2);
133
134        let remainder_moved = if num_filled + space_needed > LE {
135            // We need to split the node. The proper b-tree way to do this is to make sure there's
136            // always N/2 items in every leaf after a split, but I don't think it'll matter here.
137            // Instead I'll split at idx, and insert the new items in whichever child has more space
138            // afterwards.
139
140            // We have to flush regardless, because we might have truncated the current element.
141            node.flush_metric_update(flush_marker);
142
143            if cursor.idx < LE / 2 {
144                // Split then elements go in left branch, so the cursor isn't updated.
145                node.split_at(cursor.idx, 0, notify);
146                node.num_entries += space_needed as u8;
147                false
148            } else {
149                // This will adjust num_entries based on the padding parameter.
150                let new_node_ptr = node.split_at(cursor.idx, space_needed, notify);
151                cursor.node = new_node_ptr;
152                cursor.idx = 0;
153                node = &mut *cursor.node.as_ptr();
154                true
155            }
156        } else {
157            // We need to move the existing items. This doesn't effect sizes.
158            if num_filled > cursor.idx {
159                node.data[..].copy_within(cursor.idx..num_filled, cursor.idx + space_needed);
160            }
161            node.num_entries += space_needed as u8;
162            false
163        };
164
165        // Step 3: There's space now, so we can just insert.
166
167        let remainder_idx = cursor.idx + items.len();
168
169        if !items.is_empty() {
170            for e in items {
171                I::increment_marker(flush_marker, e);
172                // flush_marker.0 += e.content_len() as isize;
173                notify(*e, cursor.node);
174            }
175            node.data[cursor.idx..cursor.idx + items.len()].copy_from_slice(items);
176
177            // Point the cursor to the end of the last inserted item.
178            cursor.idx += items.len() - 1;
179            cursor.offset = items[items.len() - 1].len();
180
181            if trailing_offset > 0 {
182                cursor.move_forward_by_offset(trailing_offset, Some(flush_marker));
183            }
184        }
185
186        // The cursor isn't updated to point after remainder.
187        if let Some(e) = remainder {
188            I::increment_marker(flush_marker, &e);
189            if remainder_moved {
190                notify(e, cursor.node);
191            }
192            node.data[remainder_idx] = e;
193        }
194    }
195
196    pub unsafe fn unsafe_insert_notify<F>(cursor: &mut UnsafeCursor<E, I, IE, LE>, new_entry: E, mut notify: F)
197    where F: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>) {
198        let mut marker = I::Update::default();
199        Self::insert_internal(&[new_entry], cursor, &mut marker, &mut notify);
200
201        cursor.get_node_mut().flush_metric_update(&mut marker);
202        // cursor.compress_node();
203    }
204
205    #[inline(always)]
206    pub fn insert_at_start_notify<F>(self: &mut Pin<Box<Self>>, new_entry: E, notify: F)
207    where F: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>)
208    {
209        unsafe { Self::unsafe_insert_notify(&mut self.unsafe_cursor_at_start(), new_entry, notify) }
210    }
211
212    #[inline(always)]
213    pub fn insert_at_start(self: &mut Pin<Box<Self>>, new_entry: E) {
214        self.insert_at_start_notify(new_entry, null_notify);
215    }
216
217    #[inline(always)]
218    pub fn push_notify<F>(self: &mut Pin<Box<Self>>, new_entry: E, notify: F)
219    where F: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>)
220    {
221        unsafe { Self::unsafe_insert_notify(&mut self.unsafe_cursor_at_end(), new_entry, notify) }
222    }
223
224    /// Push a new entry to the end of the tree. The new entry will be merged with the existing
225    /// last entry if possible.
226    #[inline(always)]
227    pub fn push(self: &mut Pin<Box<Self>>, new_entry: E)
228    {
229        self.push_notify(new_entry, null_notify);
230    }
231
232    /// Replace the item at the cursor position with the new items provided by items.
233    ///
234    /// Items must have a maximum length of 3, due to limitations in split_insert above.
235    /// The cursor's offset is ignored. The cursor ends up at the end of the inserted items.
236    #[allow(clippy::len_zero)]
237    unsafe fn replace_entry<F>(cursor: &mut UnsafeCursor<E, I, IE, LE>, items: &[E], flush_marker: &mut I::Update, notify: &mut F)
238        where F: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>) {
239        assert!(items.len() >= 1 && items.len() <= 3);
240
241        // Essentially here we want to:
242        // 1. Concatenate as much from items as we can into the previous element
243        // 2. With the rest:
244        //   - If we run out of items, slide back (deleting the item under the cursor)
245        //   - If we have 1 item left, replace inline
246        //   - If we have more than 1 item left, replace then insert.
247        // Even though we can delete items here, we will never end up with an empty node. So no
248        // need to worry about the complex cases of delete.
249
250        // Before anything else, we'll give a token effort trying to concatenate the item onto the
251        // previous item.
252        let mut items_idx = 0;
253        let node = cursor.node.as_mut();
254        debug_assert!(cursor.idx < node.len_entries());
255
256        if cursor.idx >= 1 {
257            let elem = &mut node.data[cursor.idx - 1];
258            loop { // This is a crap for / while loop.
259                let item = &items[items_idx];
260                if elem.can_append(item) {
261                    I::increment_marker(flush_marker, item);
262                    elem.append(*item);
263                    items_idx += 1;
264                    if items_idx >= items.len() { break; }
265                } else { break; }
266            }
267        }
268
269        // let entry = cursor.get_raw_entry_mut();
270        let entry = &mut node.data[cursor.idx];
271        I::decrement_marker(flush_marker, entry);
272
273        if items_idx >= items.len() {
274            // Nuke the item under the cursor and shuffle everything back.
275            node.splice_out(cursor.idx);
276            if cursor.idx >= node.len_entries() {
277                // The cursor might now be pointing past the end of this node.
278                debug_assert!(node.len_entries() >= 1);
279                cursor.idx -= 1;
280                cursor.offset = node.data[cursor.idx].len();
281            } else {
282                cursor.offset = 0;
283            }
284        } else {
285            // First replace the item directly.
286            *entry = items[items_idx];
287            I::increment_marker(flush_marker, entry);
288
289            cursor.offset = entry.len();
290            // notify(*entry, cursor.node);
291
292            // And insert the rest, if there are any.
293            Self::insert_internal(&items[items_idx + 1..], cursor, flush_marker, notify);
294        }
295
296        if cfg!(debug_assertions) {
297            // The cursor should always end up inside the node.
298            let node = cursor.get_node_mut();
299            debug_assert!(cursor.idx < node.len_entries());
300        }
301    }
302
303    /// Replace the current entry with the items passed via items[]. Items.len must be <= 3. The
304    /// cursor offset is ignored. This is a fancy method - use sparingly.
305    pub unsafe fn unsafe_replace_entry_notify<N>(cursor: &mut UnsafeCursor<E, I, IE, LE>, items: &[E], mut notify: N)
306        where N: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>) {
307
308        let mut flush_marker = I::Update::default();
309        Self::replace_entry(cursor, items, &mut flush_marker, &mut notify);
310        cursor.get_node_mut().flush_metric_update(&mut flush_marker);
311    }
312
313    #[inline]
314    unsafe fn replace_entry_simple<F>(cursor: &mut UnsafeCursor<E, I, IE, LE>, new_item: E, flush_marker: &mut I::Update, notify: &mut F)
315        where F: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>) {
316        notify(new_item, cursor.node);
317        cursor.offset = new_item.len();
318        let entry = cursor.get_raw_entry_mut();
319        I::decrement_marker(flush_marker, entry);
320        *entry = new_item;
321        I::increment_marker(flush_marker, entry);
322    }
323
324    pub unsafe fn unsafe_replace_entry_simple_notify<N>(cursor: &mut UnsafeCursor<E, I, IE, LE>, new_item: E, mut notify: N)
325        where N: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>) {
326
327        let mut flush_marker = I::Update::default();
328        Self::replace_entry_simple(cursor, new_item, &mut flush_marker, &mut notify);
329        cursor.get_node_mut().flush_metric_update(&mut flush_marker);
330    }
331
332
333    /// Replace as much of the current entry from cursor onwards as we can.
334    unsafe fn unsafe_mutate_entry_internal<MapFn, N, R>(
335        map_fn: MapFn,
336        cursor: &mut UnsafeCursor<E, I, IE, LE>,
337        replace_max: usize,
338        flush_marker: &mut I::Update,
339        notify: &mut N
340    ) -> (usize, R)
341    where N: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>), MapFn: FnOnce(&mut E) -> R
342    {
343        let node = cursor.get_node_mut();
344        debug_assert!(cursor.idx < node.len_entries());
345        let mut entry: E = node.data[cursor.idx];
346        let mut entry_len = entry.len();
347
348        assert!(cursor.offset < entry_len);
349
350        // There's 1-3 parts here - part1<part2>part3
351
352        // Trim off the first part
353        let a = if cursor.offset > 0 {
354            entry_len -= cursor.offset;
355            Some(entry.truncate_keeping_right(cursor.offset))
356        } else { None };
357
358        // Trim off the last part
359        let (c, replaced_here) = if replace_max < entry_len {
360            (Some(entry.truncate(replace_max)), replace_max)
361        } else { (None, entry_len) };
362
363        let return_val = map_fn(&mut entry);
364
365        match (a, c) {
366            (Some(a), Some(c)) => {
367                let c_len = c.len();
368                Self::replace_entry(cursor, &[a, entry, c], flush_marker, notify);
369                cursor.move_back_by_offset(c_len, Some(flush_marker));
370            },
371            (Some(a), None) => {
372                Self::replace_entry(cursor, &[a, entry], flush_marker, notify);
373            },
374            (None, Some(c)) => {
375                let c_len = c.len();
376                Self::replace_entry(cursor, &[entry, c], flush_marker, notify);
377                cursor.move_back_by_offset(c_len, Some(flush_marker));
378            },
379            (None, None) => {
380                // Short circuit for:
381                // self.replace_entry(&mut cursor, &[entry], &mut flush_marker, &mut notify);
382
383                // TODO: Check if the replacement item can be appended to the previous element?
384                // Self::replace_entry_simple(cursor, entry, flush_marker, notify);
385                I::decrement_marker(flush_marker, &node.data[cursor.idx]);
386                node.data[cursor.idx] = entry;
387                cursor.offset = replaced_here;
388                I::increment_marker(flush_marker, &entry);
389                notify(entry, cursor.node);
390            }
391        }
392
393        (replaced_here, return_val)
394    }
395
396    pub unsafe fn unsafe_mutate_single_entry_notify<MapFn, R, N>(
397        map_fn: MapFn,
398        cursor: &mut UnsafeCursor<E, I, IE, LE>,
399        replace_max: usize,
400        mut notify: N
401    ) -> (usize, R)
402    where N: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>), MapFn: FnOnce(&mut E) -> R {
403        let mut flush_marker = I::Update::default();
404        let (amt_modified, ret) = Self::unsafe_mutate_entry_internal(map_fn, cursor, replace_max, &mut flush_marker, &mut notify);
405
406        cursor.get_node_mut().flush_metric_update(&mut flush_marker);
407        (amt_modified, ret)
408    }
409
410    pub unsafe fn unsafe_mutate_entries_notify<MapFn, N>(
411        map_fn: MapFn,
412        cursor: &mut UnsafeCursor<E, I, IE, LE>,
413        replace_len: usize,
414        mut notify: N
415    )
416    where N: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>), MapFn: Fn(&mut E) {
417        let mut flush_marker = I::Update::default();
418        let mut remaining = replace_len;
419        while remaining > 0 {
420            cursor.roll_to_next_entry_marker(&mut flush_marker);
421            let (consumed_here, _) = Self::unsafe_mutate_entry_internal(&map_fn, cursor, remaining, &mut flush_marker, &mut notify);
422            assert!(consumed_here > 0, "Could not mutate past end of list");
423            remaining -= consumed_here;
424            // cursor.next_entry_marker(Some(&mut flush_marker));
425        }
426
427        cursor.get_node_mut().flush_metric_update(&mut flush_marker);
428    }
429
430    /// Replace the range from cursor..cursor + replaced_len with new_entry.
431    pub unsafe fn unsafe_replace_range_notify<N>(cursor: &mut UnsafeCursor<E, I, IE, LE>, new_entry: E, notify: N)
432        where N: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>) {
433
434        let mut flush_marker = I::Update::default();
435        Self::replace_range_internal(cursor, new_entry.len(), new_entry, &mut flush_marker, notify);
436        cursor.get_node_mut().flush_metric_update(&mut flush_marker);
437        // cursor.compress_node();
438    }
439
440    unsafe fn replace_range_internal<N>(cursor: &mut UnsafeCursor<E, I, IE, LE>, mut replaced_len: usize, new_entry: E, flush_marker: &mut I::Update, mut notify: N)
441        where N: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>) {
442
443        let node = cursor.node.as_mut();
444
445        if cursor.idx >= node.len_entries() {
446            // The cursor already points past the end of the entry.
447            cursor.roll_to_next_entry();
448            Self::insert_internal(&[new_entry], cursor, flush_marker, &mut notify);
449            return;
450        }
451
452        // Dirty.
453        // if node.num_entries >= cursor.idx as u8 {
454        //     // The only way this can happen normally is by creating a cursor at the end of the
455        //     // document. So we're inserting, not replacing.
456        //     self.insert_internal(&[new_entry], &mut cursor, flush_marker, &mut notify);
457        // }
458
459        let entry = &mut node.data[cursor.idx];
460        let entry_len = entry.len();
461
462        // This is awful. We're just going to have to go case by case.
463
464        // If we can just append the new entry here, do that and delete.
465        if cursor.offset == entry_len && entry.can_append(&new_entry) {
466            assert!(cursor.offset > 0);
467            notify(new_entry, cursor.node);
468            I::increment_marker(flush_marker, &new_entry);
469            entry.append(new_entry);
470            cursor.offset += new_entry.len();
471
472            Self::delete_internal(cursor, replaced_len, flush_marker, &mut notify);
473            return;
474        }
475
476        if !cursor.roll_to_next_entry() { // Only valid because flush_marker is empty here.
477            debug_assert_eq!(*flush_marker, I::Update::default());
478
479            // We've reached the end of the tree. Can't replace more, so we just insert here.
480            Self::insert_internal(&[new_entry], cursor, flush_marker, &mut notify);
481            return;
482        }
483
484        let mut node = cursor.node.as_mut();
485        let mut entry = &mut node.data[cursor.idx];
486        let mut entry_len = entry.len();
487
488        if cursor.offset > 0 {
489            if cursor.offset + replaced_len < entry_len {
490                // We're replacing a strict subset. Delegate to replace_entry[a, new, c].
491                let mut a = *entry;
492                a.truncate(cursor.offset);
493
494                let mut c = *entry;
495                c.truncate_keeping_right(cursor.offset + replaced_len);
496                let c_len = c.len();
497
498                // This will update flush_marker for us.
499                Self::replace_entry(cursor, &[a, new_entry, c], flush_marker, &mut notify);
500
501                // Move the cursor back to be pointing at the end of new_entry.
502                cursor.move_back_by_offset(c_len, Some(flush_marker));
503                return;
504            } else {
505                // Remove (truncate) the remainder of this entry. Then continue.
506                let removed = entry.truncate(cursor.offset);
507                I::decrement_marker(flush_marker, &removed);
508                replaced_len -= entry_len - cursor.offset;
509                debug_assert_eq!(entry_len - cursor.offset, removed.len());
510
511                if replaced_len == 0 || !cursor.next_entry_marker(Some(flush_marker)) {
512                    // Only inserting remains.
513                    Self::insert_internal(&[new_entry], cursor, flush_marker, &mut notify);
514                    return;
515                }
516
517                // Could check for appending in this case, but its unlikely given we've just
518                // truncated. (Unless we're replacing like for like).
519                node = cursor.node.as_mut();
520                entry = &mut node.data[cursor.idx];
521                entry_len = entry.len();
522            }
523        }
524
525        debug_assert_eq!(cursor.offset, 0);
526
527        if replaced_len >= entry_len {
528            // Replace this item inline.
529            // Note that even if the size hasn't changed, they might have different character
530            // sizes or something like that.
531            I::decrement_marker(flush_marker, entry);
532            I::increment_marker(flush_marker, &new_entry);
533            notify(new_entry, cursor.node);
534            cursor.offset = new_entry.len();
535            *cursor.get_raw_entry_mut() = new_entry;
536
537            if replaced_len > entry_len {
538                // Delete any extra trailing length.
539                cursor.next_entry_marker(Some(flush_marker));
540                Self::delete_internal(cursor, replaced_len - entry_len, flush_marker, &mut notify);
541            } // Otherwise we're done.
542        } else { // replaced_len < entry_len
543            // Replace this item with [new, remainder].
544            let mut remainder = *entry;
545            let remainder = remainder.truncate(replaced_len);
546            let rem_len = remainder.len();
547            Self::replace_entry(cursor, &[new_entry, remainder], flush_marker, &mut notify);
548            cursor.move_back_by_offset(rem_len, Some(flush_marker));
549        }
550    }
551
552    /// Internal method to remove whole entries inside the current leaf. Could be moved into Leaf.
553    /// It doesn't really make sense to take a &Self here.
554    ///
555    /// This method requires that the passed cursor is at the start of an item. (cursor.offset = 0).
556    ///
557    /// We return a tuple of (should_iterate, the number of remaining items to delete).
558    /// If should_iterate is true, keep calling this in a loop. (Eh I need a better name for that
559    /// variable).
560    unsafe fn delete_entry_range(cursor: &mut UnsafeCursor<E, I, IE, LE>, mut del_items: usize, flush_marker: &mut I::Update) -> (bool, usize) {
561        // This method only deletes whole items.
562        debug_assert_eq!(cursor.offset, 0);
563        debug_assert!(del_items > 0);
564
565        let mut node = cursor.get_node_mut();
566        // If the cursor is at the end of the leaf, flush and roll.
567        if cursor.idx >= node.num_entries as usize {
568            node.flush_metric_update(flush_marker);
569            // If we reach the end of the tree, discard trailing deletes.
570            if !cursor.traverse_forward() { return (false, 0); }
571            node = cursor.get_node_mut();
572        }
573
574        if cursor.idx >= LE { unreachable_unchecked(); }
575        let start_range = cursor.idx;
576        let mut end_range = cursor.idx;
577
578        // 1. Find the end index to remove
579        let len_entries = node.len_entries();
580        // let mut node = unsafe { &mut *cursor.node.as_ptr() };
581        while end_range < len_entries && del_items > 0 {
582            let entry = node.data[end_range];
583            let entry_len = entry.len();
584            if entry_len <= del_items {
585                I::decrement_marker(flush_marker, &entry);
586                del_items -= entry_len;
587                end_range += 1;
588            } else {
589                break;
590            }
591        }
592
593        if start_range == 0 && end_range == len_entries && !node.has_root_as_parent() {
594            // Remove the entire leaf from the tree.
595            node.flush_metric_update(flush_marker);
596
597            let node = cursor.node;
598            let has_next = cursor.traverse_forward();
599            if !has_next {
600                // This is weird and hacky but - we've just deleted the last item in the tree.
601                // If the cursor is still pointing to this element afterwards, the cursor will
602                // be invalid. So instead I'll move the cursor to the end of the previous item.
603                //
604                // If this is the only item, the cursor will stay here. (traverse_backward
605                // returns false). And the item itself will end up being reused by the
606                // NodeLeaf::remove() logic.
607                //
608                // The resulting behaviour of all this is tested by the fuzzer. If any of these
609                // assumptions break later, the tests should catch it.
610                cursor.traverse_backwards();
611                del_items = 0; // There's nothing remaining to delete.
612            }
613
614            NodeLeaf::remove(node);
615            (has_next, del_items)
616        } else if end_range > start_range {
617            // Delete from [start_range..end_range)
618            // println!("Delete entry range from {} to {} (m: {:?})", start_range, end_range, flush_marker);
619            let len_entries = node.len_entries();
620            let tail_count = len_entries - end_range;
621            if tail_count > 0 {
622                node.data.copy_within(end_range..len_entries, start_range);
623            }
624            node.num_entries = (start_range + tail_count) as u8;
625
626            // If the result is to remove all entries, the leaf should have been removed instead.
627            debug_assert!(node.num_entries > 0 || node.parent.is_root());
628
629            // This is unnecessary but for some total magic reason, disabling this results in a
630            // performance regression.
631            // #[cfg(debug_assertions)]
632            node.data[start_range + tail_count..].fill(E::default());
633
634            // TODO: And rebalance if the node is now less than half full.
635            (true, del_items)
636        } else {
637            (false, del_items)
638        }
639    }
640
641    unsafe fn delete_internal<N>(cursor: &mut UnsafeCursor<E, I, IE, LE>, mut del_items: usize, flush_marker: &mut I::Update, notify: &mut N)
642        where N: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>) {
643
644        if del_items == 0 { return; }
645
646        // First trim the current element.
647        if cursor.offset > 0 {
648            let node = cursor.node.as_mut();
649            let entry = &mut node.data[cursor.idx];
650            let entry_len = entry.len();
651
652            let remaining_len = entry_len - cursor.offset;
653            if remaining_len > 0 {
654                if remaining_len <= del_items {
655                    // Simply truncate and discard the rest of this entry.
656                    I::decrement_marker(flush_marker, &entry.truncate(cursor.offset));
657                    del_items -= remaining_len;
658                    if del_items == 0 { return; }
659                } else { // remaining_len > del_items
660                    let mut remainder = entry.truncate(cursor.offset);
661                    I::decrement_marker(flush_marker, &remainder);
662
663                    remainder.truncate_keeping_right(del_items);
664
665                    // And insert the rest, if there are any. I'm using insert() to do this because
666                    // we don't want our cursor changed as a result of the insert. This also makes
667                    // a fresh flush marker, but that's not a big deal.
668
669                    // The code below is equivalent to, but marginally faster than:
670                    // self.insert(cursor.clone(), remainder, notify);
671
672                    let mut c2 = cursor.clone();
673                    Self::insert_internal(&[remainder], &mut c2, flush_marker, notify);
674                    c2.get_node_mut().flush_metric_update(flush_marker);
675
676                    return;
677                }
678            }
679
680            // If we've run out of items in the tree to delete, silently return.
681            if !cursor.next_entry_marker(Some(flush_marker)) { return; }
682        }
683
684        debug_assert!(del_items > 0);
685        debug_assert_eq!(cursor.offset, 0);
686
687        // Ok, we're at the start of an entry. Scan and delete entire entries from this leaf.
688
689        while del_items > 0 {
690            let (iterate, num) = Self::delete_entry_range(cursor, del_items, flush_marker);
691            del_items = num;
692            if !iterate { break; }
693            // delete_entry_range only deletes from the current item each iteration.
694        }
695
696
697        let node = cursor.node.as_mut();
698        if del_items > 0 {
699            // Trim the final entry.
700            //
701            // Note this code doesn't handle the case when del_items > 0 but we're at the end of the
702            // tree. Thats currently impossible given the code in delete_entry_range() according to the
703            // fuzzer, so its probably not something to be concerned by.
704
705            // let node = unsafe { cursor.get_node_mut() };
706            debug_assert!(cursor.idx < node.len_entries());
707            debug_assert!(node.data[cursor.idx].len() > del_items);
708
709            let trimmed = node.data[cursor.idx].truncate_keeping_right(del_items);
710            I::decrement_marker(flush_marker, &trimmed);
711        } else if cursor.idx >= node.len_entries() {
712            debug_assert_eq!(cursor.offset, 0);
713            if cursor.idx == 0 {
714                // We've removed all items in the tree.
715                cursor.offset = usize::MAX;
716                debug_assert!(node.parent.is_root());
717            } else {
718                cursor.idx -= 1;
719                cursor.offset = node.data[cursor.idx].len();
720            }
721        }
722    }
723
724    /// Delete the specified number of items from the b-tree at the cursor.
725    /// Cursor may be modified to point to the start of the next item.
726    pub unsafe fn unsafe_delete_notify<F>(cursor: &mut UnsafeCursor<E, I, IE, LE>, del_items: usize, mut notify: F)
727    where F: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>)
728    {
729        let mut marker = I::Update::default();
730        Self::delete_internal(cursor, del_items, &mut marker, &mut notify);
731        cursor.get_node_mut().flush_metric_update(&mut marker);
732    }
733
734    pub fn delete_at_start_notify<F>(self: &mut Pin<Box<Self>>, del_items: usize, mut notify: F)
735    where F: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>)
736    {
737        let mut marker = I::Update::default();
738        let mut cursor = self.unsafe_cursor_at_start();
739        unsafe {
740            Self::delete_internal(&mut cursor, del_items, &mut marker, &mut notify);
741            cursor.get_node_mut().flush_metric_update(&mut marker);
742        }
743    }
744
745    pub fn delete_at_start(self: &mut Pin<Box<Self>>, del_items: usize) {
746        self.delete_at_start_notify(del_items, null_notify);
747    }
748}
749
750impl<E: ContentTraits + Toggleable, I: TreeMetrics<E>, const IE: usize, const LE: usize> ContentTreeRaw<E, I, IE, LE> {
751    pub unsafe fn local_deactivate_notify<F>(self: &mut Pin<Box<Self>>, mut cursor: UnsafeCursor<E, I, IE, LE>, deleted_len: usize, mut notify: F) -> DeleteResult<E>
752    where F: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>)
753    {
754        // println!("local_delete len: {} at cursor {:?}", deleted_len, cursor);
755
756        if cfg!(debug_assertions) {
757            // TODO: Restore this.
758            // let cursor_pos = cursor.count_pos();
759            // assert!(cursor_pos + deleted_len <= self.count);
760        }
761        // dbg!(cursor_pos, self.count);
762
763        // TODO: And this.
764        // let expected_size = self.count - deleted_len;
765
766        let mut result: DeleteResult<E> = SmallVec::default();
767        let mut flush_marker = I::Update::default();
768        let mut delete_remaining = deleted_len;
769        cursor.roll_to_next_entry();
770
771        while delete_remaining > 0 {
772            // We're iterating through entries, marking entries for delete along the way.
773            // debug_assert!(cursor.get_raw_entry().is_valid());
774
775            while cursor.get_raw_entry().is_deactivated() {
776                Self::next_entry_or_panic(&mut cursor, &mut flush_marker);
777            }
778
779            // dbg!(self, delete_remaining, &flush_marker);
780
781            delete_remaining -= Self::unsafe_mutate_entry_internal(|e| {
782                result.push_rle(*e);
783                e.mark_deactivated();
784            }, &mut cursor, delete_remaining, &mut flush_marker, &mut notify).0;
785        }
786        cursor.compress_node();
787
788        // The cursor is potentially after any remainder.
789        cursor.get_node_mut().flush_metric_update(&mut flush_marker);
790
791        if cfg!(debug_assertions) {
792            // self.print_ptr_tree();
793            // self.as_ref().get_ref().check();
794
795            // Check the total size of the tree has grown by len.
796            // assert_eq!(expected_size, self.count);
797        }
798
799        result
800    }
801
802    unsafe fn set_enabled<F>(cursor: &mut UnsafeCursor<E, I, IE, LE>, max_len: usize, want_enabled: bool, notify: F) -> (usize, bool)
803        where F: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>) {
804
805        cursor.roll_to_next_entry();
806        let entry = cursor.get_raw_entry();
807
808        if entry.is_activated() != want_enabled {
809            // The region could be in the middle of an item and that has all sorts of complexity.
810            // Just delegate to mutate_entry above, which will take care of all that jazz.
811            //
812            // Even though we're just editing an item here, the item could be split as a result,
813            // so notify may end up called.
814            let (amt_modified, _) = Self::unsafe_mutate_single_entry_notify(|e| {
815                if want_enabled { e.mark_activated(); } else { e.mark_deactivated(); }
816            }, cursor, max_len, notify);
817
818            (amt_modified, true)
819        } else {
820            // The range has already been activated / deactivated.
821            (max_len.min(entry.len() - cursor.offset), false)
822        }
823    }
824
825    /// Deactivate up to max_deleted_len from the marker tree, at the location specified by cursor.
826    /// We will always process at least one item. Consumers of this API should call this in a loop.
827    ///
828    /// If the entry is already marked as deleted, unlike local_deactivate, this method does
829    /// nothing. local_deactivate will skip over deleted items and delete something else.
830    ///
831    /// Returns the number of items we tried to deactivate, and whether we were successful.
832    /// (eg (1, true) means we marked 1 item for deletion. (2, false) means we skipped past 2 items
833    /// which were already deactivated.
834    ///
835    /// TODO: It might be cleaner to make the caller check for deleted items if we return 0.
836    ///
837    /// TODO: Consider returning / mutating the cursor. Subsequent items will probably be in this
838    /// node. It would be marginally faster to find a cursor using a hint, and subsequent deletes
839    /// in the txn we're applying will usually be in this node (usually the next item in this node).
840    pub unsafe fn unsafe_remote_deactivate_notify<F>(cursor: &mut UnsafeCursor<E, I, IE, LE>, max_deleted_len: usize, notify: F) -> (usize, bool)
841    where F: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>)
842    {
843        Self::set_enabled(cursor, max_deleted_len, false, notify)
844    }
845
846    pub unsafe fn unsafe_remote_reactivate_notify<F>(cursor: &mut UnsafeCursor<E, I, IE, LE>, max_len: usize, notify: F) -> (usize, bool)
847    where F: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>)
848    {
849        Self::set_enabled(cursor, max_len, true, notify)
850    }
851}
852
853impl<E: ContentTraits, I: FindOffset<E>, const IE: usize, const LE: usize> ContentTreeRaw<E, I, IE, LE> {
854    // TODO: All these methods could just use self.mut_cursor_at...
855    pub fn insert_at_offset_notify<F>(self: &mut Pin<Box<Self>>, pos: usize, new_entry: E, notify: F)
856        where F: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>)
857    {
858        let mut cursor = self.unsafe_cursor_at_offset_pos(pos, true);
859        unsafe { Self::unsafe_insert_notify(&mut cursor, new_entry, notify); }
860    }
861
862    pub fn insert_at_offset(self: &mut Pin<Box<Self>>, pos: usize, new_entry: E) {
863        let mut cursor = self.unsafe_cursor_at_offset_pos(pos, true);
864        unsafe { Self::unsafe_insert_notify(&mut cursor, new_entry, null_notify); }
865    }
866
867    pub fn replace_range_at_offset_notify<N>(self: &mut Pin<Box<Self>>, offset: usize, new_entry: E, notify: N)
868        where N: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>)
869    {
870        let mut cursor = self.unsafe_cursor_at_offset_pos(offset, true);
871        unsafe { Self::unsafe_replace_range_notify(&mut cursor, new_entry, notify); }
872    }
873
874    pub fn replace_range_at_offset(self: &mut Pin<Box<Self>>, offset: usize, new_entry: E) {
875        let mut cursor = self.unsafe_cursor_at_offset_pos(offset, true);
876        unsafe { Self::unsafe_replace_range_notify(&mut cursor, new_entry, null_notify); }
877    }
878
879    pub fn delete_at_offset_notify<F>(self: &mut Pin<Box<Self>>, pos: usize, del_items: usize, notify: F)
880        where F: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>)
881    {
882        let mut cursor = self.unsafe_cursor_at_offset_pos(pos, false);
883        unsafe { Self::unsafe_delete_notify(&mut cursor, del_items, notify); }
884    }
885
886    pub fn delete_at_offset(self: &mut Pin<Box<Self>>, pos: usize, del_items: usize) {
887        let mut cursor = self.unsafe_cursor_at_offset_pos(pos, false);
888        unsafe { Self::unsafe_delete_notify(&mut cursor, del_items, null_notify); }
889    }
890}
891
892impl<E: ContentTraits + ContentLength, I: FindContent<E>, const IE: usize, const LE: usize> ContentTreeRaw<E, I, IE, LE> {
893    pub fn insert_at_content_notify<F>(self: &mut Pin<Box<Self>>, pos: usize, new_entry: E, notify: F)
894        where F: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>)
895    {
896        let mut cursor = self.unsafe_cursor_at_content_pos(pos, true);
897        unsafe { Self::unsafe_insert_notify(&mut cursor, new_entry, notify); }
898    }
899
900    pub fn insert_at_content(self: &mut Pin<Box<Self>>, pos: usize, new_entry: E) {
901        let mut cursor = self.unsafe_cursor_at_content_pos(pos, true);
902        unsafe { Self::unsafe_insert_notify(&mut cursor, new_entry, null_notify); }
903    }
904
905    pub fn replace_range_at_content_notify<N>(self: &mut Pin<Box<Self>>, pos: usize, new_entry: E, notify: N)
906        where N: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>)
907    {
908        let mut cursor = self.unsafe_cursor_at_content_pos(pos, true);
909        unsafe { Self::unsafe_replace_range_notify(&mut cursor, new_entry, notify); }
910    }
911    pub fn replace_range_at_content(self: &mut Pin<Box<Self>>, pos: usize, new_entry: E) {
912        let mut cursor = self.unsafe_cursor_at_content_pos(pos, true);
913        unsafe { Self::unsafe_replace_range_notify(&mut cursor, new_entry, null_notify); }
914    }
915
916    pub fn delete_at_content_notify<F>(self: &mut Pin<Box<Self>>, pos: usize, del_items: usize, notify: F)
917        where F: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>)
918    {
919        let mut cursor = self.unsafe_cursor_at_content_pos(pos, false);
920        unsafe { Self::unsafe_delete_notify(&mut cursor, del_items, notify); }
921    }
922    pub fn delete_at_content(self: &mut Pin<Box<Self>>, pos: usize, del_items: usize) {
923        let mut cursor = self.unsafe_cursor_at_content_pos(pos, false);
924        unsafe { Self::unsafe_delete_notify(&mut cursor, del_items, null_notify); }
925    }
926}
927
928impl<E: ContentTraits + ContentLength + Toggleable, I: FindContent<E>, const IE: usize, const LE: usize> ContentTreeRaw<E, I, IE, LE> {
929    pub fn local_deactivate_at_content_notify<F>(self: &mut Pin<Box<Self>>, offset: usize, deleted_len: usize, notify: F) -> DeleteResult<E>
930        where F: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>)
931    {
932        let cursor = self.unsafe_cursor_at_content_pos(offset, false);
933        unsafe { self.local_deactivate_notify(cursor, deleted_len, notify) }
934    }
935}
936
937impl<E: ContentTraits, I: TreeMetrics<E>, const IE: usize, const LE: usize> NodeLeaf<E, I, IE, LE> {
938
939    /// Split this leaf node at the specified index, so 0..idx stays and idx.. moves to a new node.
940    ///
941    /// The new node has additional `padding` empty items at the start of its list.
942    fn split_at<F>(&mut self, idx: usize, padding: usize, notify: &mut F) -> NonNull<NodeLeaf<E, I, IE, LE>>
943        where F: FnMut(E, NonNull<NodeLeaf<E, I, IE, LE>>)
944    {
945        // println!("split_at {} {}", idx, padding);
946        unsafe {
947            // TODO(optimization): We're currently copying / moving everything *after* idx. If idx
948            // is small, we could instead move everything before idx - which would save a bunch of
949            // calls to notify and save us needing to fix up a bunch of parent pointers. More work
950            // here, but probably less work overall.
951
952            let mut new_node = Self::new(self.next); // The new node has a danging parent pointer
953            let new_filled_len = self.len_entries() - idx;
954            let new_len = new_filled_len + padding;
955            debug_assert!(new_len <= LE);
956
957            if new_filled_len > 0 {
958                ptr::copy_nonoverlapping(&self.data[idx], &mut new_node.data[padding], new_filled_len);
959            }
960
961            new_node.num_entries = new_len as u8; // Not including padding!
962
963            // zero out the old entries
964            // let mut stolen_length: usize = 0;
965            let mut stolen_length = I::Value::default();
966            // dbg!(&self.data);
967            for e in &mut self.data[idx..self.num_entries as usize] {
968                I::increment_offset(&mut stolen_length, e);
969                // stolen_length += e.content_len();
970                *e = E::default();
971            }
972            self.num_entries = idx as u8;
973
974            // eprintln!("split_at idx {} stolen_length {:?} self {:?}", idx, stolen_length, &self);
975
976            let mut new_node_boxed = Box::pin(new_node);
977
978            // This is the pointer to the new item we'll end up returning.
979            let new_leaf_ptr = NonNull::new_unchecked(new_node_boxed.as_mut().get_unchecked_mut());
980            self.next = Some(new_leaf_ptr);
981
982            for e in &new_node_boxed.as_ref().data[padding..new_len] {
983                notify(*e, new_leaf_ptr);
984            }
985
986            insert_after(self.parent, Node::Leaf(new_node_boxed), NodePtr::Leaf(NonNull::new_unchecked(self)), stolen_length);
987
988            // TODO: It would be cleaner to return a Pin<&mut NodeLeaf> here instead of the pointer.
989            new_leaf_ptr
990        }
991    }
992
993    /// Remove this leaf from the tree. Cursor positioned after leaf.
994    ///
995    /// It is invalid to call this on the last node in the tree - which will have the parent as a
996    /// root.
997    unsafe fn remove(self_ptr: NonNull<NodeLeaf<E, I, IE, LE>>) {
998        // I'm really not sure what sort of self reference this method should take. We could take a
999        // Pin<*mut Self> - which feels more correct. Using NonNull<Self> is convenient because of
1000        // cursor, though we'll dereference it anyway so maybe Pin<&mut Self>? O_o
1001        //
1002        // Function is unsafe.
1003        let leaf = self_ptr.as_ref();
1004        debug_assert!(!leaf.has_root_as_parent());
1005
1006        if let Some(mut prev) = leaf.prev_leaf() {
1007            prev.as_mut().next = leaf.next;
1008        }
1009
1010        NodeInternal::remove_leaf(leaf.parent.unwrap_internal(), self_ptr);
1011    }
1012}
1013
1014impl<E: ContentTraits, I: TreeMetrics<E>, const IE: usize, const LE: usize> NodeInternal<E, I, IE, LE> {
1015    unsafe fn slice_out(&mut self, child: NodePtr<E, I, IE, LE>) -> Node<E, I, IE, LE> {
1016        if self.children[1].is_none() {
1017            // short circuit.
1018
1019            // If we're in this situation, children[0] must be Some(child).
1020            debug_assert_eq!(self.find_child(child).unwrap(), 0);
1021
1022            self.children[0].take().unwrap()
1023        } else {
1024            let idx = self.find_child(child).unwrap();
1025            let num_children = self.count_children();
1026
1027            let removed = self.children[idx].take().unwrap();
1028
1029            let count = num_children - idx - 1;
1030            if count > 0 {
1031                ptr::copy(
1032                    &self.children[idx + 1],
1033                    &mut self.children[idx],
1034                    count
1035                );
1036
1037                self.metrics.copy_within(idx + 1..num_children, idx);
1038            }
1039
1040            // This pointer has been moved. We need to set its entry to None without dropping it.
1041            std::mem::forget(self.children[num_children - 1].take());
1042
1043            removed
1044        }
1045    }
1046
1047    unsafe fn remove_leaf(mut self_ptr: NonNull<NodeInternal<E, I, IE, LE>>, child: NonNull<NodeLeaf<E, I, IE, LE>>) {
1048        let spare = self_ptr.as_mut().slice_out(NodePtr::Leaf(child));
1049        Self::ripple_delete(self_ptr, spare);
1050    }
1051
1052    unsafe fn ripple_delete(mut self_ptr: NonNull<NodeInternal<E, I, IE, LE>>, mut spare_leaf: Node<E, I, IE, LE>) {
1053        debug_assert!(spare_leaf.is_leaf());
1054
1055        let self_ref = self_ptr.as_mut();
1056
1057        if self_ref.children[0].is_none() {
1058            // This child is empty. Remove it from its parent.
1059            match self_ref.parent {
1060                ParentPtr::Root(mut root) => {
1061                    // We're removing the last item from the tree. The tree must always have at
1062                    // least 1 item, so we need to replace the single child. We could replace it
1063                    // with a fresh node, which would be simpler, but doing that would mess up the
1064                    // cursor (which we don't have access to here). And it would require an
1065                    // additional allocation - though this is rare anyway.
1066                    let mut root = root.as_mut();
1067                    spare_leaf.set_parent(root.to_parent_ptr());
1068                    // spare_leaf.unwrap_leaf_mut().get_unchecked_mut().num_entries = 0;
1069                    spare_leaf.unwrap_leaf_mut().get_unchecked_mut().clear_all();
1070                    root.root = spare_leaf;
1071                }
1072                ParentPtr::Internal(mut parent) => {
1073                    // Remove recursively.
1074                    parent.as_mut().slice_out(NodePtr::Internal(self_ptr));
1075                    Self::ripple_delete(parent, spare_leaf);
1076                }
1077            }
1078        }
1079    }
1080}
1081
1082
1083// I'm really not sure where to put these methods. Its not really associated with
1084// any of the tree implementation methods. This seems like a hidden spot. Maybe
1085// content-tree? I could put it in impl ParentPtr? I dunno...
1086unsafe fn insert_after<E: ContentTraits, I: TreeMetrics<E>, const INT_ENTRIES: usize, const LEAF_ENTRIES: usize>(
1087    mut parent: ParentPtr<E, I, INT_ENTRIES, LEAF_ENTRIES>,
1088    mut inserted_leaf_node: Node<E, I, INT_ENTRIES, LEAF_ENTRIES>,
1089    mut insert_after: NodePtr<E, I, INT_ENTRIES, LEAF_ENTRIES>,
1090    mut stolen_length: I::Value) {
1091    // println!("insert_after {:?} leaf {:#?} parent {:#?}", stolen_length, inserted_leaf_node, parent);
1092    // Ok now we need to walk up the tree trying to insert. At each step
1093    // we will try and insert inserted_node into parent next to old_node
1094    // (topping out at the head).
1095    loop {
1096        // First try and simply emplace in the new element in the parent.
1097        if let ParentPtr::Internal(mut n) = parent {
1098            let parent_ref = n.as_ref();
1099            let count = parent_ref.count_children();
1100            if count < INT_ENTRIES {
1101                // Great. Insert the new node into the parent and return.
1102                inserted_leaf_node.set_parent(ParentPtr::Internal(n));
1103
1104                let old_idx = parent_ref.find_child(insert_after).unwrap();
1105                let new_idx = old_idx + 1;
1106
1107                let parent_ref = n.as_mut();
1108                // dbg!(&parent_ref.data[old_idx].0, stolen_length);
1109                parent_ref.metrics[old_idx] -= stolen_length;
1110                parent_ref.splice_in(new_idx, stolen_length, inserted_leaf_node);
1111
1112                // eprintln!("1");
1113                return;
1114            }
1115        }
1116
1117        // Ok so if we've gotten here we need to make a new internal
1118        // node filled with inserted_node, then move and all the goodies
1119        // from ParentPtr.
1120        match parent {
1121            ParentPtr::Root(mut r) => {
1122                // This is the simpler case. The new root will be a new
1123                // internal node containing old_node and inserted_node.
1124                let new_root = Node::Internal(NodeInternal::new_with_parent(ParentPtr::Root(r)));
1125                let mut old_root = mem::replace(&mut r.as_mut().root, new_root);
1126
1127                // *inserted_node.get_parent_mut() = parent_ptr;
1128
1129                let root = r.as_mut();
1130                let mut count = root.count;
1131                let mut new_internal_root = root.root.unwrap_internal_mut();
1132                // let parent_ptr = ParentPtr::Internal(NonNull::new_unchecked(new_root_ref));
1133                let parent_ptr = new_internal_root.as_ref().to_parent_ptr();
1134
1135                // Reassign parents for each node
1136                old_root.set_parent(parent_ptr);
1137                inserted_leaf_node.set_parent(parent_ptr);
1138
1139                count -= stolen_length;
1140                new_internal_root.as_mut().set_entry(0, count, Some(old_root));
1141                new_internal_root.as_mut().set_entry(1, stolen_length, Some(inserted_leaf_node));
1142
1143                // r.as_mut().print_ptr_tree();
1144                return;
1145            },
1146
1147            ParentPtr::Internal(mut n) => {
1148                // And this is the complex case. We have MAX_CHILDREN+1
1149                // items (in some order) to distribute between two
1150                // internal nodes (one old, one new). Then we iterate up
1151                // the tree.
1152                let left_sibling = n.as_ref();
1153                parent = left_sibling.parent; // For next iteration through the loop.
1154                debug_assert!(left_sibling.count_children() == INT_ENTRIES);
1155
1156                // let mut right_sibling = NodeInternal::new_with_parent(parent);
1157                let mut right_sibling_box = Node::Internal(NodeInternal::new_with_parent(parent));
1158                let mut right_sibling = right_sibling_box.unwrap_internal_mut();
1159                let old_idx = left_sibling.find_child(insert_after).unwrap();
1160
1161                let left_sibling = n.as_mut();
1162                left_sibling.metrics[old_idx] -= stolen_length;
1163                let mut new_stolen_length = I::Value::default();
1164                // Dividing this into cases makes it easier to reason
1165                // about.
1166                if old_idx < INT_ENTRIES /2 {
1167                    // Move all items from MAX_CHILDREN/2..MAX_CHILDREN
1168                    // into right_sibling, then splice inserted_node into
1169                    // old_parent.
1170                    for i in 0..INT_ENTRIES /2 {
1171                        let ii = i + INT_ENTRIES /2;
1172                        // let c = mem::replace(&mut left_sibling.index[ii], I::IndexOffset::default());
1173                        let c = mem::take(&mut left_sibling.metrics[ii]);
1174                        // let e = mem::replace(&mut left_sibling.children[ii], None);
1175                        let e = mem::take(&mut left_sibling.children[ii]);
1176                        if let Some(mut e) = e {
1177                            e.set_parent(right_sibling.as_ref().to_parent_ptr());
1178                            new_stolen_length += c;
1179                            right_sibling.as_mut().set_entry(i, c, Some(e));
1180                        }
1181
1182                    }
1183
1184                    let new_idx = old_idx + 1;
1185                    inserted_leaf_node.set_parent(ParentPtr::Internal(NonNull::new_unchecked(left_sibling)));
1186                    left_sibling.splice_in(new_idx, stolen_length, inserted_leaf_node);
1187                } else {
1188                    // The new element is in the second half of the
1189                    // group.
1190                    let new_idx = old_idx - INT_ENTRIES /2 + 1;
1191
1192                    inserted_leaf_node.set_parent(right_sibling.as_ref().to_parent_ptr());
1193                    let mut new_entry = (stolen_length, Some(inserted_leaf_node));
1194                    new_stolen_length = stolen_length;
1195
1196                    let mut src = INT_ENTRIES /2;
1197                    for dest in 0..=INT_ENTRIES /2 {
1198                        if dest == new_idx {
1199                            right_sibling.as_mut().set_entry(dest, mem::take(&mut new_entry.0), mem::take(&mut new_entry.1));
1200                        } else {
1201                            let c = mem::take(&mut left_sibling.metrics[src]);
1202                            let e = mem::take(&mut left_sibling.children[src]);
1203                            // let (c, e) = mem::replace(&mut left_sibling.data[src], (I::IndexOffset::default(), None));
1204
1205                            if let Some(mut e) = e {
1206                                e.set_parent(right_sibling.as_ref().to_parent_ptr());
1207                                new_stolen_length += c;
1208                                right_sibling.as_mut().set_entry(dest, c, Some(e));
1209                                src += 1;
1210                            } else { break; }
1211                        }
1212                    }
1213                    debug_assert!(new_entry.1.is_none());
1214                }
1215
1216                insert_after = NodePtr::Internal(n);
1217                inserted_leaf_node = right_sibling_box;
1218                stolen_length = new_stolen_length;
1219                // And iterate up the tree.
1220            },
1221        };
1222    }
1223}
1224
1225#[cfg(test)]
1226mod tests {
1227    // use std::pin::Pin;
1228    use super::*;
1229    use crate::testrange::TestRange;
1230
1231    #[test]
1232    fn splice_insert_test() {
1233        let mut tree = ContentTreeRaw::<TestRange, ContentMetrics, DEFAULT_IE, DEFAULT_LE>::new();
1234        let entry = TestRange {
1235            id: 1000,
1236            len: 100,
1237            is_activated: true
1238        };
1239        tree.insert_at_content(15, entry);
1240        tree.check();
1241
1242        let entry = TestRange {
1243            id: 1100,
1244            len: 20,
1245            is_activated: true
1246        };
1247        tree.insert_at_content(15, entry);
1248        tree.check();
1249
1250        // println!("{:#?}", tree);
1251        assert_eq!(tree.raw_iter().collect::<Vec<TestRange>>(), vec![
1252            TestRange { id: 1000, len: 15, is_activated: true },
1253            TestRange { id: 1100, len: 20, is_activated: true },
1254            TestRange { id: 1015, len: 85, is_activated: true },
1255        ]);
1256    }
1257
1258    #[test]
1259    fn delete_collapses() {
1260        let mut tree = ContentTreeRaw::<TestRange, ContentMetrics, DEFAULT_IE, DEFAULT_LE>::new();
1261
1262        let entry = TestRange {
1263            id: 1000,
1264            len: 100,
1265            is_activated: true,
1266        };
1267        tree.insert_at_content(0, entry);
1268        assert_eq!(tree.count_entries(), 1);
1269
1270        // I'm going to delete two items in the middle.
1271        tree.local_deactivate_at_content_notify(50, 1, null_notify);
1272        assert_eq!(tree.count_entries(), 3);
1273
1274        // dbg!(&tree);
1275        tree.local_deactivate_at_content_notify(50, 1, null_notify);
1276        // dbg!(&tree);
1277
1278        assert_eq!(tree.raw_iter().collect::<Vec<TestRange>>(), vec![
1279            TestRange { id: 1000, len: 50, is_activated: true },
1280            TestRange { id: 1050, len: 2, is_activated: false },
1281            TestRange { id: 1052, len: 48, is_activated: true },
1282        ]);
1283    }
1284
1285    #[test]
1286    fn backspace_collapses() {
1287        let mut tree = ContentTreeRaw::<TestRange, ContentMetrics, DEFAULT_IE, DEFAULT_LE>::new();
1288
1289        let entry = TestRange {
1290            id: 1000,
1291            len: 100,
1292            is_activated: true,
1293        };
1294        tree.insert_at_content_notify(0, entry, null_notify);
1295        assert_eq!(tree.count_entries(), 1);
1296
1297        // Ok now I'm going to delete the last and second-last elements. We should end up with
1298        // two entries.
1299        tree.local_deactivate_at_content_notify(99, 1, null_notify);
1300        assert_eq!(tree.count_entries(), 2);
1301
1302        tree.local_deactivate_at_content_notify(98, 1, null_notify);
1303        assert_eq!(tree.count_entries(), 2);
1304
1305        assert_eq!(tree.raw_iter().collect::<Vec<TestRange>>(), vec![
1306            TestRange { id: 1000, len: 98, is_activated: true },
1307            TestRange { id: 1098, len: 2, is_activated: false },
1308        ]);
1309        tree.check();
1310    }
1311
1312    #[test]
1313    fn delete_single_item() {
1314        let mut tree = ContentTreeRaw::<TestRange, ContentMetrics, DEFAULT_IE, DEFAULT_LE>::new();
1315        tree.insert_at_start(TestRange { id: 0, len: 10, is_activated: true });
1316
1317        tree.delete_at_start(10);
1318        assert_eq!(tree.len(), 0);
1319        tree.check();
1320    }
1321
1322    #[test]
1323    fn delete_all_items() {
1324        let mut tree = ContentTreeRaw::<TestRange, ContentMetrics, DEFAULT_IE, DEFAULT_LE>::new();
1325        let num = DEFAULT_LE + 1;
1326        for i in 0..num {
1327            tree.insert_at_start_notify(TestRange { id: i as _, len: 10, is_activated: true }, null_notify);
1328        }
1329        // dbg!(&tree);
1330        assert!(!tree.root.is_leaf());
1331
1332        tree.delete_at_start_notify(10 * num, null_notify);
1333        assert_eq!(tree.len(), 0);
1334        tree.check();
1335    }
1336
1337    #[test]
1338    fn delete_past_end() {
1339        let mut tree = ContentTreeRaw::<TestRange, ContentMetrics, DEFAULT_IE, DEFAULT_LE>::new();
1340        tree.insert_at_start_notify(TestRange { id: 10 as _, len: 10, is_activated: true }, null_notify);
1341        tree.delete_at_content_notify(10, 100, null_notify);
1342
1343        assert_eq!(tree.raw_iter().collect::<Vec<TestRange>>(), vec![
1344            TestRange { id: 10, len: 10, is_activated: true },
1345        ]);
1346    }
1347
1348    #[test]
1349    fn push_into_empty() {
1350        let mut tree = ContentTreeRaw::<TestRange, ContentMetrics, DEFAULT_IE, DEFAULT_LE>::new();
1351        tree.push(TestRange { id: 0, len: 10, is_activated: true });
1352    }
1353
1354    #[test]
1355    fn mutation_wrappers() {
1356        let mut tree = ContentTreeRaw::<TestRange, FullMetricsU32, DEFAULT_IE, DEFAULT_LE>::new();
1357        tree.insert_at_content(0, TestRange { id: 0, len: 10, is_activated: true });
1358        assert_eq!(tree.offset_len(), 10);
1359        assert_eq!(tree.content_len(), 10);
1360
1361        tree.replace_range_at_content(3, TestRange { id: 100, len: 3, is_activated: false });
1362        assert_eq!(tree.offset_len(), 10);
1363        assert_eq!(tree.content_len(), 7);
1364
1365        assert_eq!(tree.at_content(4), Some((7, true)));
1366        assert_eq!(tree.at_offset(4), Some((101, false)));
1367
1368        // TODO: Eh and do the others - insert_at_offset, replace_range_at_offset, etc.
1369        tree.delete_at_offset(5, 3);
1370        assert_eq!(tree.offset_len(), 7);
1371        assert_eq!(tree.content_len(), 5);
1372
1373        tree.delete_at_content(0, 1);
1374        assert_eq!(tree.offset_len(), 6);
1375        assert_eq!(tree.content_len(), 4);
1376    }
1377
1378    #[test]
1379    fn mutate_range() {
1380        let mut tree = ContentTreeRaw::<TestRange, FullMetricsU32, DEFAULT_IE, DEFAULT_LE>::new();
1381        tree.push(TestRange { id: 0, len: 10, is_activated: true });
1382
1383        unsafe {
1384            let mut cursor = tree.unsafe_cursor_at_offset_pos(5, false);
1385            ContentTreeRaw::unsafe_mutate_entries_notify(|r| {
1386                assert_eq!(r, &TestRange { id: 5, len: 2, is_activated: true });
1387
1388                r.len = 1;
1389            }, &mut cursor, 2, null_notify);
1390        }
1391        // Tree now contains [0..5] [7..10].
1392        // dbg!(&tree);
1393        unsafe {
1394            let mut cursor = tree.unsafe_cursor_at_offset_pos(5, false);
1395            ContentTreeRaw::unsafe_mutate_entries_notify(|r| {
1396                // We should get 5 then 7.
1397                assert_eq!(r.len, 1);
1398                assert!(r.id == 5 || r.id == 7);
1399                r.len += 1;
1400            }, &mut cursor, 2, null_notify);
1401        }
1402
1403        // This looks wrong, but its right.
1404        assert_eq!(tree.raw_iter().collect::<Vec<TestRange>>(), vec![
1405            TestRange { id: 0, len: 9, is_activated: true },
1406            TestRange { id: 8, len: 2, is_activated: true },
1407        ]);
1408        // dbg!(&tree);
1409    }
1410}