1use super::*;
2use crate::storage::engine::overflow::OverflowChain;
3
4impl BTree {
5 fn free_chain_if_pointer(&self, stored: &[u8]) -> BTreeResult<()> {
17 if let Some(head) = value_layout::pointer_head(stored) {
18 OverflowChain::new(&self.pager)
19 .free(head)
20 .map_err(value_layout::ValueLayoutError::from)?;
21 }
22 Ok(())
23 }
24 pub fn new(pager: Arc<Pager>) -> Self {
26 Self {
27 retirement_pin: Arc::new(()),
28 pager,
29 root_page_id: RwLock::new(0),
30 rightmost_leaf: RwLock::new(None),
31 writer: parking_lot::ReentrantMutex::new(()),
32 }
33 }
34
35 pub fn with_root(pager: Arc<Pager>, root_page_id: u32) -> Self {
37 Self {
38 retirement_pin: Arc::new(()),
39 pager,
40 root_page_id: RwLock::new(root_page_id),
41 rightmost_leaf: RwLock::new(None),
42 writer: parking_lot::ReentrantMutex::new(()),
43 }
44 }
45
46 pub fn root_page_id(&self) -> u32 {
48 *self
49 .root_page_id
50 .read()
51 .unwrap_or_else(|poisoned| poisoned.into_inner())
52 }
53
54 pub fn is_empty(&self) -> bool {
56 self.root_page_id() == 0
57 }
58
59 pub fn get(&self, key: &[u8]) -> BTreeResult<Option<Vec<u8>>> {
61 let root_id = self.root_page_id();
62 if root_id == 0 {
63 return Ok(None);
64 }
65
66 let (leaf_id, _) = self.find_leaf(root_id, key)?;
68
69 const MAX_RIGHTLINK_HOPS: usize = 32;
78 let mut current_id = leaf_id;
79 for _ in 0..MAX_RIGHTLINK_HOPS {
80 let page = self.pager.read_page(current_id)?;
81
82 match search_leaf(&page, key)? {
83 SearchResult::Found(pos) => {
84 let (_, stored) = read_leaf_cell(&page, pos)?;
85 let value = value_layout::decode(&self.pager, &stored)?;
86 return Ok(Some(value));
87 }
88 SearchResult::NotFound(_) => {
89 let right = leaf_right_sibling(&page);
91 if right != 0 {
92 if let Some(high_key) = leaf_high_key(&page)? {
93 if key > high_key.as_slice() {
94 current_id = right;
96 continue;
97 }
98 }
99 }
100 return Ok(None);
102 }
103 }
104 }
105
106 let (leaf_id, _) = self.find_leaf(self.root_page_id(), key)?;
108 let page = self.pager.read_page(leaf_id)?;
109 match search_leaf(&page, key)? {
110 SearchResult::Found(pos) => {
111 let (_, stored) = read_leaf_cell(&page, pos)?;
112 let value = value_layout::decode(&self.pager, &stored)?;
113 Ok(Some(value))
114 }
115 SearchResult::NotFound(_) => Ok(None),
116 }
117 }
118
119 pub fn insert(&self, key: &[u8], value: &[u8]) -> BTreeResult<()> {
127 let _writer = self.writer.lock();
128 if key.len() > MAX_KEY_SIZE {
129 return Err(BTreeError::KeyTooLarge(key.len()));
130 }
131 let stored = value_layout::encode(&self.pager, value)?;
132 self.insert_encoded(key, &stored)
133 }
134
135 pub(crate) fn insert_encoded(&self, key: &[u8], value: &[u8]) -> BTreeResult<()> {
143 let _writer = self.writer.lock();
144 let root_id = self.root_page_id();
145
146 if root_id == 0 {
148 let mut page = self.pager.allocate_page(PageType::BTreeLeaf)?;
149 clear_leaf_cells(&mut page);
150 insert_into_leaf(&mut page, key, value)?;
151 init_leaf_links(&mut page, 0, 0);
152 page.update_checksum();
153 let new_root = page.page_id();
154 self.pager.write_page(new_root, page)?;
155 *self.root_page_id.write().map_err(|e| {
156 BTreeError::LockPoisoned(format!("insert: root_page_id write lock: {e}"))
157 })? = new_root;
158 return Ok(());
159 }
160
161 let cached = {
166 self.rightmost_leaf
167 .read()
168 .map_err(|e| BTreeError::LockPoisoned(format!("rightmost_leaf read: {e}")))?
169 .clone()
170 };
171 if let Some((cached_page_id, ref high_key)) = cached {
172 if key > high_key.as_slice() {
173 let mut page = self.pager.read_page(cached_page_id)?;
174 let right_sibling = leaf_right_sibling(&page);
178 if right_sibling == 0 {
179 if can_insert_leaf(&page, key, value) {
181 insert_into_leaf(&mut page, key, value)?;
182 let page_id = page.page_id();
186 *self.rightmost_leaf.write().map_err(|e| {
188 BTreeError::LockPoisoned(format!("rightmost_leaf write: {e}"))
189 })? = Some((page_id, key.to_vec()));
190 self.pager.write_page(page_id, page)?;
191 return Ok(());
192 }
193 let (new_leaf, separator_key) = self.split_leaf(&mut page, key, value)?;
196 let new_leaf_id = new_leaf.page_id();
197 page.update_checksum();
198 let page_id = page.page_id();
199 self.pager.write_page(page_id, page.clone())?;
200 self.cache_rightmost_leaf(&new_leaf)?;
202 let (_, path) = self.find_leaf(root_id, &separator_key)?;
205 self.insert_into_parent(path, cached_page_id, &separator_key, new_leaf_id)?;
206 return Ok(());
207 }
208 *self.rightmost_leaf.write().map_err(|e| {
212 BTreeError::LockPoisoned(format!("rightmost_leaf write: {e}"))
213 })? = None;
214 }
215 }
216
217 let (leaf_id, path) = self.find_leaf(root_id, key)?;
219 let mut page = self.pager.read_page(leaf_id)?;
220
221 if let SearchResult::Found(_) = search_leaf(&page, key)? {
223 return Err(BTreeError::DuplicateKey);
224 }
225
226 if can_insert_leaf(&page, key, value) {
228 insert_into_leaf(&mut page, key, value)?;
229 let page_id = page.page_id();
231 if leaf_right_sibling(&page) == 0 {
233 self.cache_rightmost_leaf(&page)?;
234 }
235 self.pager.write_page(page_id, page)?;
236 return Ok(());
237 }
238
239 let (new_leaf, separator_key) = self.split_leaf(&mut page, key, value)?;
241 let new_leaf_id = new_leaf.page_id();
242 page.update_checksum();
243 let page_id = page.page_id();
244 self.pager.write_page(page_id, page.clone())?;
245 self.cache_rightmost_leaf(&new_leaf)?;
247
248 self.insert_into_parent(path, page_id, &separator_key, new_leaf_id)?;
250
251 Ok(())
252 }
253
254 pub fn upsert(&self, key: &[u8], value: &[u8]) -> BTreeResult<()> {
266 let _writer = self.writer.lock();
267 let root_id = self.root_page_id();
268 if root_id == 0 {
269 return self.insert(key, value);
270 }
271
272 let new_stored = value_layout::encode(&self.pager, value)?;
277
278 let (leaf_id, _path) = self.find_leaf(root_id, key)?;
279 let mut page = self.pager.read_page(leaf_id)?;
280
281 if let SearchResult::Found(pos) = search_leaf(&page, key)? {
282 let (_, old_value) = read_leaf_cell(&page, pos)?;
283 if new_stored.len() <= old_value.len() {
284 self.free_chain_if_pointer(&old_value)?;
289 overwrite_leaf_value(&mut page, pos, &new_stored)?;
290 let page_id = page.page_id();
291 self.pager.write_page(page_id, page)?;
292 return Ok(());
293 }
294 let _ = self.delete(key);
297 return self.insert_encoded(key, &new_stored);
298 }
299
300 self.insert_encoded(key, &new_stored)
303 }
304
305 pub fn upsert_batch_sorted(&self, items: &[(Vec<u8>, Vec<u8>)]) -> BTreeResult<()> {
316 let _writer = self.writer.lock();
317 if items.is_empty() {
318 return Ok(());
319 }
320 let root_id = self.root_page_id();
321 if root_id == 0 {
322 for (k, v) in items {
323 self.upsert(k, v)?;
324 }
325 return Ok(());
326 }
327
328 let mut current_leaf: Option<(u32, Page, bool)> = None; for (key, value) in items {
330 let (leaf_id, _path) = self.find_leaf(root_id, key)?;
333 if current_leaf.as_ref().map(|(id, _, _)| *id) != Some(leaf_id) {
334 if let Some((id, page, dirty)) = current_leaf.take() {
335 if dirty {
336 self.pager.write_page(id, page)?;
337 }
338 }
339 let page = self.pager.read_page(leaf_id)?;
340 current_leaf = Some((leaf_id, page, false));
341 }
342
343 let applied_in_place = {
349 let (_, page, dirty) = current_leaf.as_mut().expect("set above");
350 if let SearchResult::Found(pos) = search_leaf(page, key)? {
351 let (_, old_value) = read_leaf_cell(page, pos)?;
352 match value_layout::encode(&self.pager, value) {
353 Ok(new_stored) if new_stored.len() <= old_value.len() => {
354 self.free_chain_if_pointer(&old_value)?;
358 overwrite_leaf_value(page, pos, &new_stored)?;
359 *dirty = true;
360 true
361 }
362 _ => false,
363 }
364 } else {
365 false
366 }
367 };
368 if !applied_in_place {
369 if let Some((id, page, dirty)) = current_leaf.take() {
370 if dirty {
371 self.pager.write_page(id, page)?;
372 }
373 }
374 self.upsert(key, value)?;
375 }
376 }
377
378 if let Some((id, page, dirty)) = current_leaf.take() {
379 if dirty {
380 self.pager.write_page(id, page)?;
381 }
382 }
383 Ok(())
384 }
385
386 pub fn bulk_insert_sorted(&self, items: &[(Vec<u8>, Vec<u8>)]) -> BTreeResult<()> {
395 let _writer = self.writer.lock();
396 if items.is_empty() {
397 return Ok(());
398 }
399 for (key, _) in items {
405 if key.len() > MAX_KEY_SIZE {
406 return Err(BTreeError::KeyTooLarge(key.len()));
407 }
408 }
409
410 let mut encoded: Vec<(&[u8], Vec<u8>)> = Vec::with_capacity(items.len());
417 let mut first_oversize: Option<usize> = None;
418 for (key, value) in items {
419 match value_layout::encode(&self.pager, value) {
420 Ok(stored) => encoded.push((key.as_slice(), stored)),
421 Err(value_layout::ValueLayoutError::ValueTooLarge(n)) => {
422 if first_oversize.is_none() {
423 first_oversize = Some(n);
424 }
425 }
426 Err(other) => return Err(other.into()),
427 }
428 }
429
430 let items: Vec<(&[u8], &[u8])> = encoded.iter().map(|(k, v)| (*k, v.as_slice())).collect();
431
432 let mut last_filled_leaf: Option<u32> = None;
440 let mut i = 0;
441 while i < items.len() {
442 let root_id = self.root_page_id();
443 if root_id == 0 {
444 let (k, v) = items[i];
448 self.insert_encoded(k, v)?;
449 i += 1;
450 last_filled_leaf = None;
451 continue;
452 }
453
454 let hint_leaf_id: Option<u32> = if let Some(prev) = last_filled_leaf {
460 let prev_page = self.pager.read_page(prev)?;
461 let sibling = leaf_right_sibling(&prev_page);
462 if sibling != 0 {
463 let sib_page = self.pager.read_page(sibling)?;
464 match leaf_high_key(&sib_page)? {
465 None => Some(sibling), Some(hk)
467 if leaf_right_sibling(&sib_page) == 0 && items[i].0 > hk.as_slice() =>
468 {
469 Some(sibling)
470 }
471 Some(_) => None,
472 }
473 } else {
474 None
475 }
476 } else {
477 None
478 };
479
480 let (leaf_id, _path) = match hint_leaf_id {
481 Some(id) => (id, Vec::new()),
482 None => self.find_leaf(root_id, items[i].0)?,
483 };
484 let mut page = self.pager.read_page(leaf_id)?;
485
486 let mut last_key_in_leaf: Option<Vec<u8>> = {
491 let cell_count = page.cell_count() as usize;
492 if cell_count == 0 {
493 None
494 } else {
495 Some(read_leaf_cell(&page, cell_count - 1)?.0)
496 }
497 };
498
499 let mut inserted = 0usize;
505 while i + inserted < items.len() {
506 let (key, value) = items[i + inserted];
507
508 if let Some(lk) = &last_key_in_leaf {
511 match key.cmp(lk.as_slice()) {
512 Ordering::Greater => {}
513 Ordering::Equal => return Err(BTreeError::DuplicateKey),
514 Ordering::Less => break,
515 }
516 }
517
518 let cell_size = 4 + key.len() + value.len();
523 let slot_end_after =
524 LEAF_SLOT_ARRAY_OFFSET + (page.cell_count() as usize + inserted + 1) * 2;
525 let cells_start = leaf_cells_start(&page);
526 if slot_end_after + cell_size > cells_start {
527 break;
528 }
529
530 let cell_offset = cells_start - cell_size;
535 {
536 let data = page.as_bytes_mut();
537 data[cell_offset..cell_offset + 2]
538 .copy_from_slice(&(key.len() as u16).to_le_bytes());
539 data[cell_offset + 2..cell_offset + 4]
540 .copy_from_slice(&(value.len() as u16).to_le_bytes());
541 data[cell_offset + 4..cell_offset + 4 + key.len()].copy_from_slice(key);
542 data[cell_offset + 4 + key.len()..cell_offset + cell_size]
543 .copy_from_slice(value);
544 }
545 page.set_free_end(cell_offset as u16);
546
547 let new_slot_index = page.cell_count() as usize + inserted;
548 let slot_pos = leaf_slot_offset_for(new_slot_index);
549 {
550 let data = page.as_bytes_mut();
551 data[slot_pos..slot_pos + 2]
552 .copy_from_slice(&(cell_offset as u16).to_le_bytes());
553 }
554
555 last_key_in_leaf = Some(key.to_vec());
556 inserted += 1;
557 }
558
559 if inserted > 0 {
560 let new_count = page.cell_count() as usize + inserted;
561 page.set_cell_count(new_count as u16);
562 page.set_free_start((LEAF_SLOT_ARRAY_OFFSET + new_count * 2) as u16);
563 page.update_checksum();
564 self.cache_rightmost_leaf(&page)?;
565 self.pager.write_page(leaf_id, page)?;
566 i += inserted;
567 last_filled_leaf = Some(leaf_id);
570 } else {
571 let (k, v) = items[i];
578 self.insert_encoded(k, v)?;
579 i += 1;
580 last_filled_leaf = None;
581 }
582 }
583
584 if let Some(n) = first_oversize {
589 return Err(BTreeError::ValueTooLarge(n));
590 }
591
592 Ok(())
593 }
594
595 pub fn delete(&self, key: &[u8]) -> BTreeResult<bool> {
597 let _writer = self.writer.lock();
598 let root_id = self.root_page_id();
599 if root_id == 0 {
600 return Ok(false);
601 }
602
603 let (leaf_id, path) = self.find_leaf(root_id, key)?;
607 let mut current_id = leaf_id;
608 const MAX_RIGHTLINK_HOPS: usize = 32;
609 for _ in 0..MAX_RIGHTLINK_HOPS {
610 let mut page = self.pager.read_page(current_id)?;
611 match search_leaf(&page, key)? {
612 SearchResult::Found(pos) => {
613 let (_, stored) = read_leaf_cell(&page, pos)?;
618 self.free_chain_if_pointer(&stored)?;
619 delete_from_leaf(&mut page, pos)?;
620 page.update_checksum();
621 let page_id = page.page_id();
622 self.pager.write_page(page_id, page.clone())?;
623
624 *self
625 .rightmost_leaf
626 .write()
627 .unwrap_or_else(|e| e.into_inner()) = None;
628
629 if page.cell_count() == 0 && page_id == root_id {
630 self.pager.free_page(root_id)?;
631 *self.root_page_id.write().map_err(|e| {
632 BTreeError::LockPoisoned(format!(
633 "delete: root_page_id write lock: {e}"
634 ))
635 })? = 0;
636 } else {
637 self.rebalance_leaf(current_id, path)?;
638 }
639 return Ok(true);
640 }
641 SearchResult::NotFound(_) => {
642 let right = leaf_right_sibling(&page);
643 if right != 0 {
644 if let Some(high_key) = leaf_high_key(&page)? {
645 if key > high_key.as_slice() {
646 current_id = right;
647 continue;
648 }
649 }
650 }
651 return Ok(false);
652 }
653 }
654 }
655 Ok(false)
656 }
657
658 pub fn cursor_first(&self) -> BTreeResult<BTreeCursor> {
660 let root_id = self.root_page_id();
661 if root_id == 0 {
662 return Ok(BTreeCursor {
663 _retirement_pin: Arc::clone(&self.retirement_pin),
664 leaf_page_id: 0,
665 position: 0,
666 pager: self.pager.clone(),
667 prefetched_next: false,
668 });
669 }
670
671 let first_leaf = self.find_first_leaf(root_id)?;
673
674 Ok(BTreeCursor {
675 _retirement_pin: Arc::clone(&self.retirement_pin),
676 leaf_page_id: first_leaf,
677 position: 0,
678 pager: self.pager.clone(),
679 prefetched_next: false,
680 })
681 }
682
683 pub fn cursor_seek(&self, key: &[u8]) -> BTreeResult<BTreeCursor> {
685 let root_id = self.root_page_id();
686 if root_id == 0 {
687 return Ok(BTreeCursor {
688 _retirement_pin: Arc::clone(&self.retirement_pin),
689 leaf_page_id: 0,
690 position: 0,
691 pager: self.pager.clone(),
692 prefetched_next: false,
693 });
694 }
695
696 let (leaf_id, _) = self.find_leaf(root_id, key)?;
697 let page = self.pager.read_page(leaf_id)?;
698
699 let position = match search_leaf(&page, key)? {
700 SearchResult::Found(pos) => pos,
701 SearchResult::NotFound(pos) => pos,
702 };
703
704 Ok(BTreeCursor {
705 _retirement_pin: Arc::clone(&self.retirement_pin),
706 leaf_page_id: leaf_id,
707 position,
708 pager: self.pager.clone(),
709 prefetched_next: false,
710 })
711 }
712
713 pub fn range(&self, start_key: &[u8], end_key: &[u8]) -> BTreeResult<Vec<(Vec<u8>, Vec<u8>)>> {
715 let mut results = Vec::new();
716 let mut cursor = self.cursor_seek(start_key)?;
717
718 while let Some((key, value)) = cursor.next()? {
719 if key.as_slice() > end_key {
720 break;
721 }
722 results.push((key, value));
723 }
724
725 Ok(results)
726 }
727
728 pub fn count(&self) -> BTreeResult<usize> {
730 let root_id = self.root_page_id();
731 if root_id == 0 {
732 return Ok(0);
733 }
734
735 let mut count = 0;
736 let mut cursor = self.cursor_first()?;
737 while cursor.next()?.is_some() {
738 count += 1;
739 }
740
741 Ok(count)
742 }
743
744 fn cache_rightmost_leaf(&self, page: &Page) -> BTreeResult<()> {
747 let cached = if leaf_right_sibling(page) == 0 {
751 leaf_high_key(page)?.map(|high| (page.page_id(), high))
752 } else {
753 None
754 };
755 *self.rightmost_leaf.write().map_err(|error| {
756 BTreeError::LockPoisoned(format!("rightmost_leaf write: {error}"))
757 })? = cached;
758 Ok(())
759 }
760
761 fn find_leaf(&self, page_id: u32, key: &[u8]) -> BTreeResult<(u32, Vec<u32>)> {
763 let mut current_id = page_id;
764 let mut path = Vec::new();
765
766 for _ in 0..64 {
769 let page = self.pager.read_page(current_id)?;
770
771 match page.page_type()? {
772 PageType::BTreeLeaf => {
773 return Ok((current_id, path));
774 }
775 PageType::BTreeInterior => {
776 path.push(current_id);
777 current_id = find_child(&page, key)?;
778 }
779 other => {
780 return Err(BTreeError::Corrupted(format!(
781 "Unexpected page type in B-tree: {:?}",
782 other
783 )));
784 }
785 }
786 }
787 Err(BTreeError::Corrupted(
788 "B-tree descent exceeds maximum depth".into(),
789 ))
790 }
791
792 pub(crate) fn find_first_leaf(&self, page_id: u32) -> BTreeResult<u32> {
794 let mut current_id = page_id;
795
796 for _ in 0..64 {
797 let page = self.pager.read_page(current_id)?;
798
799 match page.page_type()? {
800 PageType::BTreeLeaf => return Ok(current_id),
801 PageType::BTreeInterior => {
802 current_id = find_first_child(&page)?;
804 }
805 _ => {
806 return Err(BTreeError::Corrupted("Invalid page type".into()));
807 }
808 }
809 }
810 Err(BTreeError::Corrupted(
811 "leftmost-leaf descent exceeds maximum depth".into(),
812 ))
813 }
814
815 fn split_leaf(
817 &self,
818 page: &mut Page,
819 new_key: &[u8],
820 new_value: &[u8],
821 ) -> BTreeResult<(Page, Vec<u8>)> {
822 let mut entries: Vec<(Vec<u8>, Vec<u8>)> = Vec::new();
824 let cell_count = page.cell_count() as usize;
825
826 for i in 0..cell_count {
827 entries.push(read_leaf_cell(page, i)?);
828 }
829
830 let insert_pos = entries.partition_point(|(k, _)| k.as_slice() < new_key);
832 entries.insert(insert_pos, (new_key.to_vec(), new_value.to_vec()));
833
834 let capacity = PAGE_SIZE - LEAF_SLOT_ARRAY_OFFSET;
837 let total = leaf_entries_size(&entries);
838 let mut left_bytes = 0;
839 let mut split = None;
840 let mut best_balance = usize::MAX;
841 for index in 1..entries.len() {
842 left_bytes += leaf_entry_size(&entries[index - 1]);
843 let right_bytes = total - left_bytes;
844 if left_bytes <= capacity && right_bytes <= capacity {
845 let balance = left_bytes.abs_diff(right_bytes);
846 if balance < best_balance {
847 split = Some(index);
848 best_balance = balance;
849 }
850 }
851 }
852 let mid = split
853 .ok_or_else(|| BTreeError::Corrupted("leaf entries cannot fit in two pages".into()))?;
854
855 let mut new_page = self.pager.allocate_page(PageType::BTreeLeaf)?;
857
858 let old_next = read_next_leaf(page);
860 init_leaf_links(&mut new_page, page.page_id(), old_next);
861 set_next_leaf(page, new_page.page_id());
862
863 write_leaf_entries(page, &entries[..mid])?;
866 write_leaf_entries(&mut new_page, &entries[mid..])?;
867
868 let separator = entries[mid].0.clone();
870
871 new_page.update_checksum();
872 let new_page_id = new_page.page_id();
873 self.pager.write_page(new_page_id, new_page.clone())?;
874
875 Ok((new_page, separator))
876 }
877
878 fn insert_into_parent(
880 &self,
881 mut path: Vec<u32>,
882 left_child: u32,
883 key: &[u8],
884 right_child: u32,
885 ) -> BTreeResult<()> {
886 if path.is_empty() {
888 let mut new_root = self.pager.allocate_page(PageType::BTreeInterior)?;
889 write_interior_entries(&mut new_root, &[key.to_vec()], &[left_child, right_child])?;
892
893 new_root.update_checksum();
894 let new_root_id = new_root.page_id();
895 self.pager.write_page(new_root_id, new_root)?;
896 *self.root_page_id.write().map_err(|e| {
897 BTreeError::LockPoisoned(format!(
898 "insert_into_parent: root_page_id write lock: {e}"
899 ))
900 })? = new_root_id;
901 return Ok(());
902 }
903
904 let parent_id = path.pop().ok_or_else(|| {
906 BTreeError::Corrupted("insert_into_parent: path unexpectedly empty".into())
907 })?;
908 let mut parent = self.pager.read_page(parent_id)?;
909
910 if can_insert_interior(&parent, key) {
912 insert_into_interior(&mut parent, key, left_child, right_child)?;
913 parent.update_checksum();
914 self.pager.write_page(parent_id, parent)?;
915 return Ok(());
916 }
917
918 let (new_interior, separator) =
920 self.split_interior(&mut parent, key, left_child, right_child)?;
921 parent.update_checksum();
922 self.pager.write_page(parent_id, parent.clone())?;
923
924 self.insert_into_parent(path, parent.page_id(), &separator, new_interior.page_id())
926 }
927
928 fn split_interior(
930 &self,
931 page: &mut Page,
932 new_key: &[u8],
933 left_child: u32,
934 right_child: u32,
935 ) -> BTreeResult<(Page, Vec<u8>)> {
936 let (mut keys, mut children) = read_interior_keys_children(page)?;
937 let key_insert_pos = keys.partition_point(|key| key.as_slice() < new_key);
938 let child_insert_pos = children
939 .iter()
940 .position(|child| *child == left_child)
941 .unwrap_or(key_insert_pos);
942
943 keys.insert(key_insert_pos, new_key.to_vec());
944 children.insert(child_insert_pos + 1, right_child);
945
946 let mid = keys.len() / 2;
949 let separator = keys[mid].clone();
950
951 let mut new_page = self.pager.allocate_page(PageType::BTreeInterior)?;
953
954 write_interior_entries(page, &keys[..mid], &children[..mid + 1])?;
955 write_interior_entries(&mut new_page, &keys[mid + 1..], &children[mid + 1..])?;
956
957 new_page.update_checksum();
958 let new_page_id = new_page.page_id();
959 self.pager.write_page(new_page_id, new_page.clone())?;
960
961 Ok((new_page, separator))
962 }
963
964 fn rebalance_leaf(&self, leaf_id: u32, path: Vec<u32>) -> BTreeResult<()> {
965 if path.is_empty() {
966 return Ok(());
967 }
968
969 let root_id = self.root_page_id();
970 if leaf_id == root_id {
971 return Ok(());
972 }
973
974 let mut leaf = self.pager.read_page(leaf_id)?;
975 let mut leaf_entries = read_leaf_entries(&leaf)?;
976 let min_bytes = leaf_min_bytes();
977
978 let parent_id = *path.last().ok_or_else(|| {
979 BTreeError::Corrupted("rebalance_leaf: path unexpectedly empty".into())
980 })?;
981 let mut parent = self.pager.read_page(parent_id)?;
982 let (mut parent_keys, mut parent_children) = read_interior_keys_children(&parent)?;
983
984 let child_index = parent_children
985 .iter()
986 .position(|&id| id == leaf_id)
987 .ok_or_else(|| BTreeError::Corrupted("Leaf missing from parent".into()))?;
988
989 if child_index > 0 {
990 if let Some((first_key, _)) = leaf_entries.first() {
991 if parent_keys.get(child_index - 1).map(|k| k.as_slice())
992 != Some(first_key.as_slice())
993 {
994 parent_keys[child_index - 1] = first_key.clone();
995 write_interior_entries(&mut parent, &parent_keys, &parent_children)?;
996 parent.update_checksum();
997 self.pager.write_page(parent_id, parent.clone())?;
998 }
999 }
1000 }
1001
1002 if leaf_entries_size(&leaf_entries) >= min_bytes {
1003 return Ok(());
1004 }
1005
1006 if child_index > 0 {
1007 let left_id = parent_children[child_index - 1];
1008 let mut left = self.pager.read_page(left_id)?;
1009 let mut left_entries = read_leaf_entries(&left)?;
1010 let mut borrowed = false;
1011
1012 while leaf_entries_size(&leaf_entries) < min_bytes {
1013 let Some(entry) = left_entries.pop() else {
1014 break;
1015 };
1016 if leaf_entries_size(&left_entries) < min_bytes {
1017 left_entries.push(entry);
1018 break;
1019 }
1020 leaf_entries.insert(0, entry);
1021 borrowed = true;
1022 }
1023
1024 if borrowed {
1025 write_leaf_entries(&mut left, &left_entries)?;
1026 left.update_checksum();
1027 self.pager.write_page(left_id, left)?;
1028
1029 write_leaf_entries(&mut leaf, &leaf_entries)?;
1030 leaf.update_checksum();
1031 self.pager.write_page(leaf_id, leaf)?;
1032
1033 if let Some((first_key, _)) = leaf_entries.first() {
1034 parent_keys[child_index - 1] = first_key.clone();
1035 write_interior_entries(&mut parent, &parent_keys, &parent_children)?;
1036 parent.update_checksum();
1037 self.pager.write_page(parent_id, parent)?;
1038 }
1039
1040 return Ok(());
1041 }
1042 }
1043
1044 if child_index + 1 < parent_children.len() {
1045 let right_id = parent_children[child_index + 1];
1046 let mut right = self.pager.read_page(right_id)?;
1047 let mut right_entries = read_leaf_entries(&right)?;
1048 let mut borrowed = false;
1049
1050 while leaf_entries_size(&leaf_entries) < min_bytes {
1051 if right_entries.is_empty() {
1052 break;
1053 }
1054 let entry = right_entries.remove(0);
1055 if leaf_entries_size(&right_entries) < min_bytes {
1056 right_entries.insert(0, entry);
1057 break;
1058 }
1059 leaf_entries.push(entry);
1060 borrowed = true;
1061 }
1062
1063 if borrowed {
1064 write_leaf_entries(&mut right, &right_entries)?;
1065 right.update_checksum();
1066 self.pager.write_page(right_id, right)?;
1067
1068 write_leaf_entries(&mut leaf, &leaf_entries)?;
1069 leaf.update_checksum();
1070 self.pager.write_page(leaf_id, leaf)?;
1071
1072 if let Some((first_key, _)) = right_entries.first() {
1073 parent_keys[child_index] = first_key.clone();
1074 write_interior_entries(&mut parent, &parent_keys, &parent_children)?;
1075 parent.update_checksum();
1076 self.pager.write_page(parent_id, parent)?;
1077 }
1078
1079 return Ok(());
1080 }
1081 }
1082
1083 if child_index > 0 {
1084 let left_id = parent_children[child_index - 1];
1085 let mut left = self.pager.read_page(left_id)?;
1086 let mut left_entries = read_leaf_entries(&left)?;
1087
1088 left_entries.extend(leaf_entries);
1089 write_leaf_entries(&mut left, &left_entries)?;
1090
1091 let next_leaf = read_next_leaf(&leaf);
1092 set_next_leaf(&mut left, next_leaf);
1093 if next_leaf != 0 {
1094 let mut next = self.pager.read_page(next_leaf)?;
1095 set_prev_leaf(&mut next, left_id);
1096 next.update_checksum();
1097 self.pager.write_page(next_leaf, next)?;
1098 }
1099
1100 left.update_checksum();
1101 self.pager.write_page(left_id, left)?;
1102 self.pager.free_page(leaf_id)?;
1103
1104 parent_keys.remove(child_index - 1);
1105 parent_children.remove(child_index);
1106 write_interior_entries(&mut parent, &parent_keys, &parent_children)?;
1107 parent.update_checksum();
1108 self.pager.write_page(parent_id, parent)?;
1109
1110 let mut parent_path = path;
1111 parent_path.pop();
1112 return self.rebalance_interior(parent_id, parent_path);
1113 }
1114
1115 if child_index + 1 < parent_children.len() {
1116 let right_id = parent_children[child_index + 1];
1117 let right = self.pager.read_page(right_id)?;
1118 let right_entries = read_leaf_entries(&right)?;
1119
1120 leaf_entries.extend(right_entries);
1121 write_leaf_entries(&mut leaf, &leaf_entries)?;
1122
1123 let next_leaf = read_next_leaf(&right);
1124 set_next_leaf(&mut leaf, next_leaf);
1125 if next_leaf != 0 {
1126 let mut next = self.pager.read_page(next_leaf)?;
1127 set_prev_leaf(&mut next, leaf_id);
1128 next.update_checksum();
1129 self.pager.write_page(next_leaf, next)?;
1130 }
1131
1132 leaf.update_checksum();
1133 self.pager.write_page(leaf_id, leaf)?;
1134 self.pager.free_page(right_id)?;
1135
1136 parent_keys.remove(child_index);
1137 parent_children.remove(child_index + 1);
1138 write_interior_entries(&mut parent, &parent_keys, &parent_children)?;
1139 parent.update_checksum();
1140 self.pager.write_page(parent_id, parent)?;
1141
1142 let mut parent_path = path;
1143 parent_path.pop();
1144 return self.rebalance_interior(parent_id, parent_path);
1145 }
1146
1147 Ok(())
1148 }
1149
1150 fn rebalance_interior(&self, node_id: u32, mut path: Vec<u32>) -> BTreeResult<()> {
1151 let root_id = self.root_page_id();
1152 let mut node = self.pager.read_page(node_id)?;
1153 let (mut node_keys, mut node_children) = read_interior_keys_children(&node)?;
1154 let min_bytes = interior_min_bytes();
1155
1156 if node_id == root_id {
1157 if node_keys.is_empty() {
1158 let next_root = node_children.first().copied().unwrap_or(0);
1159 self.pager.free_page(node_id)?;
1160 *self.root_page_id.write().map_err(|e| {
1161 BTreeError::LockPoisoned(format!(
1162 "rebalance_interior: root_page_id write lock: {e}"
1163 ))
1164 })? = next_root;
1165 }
1166 return Ok(());
1167 }
1168
1169 if interior_entries_size(&node_keys) >= min_bytes {
1170 return Ok(());
1171 }
1172
1173 let parent_id = match path.pop() {
1174 Some(id) => id,
1175 None => return Ok(()),
1176 };
1177 let mut parent = self.pager.read_page(parent_id)?;
1178 let (mut parent_keys, mut parent_children) = read_interior_keys_children(&parent)?;
1179
1180 let child_index = parent_children
1181 .iter()
1182 .position(|&id| id == node_id)
1183 .ok_or_else(|| BTreeError::Corrupted("Interior missing from parent".into()))?;
1184
1185 if child_index > 0 {
1186 let left_id = parent_children[child_index - 1];
1187 let mut left = self.pager.read_page(left_id)?;
1188 let (mut left_keys, mut left_children) = read_interior_keys_children(&left)?;
1189
1190 if let Some(borrow_key) = left_keys.last().cloned() {
1191 let borrow_size = interior_key_size(&borrow_key);
1192 if interior_entries_size(&left_keys).saturating_sub(borrow_size) >= min_bytes {
1193 let parent_key = parent_keys[child_index - 1].clone();
1194 let borrowed_key = left_keys.pop().ok_or_else(|| {
1195 BTreeError::Corrupted(
1196 "rebalance_interior: left_keys empty after check".into(),
1197 )
1198 })?;
1199 let borrowed_child = left_children.pop().ok_or_else(|| {
1200 BTreeError::Corrupted("rebalance_interior: left_children empty".into())
1201 })?;
1202
1203 node_keys.insert(0, parent_key);
1204 node_children.insert(0, borrowed_child);
1205 parent_keys[child_index - 1] = borrowed_key;
1206
1207 write_interior_entries(&mut left, &left_keys, &left_children)?;
1208 left.update_checksum();
1209 self.pager.write_page(left_id, left)?;
1210
1211 write_interior_entries(&mut node, &node_keys, &node_children)?;
1212 node.update_checksum();
1213 self.pager.write_page(node_id, node)?;
1214
1215 write_interior_entries(&mut parent, &parent_keys, &parent_children)?;
1216 parent.update_checksum();
1217 self.pager.write_page(parent_id, parent)?;
1218
1219 return Ok(());
1220 }
1221 }
1222 }
1223
1224 if child_index + 1 < parent_children.len() {
1225 let right_id = parent_children[child_index + 1];
1226 let mut right = self.pager.read_page(right_id)?;
1227 let (mut right_keys, mut right_children) = read_interior_keys_children(&right)?;
1228
1229 if let Some(borrow_key) = right_keys.first().cloned() {
1230 let borrow_size = interior_key_size(&borrow_key);
1231 if interior_entries_size(&right_keys).saturating_sub(borrow_size) >= min_bytes {
1232 let parent_key = parent_keys[child_index].clone();
1233 let new_parent_key = right_keys.remove(0);
1234 let borrowed_child = right_children.remove(0);
1235
1236 node_keys.push(parent_key);
1237 node_children.push(borrowed_child);
1238 parent_keys[child_index] = new_parent_key;
1239
1240 write_interior_entries(&mut right, &right_keys, &right_children)?;
1241 right.update_checksum();
1242 self.pager.write_page(right_id, right)?;
1243
1244 write_interior_entries(&mut node, &node_keys, &node_children)?;
1245 node.update_checksum();
1246 self.pager.write_page(node_id, node)?;
1247
1248 write_interior_entries(&mut parent, &parent_keys, &parent_children)?;
1249 parent.update_checksum();
1250 self.pager.write_page(parent_id, parent)?;
1251
1252 return Ok(());
1253 }
1254 }
1255 }
1256
1257 if child_index > 0 {
1258 let left_id = parent_children[child_index - 1];
1259 let mut left = self.pager.read_page(left_id)?;
1260 let (mut left_keys, mut left_children) = read_interior_keys_children(&left)?;
1261 let parent_key = parent_keys.remove(child_index - 1);
1262 parent_children.remove(child_index);
1263
1264 left_keys.push(parent_key);
1265 left_keys.extend(node_keys);
1266 left_children.extend(node_children);
1267
1268 write_interior_entries(&mut left, &left_keys, &left_children)?;
1269 left.update_checksum();
1270 self.pager.write_page(left_id, left)?;
1271 self.pager.free_page(node_id)?;
1272
1273 write_interior_entries(&mut parent, &parent_keys, &parent_children)?;
1274 parent.update_checksum();
1275 self.pager.write_page(parent_id, parent)?;
1276
1277 return self.rebalance_interior(parent_id, path);
1278 }
1279
1280 if child_index + 1 < parent_children.len() {
1281 let right_id = parent_children[child_index + 1];
1282 let right = self.pager.read_page(right_id)?;
1283 let (right_keys, right_children) = read_interior_keys_children(&right)?;
1284 let parent_key = parent_keys.remove(child_index);
1285 parent_children.remove(child_index + 1);
1286
1287 node_keys.push(parent_key);
1288 node_keys.extend(right_keys);
1289 node_children.extend(right_children);
1290
1291 write_interior_entries(&mut node, &node_keys, &node_children)?;
1292 node.update_checksum();
1293 self.pager.write_page(node_id, node)?;
1294 self.pager.free_page(right_id)?;
1295
1296 write_interior_entries(&mut parent, &parent_keys, &parent_children)?;
1297 parent.update_checksum();
1298 self.pager.write_page(parent_id, parent)?;
1299
1300 return self.rebalance_interior(parent_id, path);
1301 }
1302
1303 Ok(())
1304 }
1305}