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