@@ -821,6 +821,53 @@ impl<BorrowType, K, V, NodeType> Handle<NodeRef<BorrowType, K, V, NodeType>, mar
821821 }
822822}
823823
824+ enum InsertionPlace {
825+ Left ( usize ) ,
826+ Right ( usize ) ,
827+ }
828+
829+ /// Given an edge index where we want to insert into a node filled to capacity,
830+ /// computes a sensible KV index of a split point and where to perform the insertion.
831+ /// The goal of the split point is for its key and value to end up in a parent node;
832+ /// the keys, values and edges to the left of the split point become the left child;
833+ /// the keys, values and edges to the right of the split point become the right child.
834+ fn splitpoint ( edge_idx : usize ) -> ( usize , InsertionPlace ) {
835+ debug_assert ! ( edge_idx <= CAPACITY ) ;
836+ // Rust issue #74834 tries to explain these symmetric rules.
837+ let middle_kv_idx;
838+ let insertion;
839+ if edge_idx <= B - 2 {
840+ middle_kv_idx = B - 2 ;
841+ insertion = InsertionPlace :: Left ( edge_idx) ;
842+ } else if edge_idx == B - 1 {
843+ middle_kv_idx = B - 1 ;
844+ insertion = InsertionPlace :: Left ( edge_idx) ;
845+ } else if edge_idx == B {
846+ middle_kv_idx = B - 1 ;
847+ insertion = InsertionPlace :: Right ( 0 ) ;
848+ } else {
849+ middle_kv_idx = B ;
850+ let new_edge_idx = edge_idx - ( B + 1 ) ;
851+ insertion = InsertionPlace :: Right ( new_edge_idx) ;
852+ }
853+ let mut left_len = middle_kv_idx;
854+ let mut right_len = CAPACITY - middle_kv_idx - 1 ;
855+ match insertion {
856+ InsertionPlace :: Left ( edge_idx) => {
857+ debug_assert ! ( edge_idx <= left_len) ;
858+ left_len += 1 ;
859+ }
860+ InsertionPlace :: Right ( edge_idx) => {
861+ debug_assert ! ( edge_idx <= right_len) ;
862+ right_len += 1 ;
863+ }
864+ }
865+ debug_assert ! ( left_len >= MIN_LEN ) ;
866+ debug_assert ! ( right_len >= MIN_LEN ) ;
867+ debug_assert ! ( left_len + right_len == CAPACITY ) ;
868+ ( middle_kv_idx, insertion)
869+ }
870+
824871impl < ' a , K , V , NodeType > Handle < NodeRef < marker:: Mut < ' a > , K , V , NodeType > , marker:: Edge > {
825872 /// Helps implementations of `insert_fit` for a particular `NodeType`,
826873 /// by taking care of leaf data.
@@ -863,18 +910,20 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge
863910 let kv = unsafe { Handle :: new_kv ( self . node , self . idx ) } ;
864911 ( InsertResult :: Fit ( kv) , ptr)
865912 } else {
866- let middle = unsafe { Handle :: new_kv ( self . node , B ) } ;
913+ let ( middle_kv_idx, insertion) = splitpoint ( self . idx ) ;
914+ let middle = unsafe { Handle :: new_kv ( self . node , middle_kv_idx) } ;
867915 let ( mut left, k, v, mut right) = middle. split ( ) ;
868- let ptr = if self . idx <= B {
869- unsafe { Handle :: new_edge ( left. reborrow_mut ( ) , self . idx ) . insert_fit ( key, val) }
870- } else {
871- unsafe {
916+ let ptr = match insertion {
917+ InsertionPlace :: Left ( insert_idx) => unsafe {
918+ Handle :: new_edge ( left. reborrow_mut ( ) , insert_idx) . insert_fit ( key, val)
919+ } ,
920+ InsertionPlace :: Right ( insert_idx) => unsafe {
872921 Handle :: new_edge (
873922 right. node_as_mut ( ) . cast_unchecked :: < marker:: Leaf > ( ) ,
874- self . idx - ( B + 1 ) ,
923+ insert_idx ,
875924 )
876925 . insert_fit ( key, val)
877- }
926+ } ,
878927 } ;
879928 ( InsertResult :: Split ( SplitResult { left : left. forget_type ( ) , k, v, right } ) , ptr)
880929 }
@@ -936,20 +985,20 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
936985 let kv = unsafe { Handle :: new_kv ( self . node , self . idx ) } ;
937986 InsertResult :: Fit ( kv)
938987 } else {
939- let middle = unsafe { Handle :: new_kv ( self . node , B ) } ;
988+ let ( middle_kv_idx, insertion) = splitpoint ( self . idx ) ;
989+ let middle = unsafe { Handle :: new_kv ( self . node , middle_kv_idx) } ;
940990 let ( mut left, k, v, mut right) = middle. split ( ) ;
941- if self . idx <= B {
942- unsafe {
943- Handle :: new_edge ( left. reborrow_mut ( ) , self . idx ) . insert_fit ( key, val, edge) ;
944- }
945- } else {
946- unsafe {
991+ match insertion {
992+ InsertionPlace :: Left ( insert_idx) => unsafe {
993+ Handle :: new_edge ( left. reborrow_mut ( ) , insert_idx) . insert_fit ( key, val, edge) ;
994+ } ,
995+ InsertionPlace :: Right ( insert_idx) => unsafe {
947996 Handle :: new_edge (
948997 right. node_as_mut ( ) . cast_unchecked :: < marker:: Internal > ( ) ,
949- self . idx - ( B + 1 ) ,
998+ insert_idx ,
950999 )
9511000 . insert_fit ( key, val, edge) ;
952- }
1001+ } ,
9531002 }
9541003 InsertResult :: Split ( SplitResult { left : left. forget_type ( ) , k, v, right } )
9551004 }
0 commit comments