Skip to content

Commit 75f0336

Browse files
committed
---
yaml --- r: 174375 b: refs/heads/master c: 7f8c687 h: refs/heads/master i: 174373: 1b78779 174371: 74b9fb4 174367: 86ba9ff v: v3
1 parent 2b654b0 commit 75f0336

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+1244
-662
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: a320149dcce2eb27d3014113cbf87aacc04d24eb
2+
refs/heads/master: 7f8c687fdfbf076ef1667f4d95633d4e0812b516
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 9006c3c0f14be45da8ffeba43d354d088e366c83
55
refs/heads/try: 08f6380a9f0b866796080094f44fe25ea5636547

trunk/src/libcollections/btree/map.rs

Lines changed: 333 additions & 118 deletions
Large diffs are not rendered by default.

trunk/src/libcollections/btree/node.rs

Lines changed: 215 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,24 @@ pub struct Node<K, V> {
7777
_capacity: uint,
7878
}
7979

80+
struct NodeSlice<'a, K: 'a, V: 'a> {
81+
keys: &'a [K],
82+
vals: &'a [V],
83+
pub edges: &'a [Node<K, V>],
84+
head_is_edge: bool,
85+
tail_is_edge: bool,
86+
has_edges: bool,
87+
}
88+
89+
struct MutNodeSlice<'a, K: 'a, V: 'a> {
90+
keys: &'a [K],
91+
vals: &'a mut [V],
92+
pub edges: &'a mut [Node<K, V>],
93+
head_is_edge: bool,
94+
tail_is_edge: bool,
95+
has_edges: bool,
96+
}
97+
8098
/// Rounds up to a multiple of a power of two. Returns the closest multiple
8199
/// of `target_alignment` that is higher or equal to `unrounded`.
82100
///
@@ -342,7 +360,8 @@ impl<K, V> Node<K, V> {
342360
}
343361

344362
#[inline]
345-
pub fn as_slices_internal<'a>(&'a self) -> (&'a [K], &'a [V], &'a [Node<K, V>]) {
363+
pub fn as_slices_internal<'b>(&'b self) -> NodeSlice<'b, K, V> {
364+
let is_leaf = self.is_leaf();
346365
let (keys, vals) = self.as_slices();
347366
let edges: &[_] = if self.is_leaf() {
348367
&[]
@@ -354,12 +373,18 @@ impl<K, V> Node<K, V> {
354373
})
355374
}
356375
};
357-
(keys, vals, edges)
376+
NodeSlice {
377+
keys: keys,
378+
vals: vals,
379+
edges: edges,
380+
head_is_edge: true,
381+
tail_is_edge: true,
382+
has_edges: !is_leaf,
383+
}
358384
}
359385

360386
#[inline]
361-
pub fn as_slices_internal_mut<'a>(&'a mut self) -> (&'a mut [K], &'a mut [V],
362-
&'a mut [Node<K, V>]) {
387+
pub fn as_slices_internal_mut<'b>(&'b mut self) -> MutNodeSlice<'b, K, V> {
363388
unsafe { mem::transmute(self.as_slices_internal()) }
364389
}
365390

@@ -385,12 +410,12 @@ impl<K, V> Node<K, V> {
385410

386411
#[inline]
387412
pub fn edges<'a>(&'a self) -> &'a [Node<K, V>] {
388-
self.as_slices_internal().2
413+
self.as_slices_internal().edges
389414
}
390415

391416
#[inline]
392417
pub fn edges_mut<'a>(&'a mut self) -> &'a mut [Node<K, V>] {
393-
self.as_slices_internal_mut().2
418+
self.as_slices_internal_mut().edges
394419
}
395420
}
396421

@@ -522,30 +547,11 @@ impl<K: Ord, V> Node<K, V> {
522547
// FIXME(Gankro): Tune when to search linear or binary based on B (and maybe K/V).
523548
// For the B configured as of this writing (B = 6), binary search was *significantly*
524549
// worse for uints.
525-
let (found, index) = node.search_linear(key);
526-
if found {
527-
Found(Handle {
528-
node: node,
529-
index: index
530-
})
531-
} else {
532-
GoDown(Handle {
533-
node: node,
534-
index: index
535-
})
550+
match node.as_slices_internal().search_linear(key) {
551+
(index, true) => Found(Handle { node: node, index: index }),
552+
(index, false) => GoDown(Handle { node: node, index: index }),
536553
}
537554
}
538-
539-
fn search_linear<Q: ?Sized>(&self, key: &Q) -> (bool, uint) where Q: BorrowFrom<K> + Ord {
540-
for (i, k) in self.keys().iter().enumerate() {
541-
match key.cmp(BorrowFrom::borrow_from(k)) {
542-
Greater => {},
543-
Equal => return (true, i),
544-
Less => return (false, i),
545-
}
546-
}
547-
(false, self.len())
548-
}
549555
}
550556

551557
// Public interface
@@ -1043,31 +1049,11 @@ impl<K, V> Node<K, V> {
10431049
}
10441050

10451051
pub fn iter<'a>(&'a self) -> Traversal<'a, K, V> {
1046-
let is_leaf = self.is_leaf();
1047-
let (keys, vals, edges) = self.as_slices_internal();
1048-
Traversal {
1049-
inner: ElemsAndEdges(
1050-
keys.iter().zip(vals.iter()),
1051-
edges.iter()
1052-
),
1053-
head_is_edge: true,
1054-
tail_is_edge: true,
1055-
has_edges: !is_leaf,
1056-
}
1052+
self.as_slices_internal().iter()
10571053
}
10581054

10591055
pub fn iter_mut<'a>(&'a mut self) -> MutTraversal<'a, K, V> {
1060-
let is_leaf = self.is_leaf();
1061-
let (keys, vals, edges) = self.as_slices_internal_mut();
1062-
MutTraversal {
1063-
inner: ElemsAndEdges(
1064-
keys.iter().zip(vals.iter_mut()),
1065-
edges.iter_mut()
1066-
),
1067-
head_is_edge: true,
1068-
tail_is_edge: true,
1069-
has_edges: !is_leaf,
1070-
}
1056+
self.as_slices_internal_mut().iter_mut()
10711057
}
10721058

10731059
pub fn into_iter(self) -> MoveTraversal<K, V> {
@@ -1311,22 +1297,27 @@ fn min_load_from_capacity(cap: uint) -> uint {
13111297
/// A trait for pairs of `Iterator`s, one over edges and the other over key/value pairs. This is
13121298
/// necessary, as the `MoveTraversalImpl` needs to have a destructor that deallocates the `Node`,
13131299
/// and a pair of `Iterator`s would require two independent destructors.
1314-
trait TraversalImpl<K, V, E> {
1315-
fn next_kv(&mut self) -> Option<(K, V)>;
1316-
fn next_kv_back(&mut self) -> Option<(K, V)>;
1300+
trait TraversalImpl {
1301+
type Item;
1302+
type Edge;
1303+
1304+
fn next_kv(&mut self) -> Option<Self::Item>;
1305+
fn next_kv_back(&mut self) -> Option<Self::Item>;
13171306

1318-
fn next_edge(&mut self) -> Option<E>;
1319-
fn next_edge_back(&mut self) -> Option<E>;
1307+
fn next_edge(&mut self) -> Option<Self::Edge>;
1308+
fn next_edge_back(&mut self) -> Option<Self::Edge>;
13201309
}
13211310

13221311
/// A `TraversalImpl` that actually is backed by two iterators. This works in the non-moving case,
13231312
/// as no deallocation needs to be done.
13241313
struct ElemsAndEdges<Elems, Edges>(Elems, Edges);
13251314

13261315
impl<K, V, E, Elems: DoubleEndedIterator, Edges: DoubleEndedIterator>
1327-
TraversalImpl<K, V, E> for ElemsAndEdges<Elems, Edges>
1316+
TraversalImpl for ElemsAndEdges<Elems, Edges>
13281317
where Elems : Iterator<Item=(K, V)>, Edges : Iterator<Item=E>
13291318
{
1319+
type Item = (K, V);
1320+
type Edge = E;
13301321

13311322
fn next_kv(&mut self) -> Option<(K, V)> { self.0.next() }
13321323
fn next_kv_back(&mut self) -> Option<(K, V)> { self.0.next_back() }
@@ -1347,7 +1338,10 @@ struct MoveTraversalImpl<K, V> {
13471338
is_leaf: bool
13481339
}
13491340

1350-
impl<K, V> TraversalImpl<K, V, Node<K, V>> for MoveTraversalImpl<K, V> {
1341+
impl<K, V> TraversalImpl for MoveTraversalImpl<K, V> {
1342+
type Item = (K, V);
1343+
type Edge = Node<K, V>;
1344+
13511345
fn next_kv(&mut self) -> Option<(K, V)> {
13521346
match (self.keys.next(), self.vals.next()) {
13531347
(Some(k), Some(v)) => Some((k, v)),
@@ -1398,9 +1392,12 @@ struct AbsTraversal<Impl> {
13981392
has_edges: bool,
13991393
}
14001394

1401-
/// A single atomic step in a traversal. Either an element is visited, or an edge is followed
1395+
/// A single atomic step in a traversal.
14021396
pub enum TraversalItem<K, V, E> {
1403-
Elem(K, V),
1397+
/// An element is visited. This isn't written as `Elem(K, V)` just because `opt.map(Elem)`
1398+
/// requires the function to take a single argument. (Enum constructors are functions.)
1399+
Elem((K, V)),
1400+
/// An edge is followed.
14041401
Edge(E),
14051402
}
14061403

@@ -1417,32 +1414,175 @@ pub type MutTraversal<'a, K, V> = AbsTraversal<ElemsAndEdges<Zip<slice::Iter<'a,
14171414
/// An owning traversal over a node's entries and edges
14181415
pub type MoveTraversal<K, V> = AbsTraversal<MoveTraversalImpl<K, V>>;
14191416

1420-
#[old_impl_check]
1421-
impl<K, V, E, Impl: TraversalImpl<K, V, E>> Iterator for AbsTraversal<Impl> {
1417+
1418+
impl<K, V, E, Impl> Iterator for AbsTraversal<Impl>
1419+
where Impl: TraversalImpl<Item=(K, V), Edge=E> {
14221420
type Item = TraversalItem<K, V, E>;
14231421

14241422
fn next(&mut self) -> Option<TraversalItem<K, V, E>> {
1425-
let head_is_edge = self.head_is_edge;
1426-
self.head_is_edge = !head_is_edge;
1423+
self.next_edge_item().map(Edge).or_else(||
1424+
self.next_kv_item().map(Elem)
1425+
)
1426+
}
1427+
}
14271428

1428-
if head_is_edge && self.has_edges {
1429-
self.inner.next_edge().map(|node| Edge(node))
1429+
impl<K, V, E, Impl> DoubleEndedIterator for AbsTraversal<Impl>
1430+
where Impl: TraversalImpl<Item=(K, V), Edge=E> {
1431+
fn next_back(&mut self) -> Option<TraversalItem<K, V, E>> {
1432+
self.next_edge_item_back().map(Edge).or_else(||
1433+
self.next_kv_item_back().map(Elem)
1434+
)
1435+
}
1436+
}
1437+
1438+
impl<K, V, E, Impl> AbsTraversal<Impl>
1439+
where Impl: TraversalImpl<Item=(K, V), Edge=E> {
1440+
/// Advances the iterator and returns the item if it's an edge. Returns None
1441+
/// and does nothing if the first item is not an edge.
1442+
pub fn next_edge_item(&mut self) -> Option<E> {
1443+
// NB. `&& self.has_edges` might be redundant in this condition.
1444+
let edge = if self.head_is_edge && self.has_edges {
1445+
self.inner.next_edge()
1446+
} else {
1447+
None
1448+
};
1449+
self.head_is_edge = false;
1450+
edge
1451+
}
1452+
1453+
/// Advances the iterator and returns the item if it's an edge. Returns None
1454+
/// and does nothing if the last item is not an edge.
1455+
pub fn next_edge_item_back(&mut self) -> Option<E> {
1456+
let edge = if self.tail_is_edge && self.has_edges {
1457+
self.inner.next_edge_back()
1458+
} else {
1459+
None
1460+
};
1461+
self.tail_is_edge = false;
1462+
edge
1463+
}
1464+
1465+
/// Advances the iterator and returns the item if it's a key-value pair. Returns None
1466+
/// and does nothing if the first item is not a key-value pair.
1467+
pub fn next_kv_item(&mut self) -> Option<(K, V)> {
1468+
if !self.head_is_edge {
1469+
self.head_is_edge = true;
1470+
self.inner.next_kv()
1471+
} else {
1472+
None
1473+
}
1474+
}
1475+
1476+
/// Advances the iterator and returns the item if it's a key-value pair. Returns None
1477+
/// and does nothing if the last item is not a key-value pair.
1478+
pub fn next_kv_item_back(&mut self) -> Option<(K, V)> {
1479+
if !self.tail_is_edge {
1480+
self.tail_is_edge = true;
1481+
self.inner.next_kv_back()
14301482
} else {
1431-
self.inner.next_kv().map(|(k, v)| Elem(k, v))
1483+
None
14321484
}
14331485
}
14341486
}
14351487

1436-
#[old_impl_check]
1437-
impl<K, V, E, Impl: TraversalImpl<K, V, E>> DoubleEndedIterator for AbsTraversal<Impl> {
1438-
fn next_back(&mut self) -> Option<TraversalItem<K, V, E>> {
1439-
let tail_is_edge = self.tail_is_edge;
1440-
self.tail_is_edge = !tail_is_edge;
1488+
macro_rules! node_slice_impl {
1489+
($NodeSlice:ident, $Traversal:ident,
1490+
$as_slices_internal:ident, $slice_from:ident, $slice_to:ident, $iter:ident) => {
1491+
impl<'a, K: Ord + 'a, V: 'a> $NodeSlice<'a, K, V> {
1492+
/// Performs linear search in a slice. Returns a tuple of (index, is_exact_match).
1493+
fn search_linear<Q: ?Sized>(&self, key: &Q) -> (uint, bool)
1494+
where Q: BorrowFrom<K> + Ord {
1495+
for (i, k) in self.keys.iter().enumerate() {
1496+
match key.cmp(BorrowFrom::borrow_from(k)) {
1497+
Greater => {},
1498+
Equal => return (i, true),
1499+
Less => return (i, false),
1500+
}
1501+
}
1502+
(self.keys.len(), false)
1503+
}
14411504

1442-
if tail_is_edge && self.has_edges {
1443-
self.inner.next_edge_back().map(|node| Edge(node))
1444-
} else {
1445-
self.inner.next_kv_back().map(|(k, v)| Elem(k, v))
1505+
/// Returns a sub-slice with elements starting with `min_key`.
1506+
pub fn slice_from(self, min_key: &K) -> $NodeSlice<'a, K, V> {
1507+
// _______________
1508+
// |_1_|_3_|_5_|_7_|
1509+
// | | | | |
1510+
// 0 0 1 1 2 2 3 3 4 index
1511+
// | | | | |
1512+
// \___|___|___|___/ slice_from(&0); pos = 0
1513+
// \___|___|___/ slice_from(&2); pos = 1
1514+
// |___|___|___/ slice_from(&3); pos = 1; result.head_is_edge = false
1515+
// \___|___/ slice_from(&4); pos = 2
1516+
// \___/ slice_from(&6); pos = 3
1517+
// \|/ slice_from(&999); pos = 4
1518+
let (pos, pos_is_kv) = self.search_linear(min_key);
1519+
$NodeSlice {
1520+
has_edges: self.has_edges,
1521+
edges: if !self.has_edges {
1522+
self.edges
1523+
} else {
1524+
self.edges.$slice_from(pos)
1525+
},
1526+
keys: self.keys.slice_from(pos),
1527+
vals: self.vals.$slice_from(pos),
1528+
head_is_edge: !pos_is_kv,
1529+
tail_is_edge: self.tail_is_edge,
1530+
}
1531+
}
1532+
1533+
/// Returns a sub-slice with elements up to and including `max_key`.
1534+
pub fn slice_to(self, max_key: &K) -> $NodeSlice<'a, K, V> {
1535+
// _______________
1536+
// |_1_|_3_|_5_|_7_|
1537+
// | | | | |
1538+
// 0 0 1 1 2 2 3 3 4 index
1539+
// | | | | |
1540+
//\|/ | | | | slice_to(&0); pos = 0
1541+
// \___/ | | | slice_to(&2); pos = 1
1542+
// \___|___| | | slice_to(&3); pos = 1; result.tail_is_edge = false
1543+
// \___|___/ | | slice_to(&4); pos = 2
1544+
// \___|___|___/ | slice_to(&6); pos = 3
1545+
// \___|___|___|___/ slice_to(&999); pos = 4
1546+
let (pos, pos_is_kv) = self.search_linear(max_key);
1547+
let pos = pos + if pos_is_kv { 1 } else { 0 };
1548+
$NodeSlice {
1549+
has_edges: self.has_edges,
1550+
edges: if !self.has_edges {
1551+
self.edges
1552+
} else {
1553+
self.edges.$slice_to(pos + 1)
1554+
},
1555+
keys: self.keys.slice_to(pos),
1556+
vals: self.vals.$slice_to(pos),
1557+
head_is_edge: self.head_is_edge,
1558+
tail_is_edge: !pos_is_kv,
1559+
}
1560+
}
1561+
}
1562+
1563+
impl<'a, K: 'a, V: 'a> $NodeSlice<'a, K, V> {
1564+
/// Returns an iterator over key/value pairs and edges in a slice.
1565+
#[inline]
1566+
pub fn $iter(self) -> $Traversal<'a, K, V> {
1567+
let mut edges = self.edges.$iter();
1568+
// Skip edges at both ends, if excluded.
1569+
if !self.head_is_edge { edges.next(); }
1570+
if !self.tail_is_edge { edges.next_back(); }
1571+
// The key iterator is always immutable.
1572+
$Traversal {
1573+
inner: ElemsAndEdges(
1574+
self.keys.iter().zip(self.vals.$iter()),
1575+
edges
1576+
),
1577+
head_is_edge: self.head_is_edge,
1578+
tail_is_edge: self.tail_is_edge,
1579+
has_edges: self.has_edges,
1580+
}
1581+
}
14461582
}
14471583
}
14481584
}
1585+
1586+
node_slice_impl!(NodeSlice, Traversal, as_slices_internal, slice_from, slice_to, iter);
1587+
node_slice_impl!(MutNodeSlice, MutTraversal, as_slices_internal_mut, slice_from_mut,
1588+
slice_to_mut, iter_mut);

0 commit comments

Comments
 (0)