@@ -1287,7 +1287,7 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
12871287 /// assert_eq!(a[&5], "f");
12881288 /// ```
12891289 #[ unstable( feature = "btree_merge" , issue = "152152" ) ]
1290- pub fn merge ( & mut self , mut other : Self , conflict : impl FnMut ( & K , V , V ) -> V )
1290+ pub fn merge ( & mut self , mut other : Self , mut conflict : impl FnMut ( & K , V , V ) -> V )
12911291 where
12921292 K : Ord ,
12931293 A : Clone ,
@@ -1303,16 +1303,93 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
13031303 return ;
13041304 }
13051305
1306- let self_iter = mem:: replace ( self , Self :: new_in ( ( * self . alloc ) . clone ( ) ) ) . into_iter ( ) ;
1307- let other_iter = mem:: replace ( & mut other, Self :: new_in ( ( * self . alloc ) . clone ( ) ) ) . into_iter ( ) ;
1308- let root = self . root . get_or_insert_with ( || Root :: new ( ( * self . alloc ) . clone ( ) ) ) ;
1309- root. merge_from_sorted_iters_with (
1310- self_iter,
1311- other_iter,
1312- & mut self . length ,
1313- ( * self . alloc ) . clone ( ) ,
1314- conflict,
1315- )
1306+ let mut other_iter = other. into_iter ( ) ;
1307+ let ( first_other_key, first_other_val) = other_iter. next ( ) . unwrap ( ) ;
1308+
1309+ // find the first gap that has the smallest key greater than the first key from other
1310+ let mut self_cursor = self . lower_bound_mut ( Bound :: Included ( & first_other_key) ) ;
1311+
1312+ if let Some ( ( self_key, self_val) ) = self_cursor. peek_next ( ) {
1313+ match K :: cmp ( & first_other_key, self_key) {
1314+ Ordering :: Equal => {
1315+ // SAFETY: We read in self_val's and hand it over to our conflict function
1316+ // which will always return a value that we can use to overwrite what's
1317+ // in self_val
1318+ unsafe {
1319+ let val = ptr:: read ( self_val) ;
1320+ let next_val = ( conflict) ( self_key, val, first_other_val) ;
1321+ ptr:: write ( self_val, next_val) ;
1322+ }
1323+ }
1324+ Ordering :: Less => unsafe {
1325+ self_cursor. insert_before_unchecked ( first_other_key, first_other_val) ;
1326+ } ,
1327+ Ordering :: Greater => {
1328+ unreachable ! ( "cursor's peek_next would return None in this case" ) ;
1329+ }
1330+ }
1331+ } else {
1332+ // SAFETY: if we reach here, that means our cursor has reached
1333+ // the end of self BTreeMap, (other_key is greater than all the
1334+ // previous self BTreeMap keys) so we just insert other_key here
1335+ // at the end of the CursorMut
1336+ unsafe {
1337+ self_cursor. insert_after_unchecked ( first_other_key, first_other_val) ;
1338+ }
1339+ }
1340+
1341+ for ( other_key, other_val) in other_iter {
1342+ if self_cursor. peek_next ( ) . is_some ( ) {
1343+ loop {
1344+ let self_entry = self_cursor. peek_next ( ) ;
1345+ if let Some ( ( self_key, self_val) ) = self_entry {
1346+ match K :: cmp ( & other_key, self_key) {
1347+ Ordering :: Equal => {
1348+ // SAFETY: We read in self_val's and hand it over to our conflict function
1349+ // which will always return a value that we can use to overwrite what's
1350+ // in self_val
1351+ unsafe {
1352+ let val = ptr:: read ( self_val) ;
1353+ let next_val = ( conflict) ( self_key, val, other_val) ;
1354+ ptr:: write ( self_val, next_val) ;
1355+ }
1356+ break ;
1357+ }
1358+ Ordering :: Less => {
1359+ // SAFETY: we know our other_key's ordering is less than self_key,
1360+ // so inserting before will guarantee sorted order
1361+ unsafe {
1362+ self_cursor. insert_before_unchecked ( other_key, other_val) ;
1363+ }
1364+ break ;
1365+ }
1366+ Ordering :: Greater => {
1367+ self_cursor. next ( ) ;
1368+ }
1369+ }
1370+ } else {
1371+ // SAFETY: if we reach here, that means our cursor has reached
1372+ // the end of self BTreeMap, (other_key is greater than all the
1373+ // previous self BTreeMap keys) so we just insert other_key here
1374+ // at the end of the Cursor
1375+ unsafe {
1376+ self_cursor. insert_after_unchecked ( other_key, other_val) ;
1377+ }
1378+ self_cursor. next ( ) ;
1379+ break ;
1380+ }
1381+ }
1382+ } else {
1383+ // SAFETY: if we reach here, that means our cursor has reached
1384+ // the end of self BTreeMap, (other_key is greater than all the
1385+ // previous self BTreeMap keys) so we just insert the rest of
1386+ // other_keys here at the end of CursorMut
1387+ unsafe {
1388+ self_cursor. insert_after_unchecked ( other_key, other_val) ;
1389+ }
1390+ self_cursor. next ( ) ;
1391+ }
1392+ }
13161393 }
13171394
13181395 /// Constructs a double-ended iterator over a sub-range of elements in the map.
0 commit comments