@@ -821,6 +821,53 @@ impl<BorrowType, K, V, NodeType> Handle<NodeRef<BorrowType, K, V, NodeType>, mar
821
821
}
822
822
}
823
823
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
+
824
871
impl < ' a , K , V , NodeType > Handle < NodeRef < marker:: Mut < ' a > , K , V , NodeType > , marker:: Edge > {
825
872
/// Helps implementations of `insert_fit` for a particular `NodeType`,
826
873
/// 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
863
910
let kv = unsafe { Handle :: new_kv ( self . node , self . idx ) } ;
864
911
( InsertResult :: Fit ( kv) , ptr)
865
912
} 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) } ;
867
915
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 {
872
921
Handle :: new_edge (
873
922
right. node_as_mut ( ) . cast_unchecked :: < marker:: Leaf > ( ) ,
874
- self . idx - ( B + 1 ) ,
923
+ insert_idx ,
875
924
)
876
925
. insert_fit ( key, val)
877
- }
926
+ } ,
878
927
} ;
879
928
( InsertResult :: Split ( SplitResult { left : left. forget_type ( ) , k, v, right } ) , ptr)
880
929
}
@@ -936,20 +985,20 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
936
985
let kv = unsafe { Handle :: new_kv ( self . node , self . idx ) } ;
937
986
InsertResult :: Fit ( kv)
938
987
} 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) } ;
940
990
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 {
947
996
Handle :: new_edge (
948
997
right. node_as_mut ( ) . cast_unchecked :: < marker:: Internal > ( ) ,
949
- self . idx - ( B + 1 ) ,
998
+ insert_idx ,
950
999
)
951
1000
. insert_fit ( key, val, edge) ;
952
- }
1001
+ } ,
953
1002
}
954
1003
InsertResult :: Split ( SplitResult { left : left. forget_type ( ) , k, v, right } )
955
1004
}
0 commit comments