@@ -842,20 +842,188 @@ impl<K: Ord, V> BTreeMap<K, V> {
842842 // Check if right-most child is underfull.
843843 let mut last_edge = internal. last_edge ( ) ;
844844 let right_child_len = last_edge. reborrow ( ) . descend ( ) . len ( ) ;
845- if right_child_len < node:: CAPACITY / 2 {
845+ if right_child_len < node:: MIN_LEN {
846846 // We need to steal.
847847 let mut last_kv = match last_edge. left_kv ( ) {
848848 Ok ( left) => left,
849849 Err ( _) => unreachable ! ( ) ,
850850 } ;
851- last_kv. bulk_steal_left ( node:: CAPACITY / 2 - right_child_len) ;
851+ last_kv. bulk_steal_left ( node:: MIN_LEN - right_child_len) ;
852852 last_edge = last_kv. right_edge ( ) ;
853853 }
854854
855855 // Go further down.
856856 cur_node = last_edge. descend ( ) ;
857857 }
858858 }
859+
860+ /// Splits the collection into two at the given key. Returns everything after the given key,
861+ /// including the key.
862+ ///
863+ /// # Examples
864+ ///
865+ /// Basic usage:
866+ ///
867+ /// ```
868+ /// #![feature(btree_split_off)]
869+ /// use std::collections::BTreeMap;
870+ ///
871+ /// let mut a = BTreeMap::new();
872+ /// a.insert(1, "a");
873+ /// a.insert(2, "b");
874+ /// a.insert(3, "c");
875+ /// a.insert(17, "d");
876+ /// a.insert(41, "e");
877+ ///
878+ /// let b = a.split_off(&3);
879+ ///
880+ /// assert_eq!(a.len(), 2);
881+ /// assert_eq!(b.len(), 3);
882+ ///
883+ /// assert_eq!(a[&1], "a");
884+ /// assert_eq!(a[&2], "b");
885+ ///
886+ /// assert_eq!(b[&3], "c");
887+ /// assert_eq!(b[&17], "d");
888+ /// assert_eq!(b[&41], "e");
889+ /// ```
890+ #[ unstable( feature = "btree_split_off" ,
891+ reason = "recently added as part of collections reform 2" ,
892+ issue = "19986" ) ]
893+ pub fn split_off < Q : ?Sized + Ord > ( & mut self , key : & Q ) -> Self where K : Borrow < Q > {
894+ if self . is_empty ( ) {
895+ return Self :: new ( ) ;
896+ }
897+
898+ let total_num = self . len ( ) ;
899+
900+ let mut right = Self :: new ( ) ;
901+ for _ in 0 ..( self . root . as_ref ( ) . height ( ) ) {
902+ right. root . push_level ( ) ;
903+ }
904+
905+ {
906+ let mut left_node = self . root . as_mut ( ) ;
907+ let mut right_node = right. root . as_mut ( ) ;
908+
909+ loop {
910+ let mut split_edge = match search:: search_node ( left_node, key) {
911+ // key is going to the right tree
912+ Found ( handle) => handle. left_edge ( ) ,
913+ GoDown ( handle) => handle
914+ } ;
915+
916+ split_edge. move_suffix ( & mut right_node) ;
917+
918+ match ( split_edge. force ( ) , right_node. force ( ) ) {
919+ ( Internal ( edge) , Internal ( node) ) => {
920+ left_node = edge. descend ( ) ;
921+ right_node = node. first_edge ( ) . descend ( ) ;
922+ }
923+ ( Leaf ( _) , Leaf ( _) ) => { break ; } ,
924+ _ => { unreachable ! ( ) ; }
925+ }
926+ }
927+ }
928+
929+ self . fix_right_border ( ) ;
930+ right. fix_left_border ( ) ;
931+
932+ if self . root . as_ref ( ) . height ( ) < right. root . as_ref ( ) . height ( ) {
933+ self . recalc_length ( ) ;
934+ right. length = total_num - self . len ( ) ;
935+ } else {
936+ right. recalc_length ( ) ;
937+ self . length = total_num - right. len ( ) ;
938+ }
939+
940+ right
941+ }
942+
943+ /// Calculates the number of elements if it is incorrect.
944+ fn recalc_length ( & mut self ) {
945+ fn dfs < K , V > ( node : NodeRef < marker:: Immut , K , V , marker:: LeafOrInternal > ) -> usize {
946+ let mut res = node. len ( ) ;
947+
948+ if let Internal ( node) = node. force ( ) {
949+ let mut edge = node. first_edge ( ) ;
950+ loop {
951+ res += dfs ( edge. reborrow ( ) . descend ( ) ) ;
952+ match edge. right_kv ( ) {
953+ Ok ( right_kv) => { edge = right_kv. right_edge ( ) ; } ,
954+ Err ( _) => { break ; }
955+ }
956+ }
957+ }
958+
959+ res
960+ }
961+
962+ self . length = dfs ( self . root . as_ref ( ) ) ;
963+ }
964+
965+ /// Removes empty levels on the top.
966+ fn fix_top ( & mut self ) {
967+ loop {
968+ {
969+ let node = self . root . as_ref ( ) ;
970+ if node. height ( ) == 0 || node. len ( ) > 0 {
971+ break ;
972+ }
973+ }
974+ self . root . pop_level ( ) ;
975+ }
976+ }
977+
978+ fn fix_right_border ( & mut self ) {
979+ self . fix_top ( ) ;
980+
981+ {
982+ let mut cur_node = self . root . as_mut ( ) ;
983+
984+ while let Internal ( node) = cur_node. force ( ) {
985+ let mut last_kv = node. last_kv ( ) ;
986+
987+ if last_kv. can_merge ( ) {
988+ cur_node = last_kv. merge ( ) . descend ( ) ;
989+ } else {
990+ let right_len = last_kv. reborrow ( ) . right_edge ( ) . descend ( ) . len ( ) ;
991+ // `MINLEN + 1` to avoid readjust if merge happens on the next level.
992+ if right_len < node:: MIN_LEN + 1 {
993+ last_kv. bulk_steal_left ( node:: MIN_LEN + 1 - right_len) ;
994+ }
995+ cur_node = last_kv. right_edge ( ) . descend ( ) ;
996+ }
997+ }
998+ }
999+
1000+ self . fix_top ( ) ;
1001+ }
1002+
1003+ /// The symmetric clone of `fix_right_border`.
1004+ fn fix_left_border ( & mut self ) {
1005+ self . fix_top ( ) ;
1006+
1007+ {
1008+ let mut cur_node = self . root . as_mut ( ) ;
1009+
1010+ while let Internal ( node) = cur_node. force ( ) {
1011+ let mut first_kv = node. first_kv ( ) ;
1012+
1013+ if first_kv. can_merge ( ) {
1014+ cur_node = first_kv. merge ( ) . descend ( ) ;
1015+ } else {
1016+ let left_len = first_kv. reborrow ( ) . left_edge ( ) . descend ( ) . len ( ) ;
1017+ if left_len < node:: MIN_LEN + 1 {
1018+ first_kv. bulk_steal_right ( node:: MIN_LEN + 1 - left_len) ;
1019+ }
1020+ cur_node = first_kv. left_edge ( ) . descend ( ) ;
1021+ }
1022+ }
1023+ }
1024+
1025+ self . fix_top ( ) ;
1026+ }
8591027}
8601028
8611029impl < ' a , K : ' a , V : ' a > IntoIterator for & ' a BTreeMap < K , V > {
0 commit comments