@@ -1229,15 +1229,82 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
12291229 return ;
12301230 }
12311231
1232- let self_iter = mem:: replace ( self , Self :: new_in ( ( * self . alloc ) . clone ( ) ) ) . into_iter ( ) ;
1233- let other_iter = mem:: replace ( other, Self :: new_in ( ( * self . alloc ) . clone ( ) ) ) . into_iter ( ) ;
1234- let root = self . root . get_or_insert_with ( || Root :: new ( ( * self . alloc ) . clone ( ) ) ) ;
1235- root. append_from_sorted_iters (
1236- self_iter,
1237- other_iter,
1238- & mut self . length ,
1239- ( * self . alloc ) . clone ( ) ,
1240- )
1232+ // Because `other` takes a &mut Self, in order for us to own
1233+ // the K,V pairs, we need to use mem::replace
1234+ let mut other_iter = mem:: replace ( other, Self :: new_in ( ( * self . alloc ) . clone ( ) ) ) . into_iter ( ) ;
1235+ let ( first_other_key, first_other_val) = other_iter. next ( ) . unwrap ( ) ;
1236+
1237+ // find the first gap that has the smallest key greater than or equal to
1238+ // the first key from other
1239+ let mut self_cursor = self . lower_bound_mut ( Bound :: Included ( & first_other_key) ) ;
1240+
1241+ if let Some ( ( self_key, _) ) = self_cursor. peek_next ( ) {
1242+ match K :: cmp ( self_key, & first_other_key) {
1243+ Ordering :: Equal => {
1244+ if let Some ( ( _, v) ) = self_cursor. next ( ) {
1245+ * v = first_other_val;
1246+ }
1247+ }
1248+ Ordering :: Greater =>
1249+ // SAFETY: we know our other_key's ordering is less than self_key,
1250+ // so inserting before will guarantee sorted order
1251+ unsafe {
1252+ self_cursor. insert_before_unchecked ( first_other_key, first_other_val) ;
1253+ } ,
1254+ Ordering :: Less => {
1255+ unreachable ! ( "Cursor's peek_next should return None." ) ;
1256+ }
1257+ }
1258+ } else {
1259+ // SAFETY: reaching here means our cursor is at the end
1260+ // self BTreeMap so we just insert other_key here
1261+ unsafe {
1262+ self_cursor. insert_before_unchecked ( first_other_key, first_other_val) ;
1263+ }
1264+ }
1265+
1266+ for ( other_key, other_val) in other_iter {
1267+ loop {
1268+ if let Some ( ( self_key, _) ) = self_cursor. peek_next ( ) {
1269+ match K :: cmp ( self_key, & other_key) {
1270+ Ordering :: Equal => {
1271+ if let Some ( ( _, v) ) = self_cursor. next ( ) {
1272+ * v = other_val;
1273+ }
1274+ break ;
1275+ }
1276+ Ordering :: Greater => {
1277+ // SAFETY: we know our self_key's ordering is greater than other_key,
1278+ // so inserting before will guarantee sorted order
1279+ unsafe {
1280+ self_cursor. insert_before_unchecked ( other_key, other_val) ;
1281+ }
1282+ break ;
1283+ }
1284+ Ordering :: Less => {
1285+ // FIXME: instead of doing a linear search here,
1286+ // this can be optimized to search the tree by starting
1287+ // from self_cursor and going towards the root and then
1288+ // back down to the proper node -- that should probably
1289+ // be a new method on Cursor*.
1290+ self_cursor. next ( ) ;
1291+ }
1292+ }
1293+ } else {
1294+ // FIXME: If we get here, that means all of other's keys are greater than
1295+ // self's keys. For performance, this should really do a bulk insertion of items
1296+ // from other_iter into the end of self `BTreeMap`. Maybe this should be
1297+ // a method for Cursor*?
1298+
1299+ // SAFETY: reaching here means our cursor is at the end
1300+ // self BTreeMap so we just insert other_key here
1301+ unsafe {
1302+ self_cursor. insert_before_unchecked ( other_key, other_val) ;
1303+ }
1304+ break ;
1305+ }
1306+ }
1307+ }
12411308 }
12421309
12431310 /// Moves all elements from `other` into `self`, leaving `other` empty.
0 commit comments