1use super::*;
2use crate::storage::overflow::OverflowChain;
3
4impl<P: PageStore> BTree<P> {
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.as_ref())
19 .free(head)
20 .map_err(value_layout::ValueLayoutError::from)?;
21 }
22 Ok(())
23 }
24 pub fn new(pager: Arc<P>) -> 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<P>, 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.as_ref(), &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.as_ref(), &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.as_ref(), 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.as_ref(), 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.as_ref(), 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.as_ref(), 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<P>> {
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<P>> {
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, mut path: Vec<u32>) -> BTreeResult<()> {
965 if let Some(parent_id) = self.rebalance_leaf_step(leaf_id, &path)? {
968 path.pop();
969 self.rebalance_interior(parent_id, path)?;
970 }
971 Ok(())
972 }
973
974 fn rebalance_leaf_step(&self, leaf_id: u32, path: &[u32]) -> BTreeResult<Option<u32>> {
975 if path.is_empty() {
976 return Ok(None);
977 }
978
979 let root_id = self.root_page_id();
980 if leaf_id == root_id {
981 return Ok(None);
982 }
983
984 let mut leaf = self.pager.read_page(leaf_id)?;
985 let mut leaf_entries = read_leaf_entries(&leaf)?;
986 let min_bytes = leaf_min_bytes();
987
988 let parent_id = *path.last().ok_or_else(|| {
989 BTreeError::Corrupted("rebalance_leaf: path unexpectedly empty".into())
990 })?;
991 let mut parent = self.pager.read_page(parent_id)?;
992 let (mut parent_keys, mut parent_children) = read_interior_keys_children(&parent)?;
993
994 let child_index = parent_children
995 .iter()
996 .position(|&id| id == leaf_id)
997 .ok_or_else(|| BTreeError::Corrupted("Leaf missing from parent".into()))?;
998
999 if child_index > 0 {
1000 if let Some((first_key, _)) = leaf_entries.first() {
1001 if parent_keys.get(child_index - 1).map(|k| k.as_slice())
1002 != Some(first_key.as_slice())
1003 {
1004 parent_keys[child_index - 1] = first_key.clone();
1005 write_interior_entries(&mut parent, &parent_keys, &parent_children)?;
1006 parent.update_checksum();
1007 self.pager.write_page(parent_id, parent.clone())?;
1008 }
1009 }
1010 }
1011
1012 if leaf_entries_size(&leaf_entries) >= min_bytes {
1013 return Ok(None);
1014 }
1015
1016 if child_index > 0 {
1017 let left_id = parent_children[child_index - 1];
1018 let mut left = self.pager.read_page(left_id)?;
1019 let mut left_entries = read_leaf_entries(&left)?;
1020 let mut borrowed = false;
1021
1022 while leaf_entries_size(&leaf_entries) < min_bytes {
1023 let Some(entry) = left_entries.pop() else {
1024 break;
1025 };
1026 if leaf_entries_size(&left_entries) < min_bytes {
1027 left_entries.push(entry);
1028 break;
1029 }
1030 leaf_entries.insert(0, entry);
1031 borrowed = true;
1032 }
1033
1034 if borrowed {
1035 write_leaf_entries(&mut left, &left_entries)?;
1036 left.update_checksum();
1037 self.pager.write_page(left_id, left)?;
1038
1039 write_leaf_entries(&mut leaf, &leaf_entries)?;
1040 leaf.update_checksum();
1041 self.pager.write_page(leaf_id, leaf)?;
1042
1043 if let Some((first_key, _)) = leaf_entries.first() {
1044 parent_keys[child_index - 1] = first_key.clone();
1045 write_interior_entries(&mut parent, &parent_keys, &parent_children)?;
1046 parent.update_checksum();
1047 self.pager.write_page(parent_id, parent)?;
1048 }
1049
1050 return Ok(None);
1051 }
1052 }
1053
1054 if child_index + 1 < parent_children.len() {
1055 let right_id = parent_children[child_index + 1];
1056 let mut right = self.pager.read_page(right_id)?;
1057 let mut right_entries = read_leaf_entries(&right)?;
1058 let mut borrowed = false;
1059
1060 while leaf_entries_size(&leaf_entries) < min_bytes {
1061 if right_entries.is_empty() {
1062 break;
1063 }
1064 let entry = right_entries.remove(0);
1065 if leaf_entries_size(&right_entries) < min_bytes {
1066 right_entries.insert(0, entry);
1067 break;
1068 }
1069 leaf_entries.push(entry);
1070 borrowed = true;
1071 }
1072
1073 if borrowed {
1074 write_leaf_entries(&mut right, &right_entries)?;
1075 right.update_checksum();
1076 self.pager.write_page(right_id, right)?;
1077
1078 write_leaf_entries(&mut leaf, &leaf_entries)?;
1079 leaf.update_checksum();
1080 self.pager.write_page(leaf_id, leaf)?;
1081
1082 if let Some((first_key, _)) = right_entries.first() {
1083 parent_keys[child_index] = first_key.clone();
1084 write_interior_entries(&mut parent, &parent_keys, &parent_children)?;
1085 parent.update_checksum();
1086 self.pager.write_page(parent_id, parent)?;
1087 }
1088
1089 return Ok(None);
1090 }
1091 }
1092
1093 if child_index > 0 {
1094 let left_id = parent_children[child_index - 1];
1095 let mut left = self.pager.read_page(left_id)?;
1096 let mut left_entries = read_leaf_entries(&left)?;
1097
1098 left_entries.extend(leaf_entries);
1099 write_leaf_entries(&mut left, &left_entries)?;
1100
1101 let next_leaf = read_next_leaf(&leaf);
1102 set_next_leaf(&mut left, next_leaf);
1103 if next_leaf != 0 {
1104 let mut next = self.pager.read_page(next_leaf)?;
1105 set_prev_leaf(&mut next, left_id);
1106 next.update_checksum();
1107 self.pager.write_page(next_leaf, next)?;
1108 }
1109
1110 left.update_checksum();
1111 self.pager.write_page(left_id, left)?;
1112 self.pager.free_page(leaf_id)?;
1113
1114 parent_keys.remove(child_index - 1);
1115 parent_children.remove(child_index);
1116 write_interior_entries(&mut parent, &parent_keys, &parent_children)?;
1117 parent.update_checksum();
1118 self.pager.write_page(parent_id, parent)?;
1119
1120 return Ok(Some(parent_id));
1121 }
1122
1123 if child_index + 1 < parent_children.len() {
1124 let right_id = parent_children[child_index + 1];
1125 let right = self.pager.read_page(right_id)?;
1126 let right_entries = read_leaf_entries(&right)?;
1127
1128 leaf_entries.extend(right_entries);
1129 write_leaf_entries(&mut leaf, &leaf_entries)?;
1130
1131 let next_leaf = read_next_leaf(&right);
1132 set_next_leaf(&mut leaf, next_leaf);
1133 if next_leaf != 0 {
1134 let mut next = self.pager.read_page(next_leaf)?;
1135 set_prev_leaf(&mut next, leaf_id);
1136 next.update_checksum();
1137 self.pager.write_page(next_leaf, next)?;
1138 }
1139
1140 leaf.update_checksum();
1141 self.pager.write_page(leaf_id, leaf)?;
1142 self.pager.free_page(right_id)?;
1143
1144 parent_keys.remove(child_index);
1145 parent_children.remove(child_index + 1);
1146 write_interior_entries(&mut parent, &parent_keys, &parent_children)?;
1147 parent.update_checksum();
1148 self.pager.write_page(parent_id, parent)?;
1149
1150 return Ok(Some(parent_id));
1151 }
1152
1153 Ok(None)
1154 }
1155
1156 fn rebalance_interior(&self, mut node_id: u32, mut path: Vec<u32>) -> BTreeResult<()> {
1157 while let Some(parent_id) = self.rebalance_interior_step(node_id, &mut path)? {
1159 node_id = parent_id;
1160 }
1161 Ok(())
1162 }
1163
1164 fn rebalance_interior_step(
1165 &self,
1166 node_id: u32,
1167 path: &mut Vec<u32>,
1168 ) -> BTreeResult<Option<u32>> {
1169 let root_id = self.root_page_id();
1170 let mut node = self.pager.read_page(node_id)?;
1171 let (mut node_keys, mut node_children) = read_interior_keys_children(&node)?;
1172 let min_bytes = interior_min_bytes();
1173
1174 if node_id == root_id {
1175 if node_keys.is_empty() {
1176 let next_root = node_children.first().copied().unwrap_or(0);
1177 self.pager.free_page(node_id)?;
1178 *self.root_page_id.write().map_err(|e| {
1179 BTreeError::LockPoisoned(format!(
1180 "rebalance_interior: root_page_id write lock: {e}"
1181 ))
1182 })? = next_root;
1183 }
1184 return Ok(None);
1185 }
1186
1187 if interior_entries_size(&node_keys) >= min_bytes {
1188 return Ok(None);
1189 }
1190
1191 let parent_id = match path.pop() {
1192 Some(id) => id,
1193 None => return Ok(None),
1194 };
1195 let mut parent = self.pager.read_page(parent_id)?;
1196 let (mut parent_keys, mut parent_children) = read_interior_keys_children(&parent)?;
1197
1198 let child_index = parent_children
1199 .iter()
1200 .position(|&id| id == node_id)
1201 .ok_or_else(|| BTreeError::Corrupted("Interior missing from parent".into()))?;
1202
1203 if child_index > 0 {
1204 let left_id = parent_children[child_index - 1];
1205 let mut left = self.pager.read_page(left_id)?;
1206 let (mut left_keys, mut left_children) = read_interior_keys_children(&left)?;
1207
1208 if let Some(borrow_key) = left_keys.last().cloned() {
1209 let borrow_size = interior_key_size(&borrow_key);
1210 if interior_entries_size(&left_keys).saturating_sub(borrow_size) >= min_bytes {
1211 let parent_key = parent_keys[child_index - 1].clone();
1212 let borrowed_key = left_keys.pop().ok_or_else(|| {
1213 BTreeError::Corrupted(
1214 "rebalance_interior: left_keys empty after check".into(),
1215 )
1216 })?;
1217 let borrowed_child = left_children.pop().ok_or_else(|| {
1218 BTreeError::Corrupted("rebalance_interior: left_children empty".into())
1219 })?;
1220
1221 node_keys.insert(0, parent_key);
1222 node_children.insert(0, borrowed_child);
1223 parent_keys[child_index - 1] = borrowed_key;
1224
1225 write_interior_entries(&mut left, &left_keys, &left_children)?;
1226 left.update_checksum();
1227 self.pager.write_page(left_id, left)?;
1228
1229 write_interior_entries(&mut node, &node_keys, &node_children)?;
1230 node.update_checksum();
1231 self.pager.write_page(node_id, node)?;
1232
1233 write_interior_entries(&mut parent, &parent_keys, &parent_children)?;
1234 parent.update_checksum();
1235 self.pager.write_page(parent_id, parent)?;
1236
1237 return Ok(None);
1238 }
1239 }
1240 }
1241
1242 if child_index + 1 < parent_children.len() {
1243 let right_id = parent_children[child_index + 1];
1244 let mut right = self.pager.read_page(right_id)?;
1245 let (mut right_keys, mut right_children) = read_interior_keys_children(&right)?;
1246
1247 if let Some(borrow_key) = right_keys.first().cloned() {
1248 let borrow_size = interior_key_size(&borrow_key);
1249 if interior_entries_size(&right_keys).saturating_sub(borrow_size) >= min_bytes {
1250 let parent_key = parent_keys[child_index].clone();
1251 let new_parent_key = right_keys.remove(0);
1252 let borrowed_child = right_children.remove(0);
1253
1254 node_keys.push(parent_key);
1255 node_children.push(borrowed_child);
1256 parent_keys[child_index] = new_parent_key;
1257
1258 write_interior_entries(&mut right, &right_keys, &right_children)?;
1259 right.update_checksum();
1260 self.pager.write_page(right_id, right)?;
1261
1262 write_interior_entries(&mut node, &node_keys, &node_children)?;
1263 node.update_checksum();
1264 self.pager.write_page(node_id, node)?;
1265
1266 write_interior_entries(&mut parent, &parent_keys, &parent_children)?;
1267 parent.update_checksum();
1268 self.pager.write_page(parent_id, parent)?;
1269
1270 return Ok(None);
1271 }
1272 }
1273 }
1274
1275 if child_index > 0 {
1276 let left_id = parent_children[child_index - 1];
1277 let mut left = self.pager.read_page(left_id)?;
1278 let (mut left_keys, mut left_children) = read_interior_keys_children(&left)?;
1279 let parent_key = parent_keys.remove(child_index - 1);
1280 parent_children.remove(child_index);
1281
1282 left_keys.push(parent_key);
1283 left_keys.extend(node_keys);
1284 left_children.extend(node_children);
1285
1286 write_interior_entries(&mut left, &left_keys, &left_children)?;
1287 left.update_checksum();
1288 self.pager.write_page(left_id, left)?;
1289 self.pager.free_page(node_id)?;
1290
1291 write_interior_entries(&mut parent, &parent_keys, &parent_children)?;
1292 parent.update_checksum();
1293 self.pager.write_page(parent_id, parent)?;
1294
1295 return Ok(Some(parent_id));
1296 }
1297
1298 if child_index + 1 < parent_children.len() {
1299 let right_id = parent_children[child_index + 1];
1300 let right = self.pager.read_page(right_id)?;
1301 let (right_keys, right_children) = read_interior_keys_children(&right)?;
1302 let parent_key = parent_keys.remove(child_index);
1303 parent_children.remove(child_index + 1);
1304
1305 node_keys.push(parent_key);
1306 node_keys.extend(right_keys);
1307 node_children.extend(right_children);
1308
1309 write_interior_entries(&mut node, &node_keys, &node_children)?;
1310 node.update_checksum();
1311 self.pager.write_page(node_id, node)?;
1312 self.pager.free_page(right_id)?;
1313
1314 write_interior_entries(&mut parent, &parent_keys, &parent_children)?;
1315 parent.update_checksum();
1316 self.pager.write_page(parent_id, parent)?;
1317
1318 return Ok(Some(parent_id));
1319 }
1320
1321 Ok(None)
1322 }
1323}