Skip to content

Commit c9b6aba

Browse files
committed
---
yaml --- r: 277303 b: refs/heads/try c: 241a3e4 h: refs/heads/master i: 277301: 7bea81b 277299: 32695fc 277295: 4a36d94
1 parent 511f573 commit c9b6aba

File tree

26 files changed

+861
-802
lines changed

26 files changed

+861
-802
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 6dbb0e86aec11050480beb76eade6fb805010ba7
33
refs/heads/snap-stage3: 235d77457d80b549dad3ac36d94f235208a1eafb
4-
refs/heads/try: af000a7bbffcaf5e75ff97b245fa5a413062acc1
4+
refs/heads/try: 241a3e4689d3004daf9e1d36cec2235cbd301fbf
55
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
66
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
77
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try/configure

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,6 @@ opt llvm-version-check 1 "check if the LLVM version is supported, build anyway"
609609
opt rustbuild 0 "use the rust and cargo based build system"
610610
opt orbit 0 "get MIR where it belongs - everywhere; most importantly, in orbit"
611611
opt codegen-tests 1 "run the src/test/codegen tests"
612-
opt option-checking 1 "complain about unrecognized options in this configure script"
613612

614613
# Optimization and debugging options. These may be overridden by the release channel, etc.
615614
opt_nosave optimize 1 "build optimized rust code"
@@ -675,11 +674,8 @@ then
675674
fi
676675

677676
# Validate Options
678-
if [ -z "$CFG_DISABLE_OPTION_CHECKING" ]
679-
then
680-
step_msg "validating $CFG_SELF args"
681-
validate_opt
682-
fi
677+
step_msg "validating $CFG_SELF args"
678+
validate_opt
683679

684680
# Validate the release channel, and configure options
685681
case "$CFG_RELEASE_CHANNEL" in

branches/try/src/libcollections/btree/map.rs

Lines changed: 165 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use core::cmp::Ordering;
1212
use core::fmt::Debug;
1313
use core::hash::{Hash, Hasher};
14-
use core::iter::FromIterator;
14+
use core::iter::{FromIterator, Peekable};
1515
use core::marker::PhantomData;
1616
use core::ops::Index;
1717
use core::{fmt, intrinsics, mem, ptr};
@@ -348,6 +348,12 @@ pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
348348
_marker: PhantomData<&'a mut (K, V)>,
349349
}
350350

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+
351357
impl<K: Ord, V> BTreeMap<K, V> {
352358
/// Makes a new empty BTreeMap with a reasonable choice for B.
353359
///
@@ -535,6 +541,62 @@ impl<K: Ord, V> BTreeMap<K, V> {
535541
}
536542
}
537543

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+
538600
/// Constructs a double-ended iterator over a sub-range of elements in the map, starting
539601
/// at min, and ending at max. If min is `Unbounded`, then it will be treated as "negative
540602
/// 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> {
724786
})
725787
}
726788
}
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+
}
727859
}
728860

729861
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>,
16901822
};
16911823

16921824
if handle.can_merge() {
1693-
return Merged(handle.merge().into_node());
1825+
Merged(handle.merge().into_node())
16941826
} 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+
}
17011835

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);
17041838

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+
};
17181846

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+
}
17201861
}
17211862
}

0 commit comments

Comments
 (0)