|
11 | 11 | use core::cmp::Ordering;
|
12 | 12 | use core::fmt::Debug;
|
13 | 13 | use core::hash::{Hash, Hasher};
|
14 |
| -use core::iter::FromIterator; |
| 14 | +use core::iter::{FromIterator, Peekable}; |
15 | 15 | use core::marker::PhantomData;
|
16 | 16 | use core::ops::Index;
|
17 | 17 | use core::{fmt, intrinsics, mem, ptr};
|
@@ -348,6 +348,12 @@ pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
|
348 | 348 | _marker: PhantomData<&'a mut (K, V)>,
|
349 | 349 | }
|
350 | 350 |
|
| 351 | +// An iterator for merging two sorted sequences into one |
| 352 | +struct MergeIter<K, V, I: Iterator<Item=(K, V)>> { |
| 353 | + left: Peekable<I>, |
| 354 | + right: Peekable<I>, |
| 355 | +} |
| 356 | + |
351 | 357 | impl<K: Ord, V> BTreeMap<K, V> {
|
352 | 358 | /// Makes a new empty BTreeMap with a reasonable choice for B.
|
353 | 359 | ///
|
@@ -535,6 +541,62 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
535 | 541 | }
|
536 | 542 | }
|
537 | 543 |
|
| 544 | + /// Moves all elements from `other` into `Self`, leaving `other` empty. |
| 545 | + /// |
| 546 | + /// # Examples |
| 547 | + /// |
| 548 | + /// ``` |
| 549 | + /// #![feature(btree_append)] |
| 550 | + /// use std::collections::BTreeMap; |
| 551 | + /// |
| 552 | + /// let mut a = BTreeMap::new(); |
| 553 | + /// a.insert(1, "a"); |
| 554 | + /// a.insert(2, "b"); |
| 555 | + /// a.insert(3, "c"); |
| 556 | + /// |
| 557 | + /// let mut b = BTreeMap::new(); |
| 558 | + /// b.insert(3, "d"); |
| 559 | + /// b.insert(4, "e"); |
| 560 | + /// b.insert(5, "f"); |
| 561 | + /// |
| 562 | + /// a.append(&mut b); |
| 563 | + /// |
| 564 | + /// assert_eq!(a.len(), 5); |
| 565 | + /// assert_eq!(b.len(), 0); |
| 566 | + /// |
| 567 | + /// assert_eq!(a[&1], "a"); |
| 568 | + /// assert_eq!(a[&2], "b"); |
| 569 | + /// assert_eq!(a[&3], "d"); |
| 570 | + /// assert_eq!(a[&4], "e"); |
| 571 | + /// assert_eq!(a[&5], "f"); |
| 572 | + /// ``` |
| 573 | + #[unstable(feature = "btree_append", reason = "recently added as part of collections reform 2", |
| 574 | + issue = "19986")] |
| 575 | + pub fn append(&mut self, other: &mut Self) { |
| 576 | + // Do we have to append anything at all? |
| 577 | + if other.len() == 0 { |
| 578 | + return; |
| 579 | + } |
| 580 | + |
| 581 | + // We can just swap `self` and `other` if `self` is empty. |
| 582 | + if self.len() == 0 { |
| 583 | + mem::swap(self, other); |
| 584 | + return; |
| 585 | + } |
| 586 | + |
| 587 | + // First, we merge `self` and `other` into a sorted sequence in linear time. |
| 588 | + let self_iter = mem::replace(self, BTreeMap::new()).into_iter(); |
| 589 | + let other_iter = mem::replace(other, BTreeMap::new()).into_iter(); |
| 590 | + let iter = MergeIter { |
| 591 | + left: self_iter.peekable(), |
| 592 | + right: other_iter.peekable(), |
| 593 | + }; |
| 594 | + |
| 595 | + // Second, we build a tree from the sorted sequence in linear time. |
| 596 | + self.from_sorted_iter(iter); |
| 597 | + self.fix_right_edge(); |
| 598 | + } |
| 599 | + |
538 | 600 | /// Constructs a double-ended iterator over a sub-range of elements in the map, starting
|
539 | 601 | /// at min, and ending at max. If min is `Unbounded`, then it will be treated as "negative
|
540 | 602 | /// infinity", and if max is `Unbounded`, then it will be treated as "positive infinity".
|
@@ -724,6 +786,76 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
724 | 786 | })
|
725 | 787 | }
|
726 | 788 | }
|
| 789 | + |
| 790 | + fn from_sorted_iter<I: Iterator<Item=(K, V)>>(&mut self, iter: I) { |
| 791 | + let mut cur_node = last_leaf_edge(self.root.as_mut()).into_node(); |
| 792 | + // Iterate through all key-value pairs, pushing them into nodes at the right level. |
| 793 | + for (key, value) in iter { |
| 794 | + // Try to push key-value pair into the current leaf node. |
| 795 | + if cur_node.len() < node::CAPACITY { |
| 796 | + cur_node.push(key, value); |
| 797 | + } else { |
| 798 | + // No space left, go up and push there. |
| 799 | + let mut open_node; |
| 800 | + let mut test_node = cur_node.forget_type(); |
| 801 | + loop { |
| 802 | + match test_node.ascend() { |
| 803 | + Ok(parent) => { |
| 804 | + let parent = parent.into_node(); |
| 805 | + if parent.len() < node::CAPACITY { |
| 806 | + // Found a node with space left, push here. |
| 807 | + open_node = parent; |
| 808 | + break; |
| 809 | + } else { |
| 810 | + // Go up again. |
| 811 | + test_node = parent.forget_type(); |
| 812 | + } |
| 813 | + }, |
| 814 | + Err(node) => { |
| 815 | + // We are at the top, create a new root node and push there. |
| 816 | + open_node = node.into_root_mut().push_level(); |
| 817 | + break; |
| 818 | + }, |
| 819 | + } |
| 820 | + } |
| 821 | + |
| 822 | + // Push key-value pair and new right subtree. |
| 823 | + let tree_height = open_node.height() - 1; |
| 824 | + let mut right_tree = node::Root::new_leaf(); |
| 825 | + for _ in 0..tree_height { |
| 826 | + right_tree.push_level(); |
| 827 | + } |
| 828 | + open_node.push(key, value, right_tree); |
| 829 | + |
| 830 | + // Go down to the right-most leaf again. |
| 831 | + cur_node = last_leaf_edge(open_node.forget_type()).into_node(); |
| 832 | + } |
| 833 | + |
| 834 | + self.length += 1; |
| 835 | + } |
| 836 | + } |
| 837 | + |
| 838 | + fn fix_right_edge(&mut self) { |
| 839 | + // Handle underfull nodes, start from the top. |
| 840 | + let mut cur_node = self.root.as_mut(); |
| 841 | + while let Internal(internal) = cur_node.force() { |
| 842 | + // Check if right-most child is underfull. |
| 843 | + let mut last_edge = internal.last_edge(); |
| 844 | + let right_child_len = last_edge.reborrow().descend().len(); |
| 845 | + if right_child_len < node::CAPACITY / 2 { |
| 846 | + // We need to steal. |
| 847 | + let mut last_kv = match last_edge.left_kv() { |
| 848 | + Ok(left) => left, |
| 849 | + Err(_) => unreachable!(), |
| 850 | + }; |
| 851 | + last_kv.bulk_steal_left(node::CAPACITY/2 - right_child_len); |
| 852 | + last_edge = last_kv.right_edge(); |
| 853 | + } |
| 854 | + |
| 855 | + // Go further down. |
| 856 | + cur_node = last_edge.descend(); |
| 857 | + } |
| 858 | + } |
727 | 859 | }
|
728 | 860 |
|
729 | 861 | impl<'a, K: 'a, V: 'a> IntoIterator for &'a BTreeMap<K, V> {
|
@@ -1690,32 +1822,41 @@ fn handle_underfull_node<'a, K, V>(node: NodeRef<marker::Mut<'a>,
|
1690 | 1822 | };
|
1691 | 1823 |
|
1692 | 1824 | if handle.can_merge() {
|
1693 |
| - return Merged(handle.merge().into_node()); |
| 1825 | + Merged(handle.merge().into_node()) |
1694 | 1826 | } else {
|
1695 |
| - unsafe { |
1696 |
| - let (k, v, edge) = if is_left { |
1697 |
| - handle.reborrow_mut().left_edge().descend().pop() |
1698 |
| - } else { |
1699 |
| - handle.reborrow_mut().right_edge().descend().pop_front() |
1700 |
| - }; |
| 1827 | + if is_left { |
| 1828 | + handle.steal_left(); |
| 1829 | + } else { |
| 1830 | + handle.steal_right(); |
| 1831 | + } |
| 1832 | + Stole(handle.into_node()) |
| 1833 | + } |
| 1834 | +} |
1701 | 1835 |
|
1702 |
| - let k = mem::replace(handle.reborrow_mut().into_kv_mut().0, k); |
1703 |
| - let v = mem::replace(handle.reborrow_mut().into_kv_mut().1, v); |
| 1836 | +impl<K: Ord, V, I: Iterator<Item=(K, V)>> Iterator for MergeIter<K, V, I> { |
| 1837 | + type Item = (K, V); |
1704 | 1838 |
|
1705 |
| - // FIXME: reuse cur_node? |
1706 |
| - if is_left { |
1707 |
| - match handle.reborrow_mut().right_edge().descend().force() { |
1708 |
| - Leaf(mut leaf) => leaf.push_front(k, v), |
1709 |
| - Internal(mut internal) => internal.push_front(k, v, edge.unwrap()) |
1710 |
| - } |
1711 |
| - } else { |
1712 |
| - match handle.reborrow_mut().left_edge().descend().force() { |
1713 |
| - Leaf(mut leaf) => leaf.push(k, v), |
1714 |
| - Internal(mut internal) => internal.push(k, v, edge.unwrap()) |
1715 |
| - } |
1716 |
| - } |
1717 |
| - } |
| 1839 | + fn next(&mut self) -> Option<(K, V)> { |
| 1840 | + let res = match (self.left.peek(), self.right.peek()) { |
| 1841 | + (Some(&(ref left_key, _)), Some(&(ref right_key, _))) => left_key.cmp(right_key), |
| 1842 | + (Some(_), None) => Ordering::Less, |
| 1843 | + (None, Some(_)) => Ordering::Greater, |
| 1844 | + (None, None) => return None, |
| 1845 | + }; |
1718 | 1846 |
|
1719 |
| - return Stole(handle.into_node()); |
| 1847 | + // Check which elements comes first and only advance the corresponding iterator. |
| 1848 | + // If two keys are equal, take the value from `right`. |
| 1849 | + match res { |
| 1850 | + Ordering::Less => { |
| 1851 | + self.left.next() |
| 1852 | + }, |
| 1853 | + Ordering::Greater => { |
| 1854 | + self.right.next() |
| 1855 | + }, |
| 1856 | + Ordering::Equal => { |
| 1857 | + self.left.next(); |
| 1858 | + self.right.next() |
| 1859 | + }, |
| 1860 | + } |
1720 | 1861 | }
|
1721 | 1862 | }
|
0 commit comments