Skip to content

Commit 74b9fb4

Browse files
Oliver 'ker' SchneiderOliver Schneider
authored andcommitted
---
yaml --- r: 174371 b: refs/heads/master c: f015a3b h: refs/heads/master i: 174369: 2306dc6 174367: 86ba9ff v: v3
1 parent 20faabb commit 74b9fb4

Some content is hidden

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

65 files changed

+816
-1322
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: 4032b85aec962486af7f205e72e93efc8a0bc434
2+
refs/heads/master: f015a3b871a7eade289842a868f6de580740d89c
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: 118 additions & 333 deletions
Large diffs are not rendered by default.

trunk/src/libcollections/btree/node.rs

Lines changed: 75 additions & 215 deletions
Original file line numberDiff line numberDiff line change
@@ -77,24 +77,6 @@ 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-
9880
/// Rounds up to a multiple of a power of two. Returns the closest multiple
9981
/// of `target_alignment` that is higher or equal to `unrounded`.
10082
///
@@ -360,8 +342,7 @@ impl<K, V> Node<K, V> {
360342
}
361343

362344
#[inline]
363-
pub fn as_slices_internal<'b>(&'b self) -> NodeSlice<'b, K, V> {
364-
let is_leaf = self.is_leaf();
345+
pub fn as_slices_internal<'a>(&'a self) -> (&'a [K], &'a [V], &'a [Node<K, V>]) {
365346
let (keys, vals) = self.as_slices();
366347
let edges: &[_] = if self.is_leaf() {
367348
&[]
@@ -373,18 +354,12 @@ impl<K, V> Node<K, V> {
373354
})
374355
}
375356
};
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-
}
357+
(keys, vals, edges)
384358
}
385359

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

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

411386
#[inline]
412387
pub fn edges<'a>(&'a self) -> &'a [Node<K, V>] {
413-
self.as_slices_internal().edges
388+
self.as_slices_internal().2
414389
}
415390

416391
#[inline]
417392
pub fn edges_mut<'a>(&'a mut self) -> &'a mut [Node<K, V>] {
418-
self.as_slices_internal_mut().edges
393+
self.as_slices_internal_mut().2
419394
}
420395
}
421396

@@ -547,11 +522,30 @@ impl<K: Ord, V> Node<K, V> {
547522
// FIXME(Gankro): Tune when to search linear or binary based on B (and maybe K/V).
548523
// For the B configured as of this writing (B = 6), binary search was *significantly*
549524
// worse for uints.
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 }),
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+
})
553536
}
554537
}
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+
}
555549
}
556550

557551
// Public interface
@@ -1049,11 +1043,31 @@ impl<K, V> Node<K, V> {
10491043
}
10501044

10511045
pub fn iter<'a>(&'a self) -> Traversal<'a, K, V> {
1052-
self.as_slices_internal().iter()
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+
}
10531057
}
10541058

10551059
pub fn iter_mut<'a>(&'a mut self) -> MutTraversal<'a, K, V> {
1056-
self.as_slices_internal_mut().iter_mut()
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+
}
10571071
}
10581072

10591073
pub fn into_iter(self) -> MoveTraversal<K, V> {
@@ -1297,27 +1311,22 @@ fn min_load_from_capacity(cap: uint) -> uint {
12971311
/// A trait for pairs of `Iterator`s, one over edges and the other over key/value pairs. This is
12981312
/// necessary, as the `MoveTraversalImpl` needs to have a destructor that deallocates the `Node`,
12991313
/// and a pair of `Iterator`s would require two independent destructors.
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>;
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)>;
13061317

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

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

13151326
impl<K, V, E, Elems: DoubleEndedIterator, Edges: DoubleEndedIterator>
1316-
TraversalImpl for ElemsAndEdges<Elems, Edges>
1327+
TraversalImpl<K, V, E> for ElemsAndEdges<Elems, Edges>
13171328
where Elems : Iterator<Item=(K, V)>, Edges : Iterator<Item=E>
13181329
{
1319-
type Item = (K, V);
1320-
type Edge = E;
13211330

13221331
fn next_kv(&mut self) -> Option<(K, V)> { self.0.next() }
13231332
fn next_kv_back(&mut self) -> Option<(K, V)> { self.0.next_back() }
@@ -1338,10 +1347,7 @@ struct MoveTraversalImpl<K, V> {
13381347
is_leaf: bool
13391348
}
13401349

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

1395-
/// A single atomic step in a traversal.
1401+
/// A single atomic step in a traversal. Either an element is visited, or an edge is followed
13961402
pub enum TraversalItem<K, V, E> {
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.
1403+
Elem(K, V),
14011404
Edge(E),
14021405
}
14031406

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

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

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

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()
1428+
if head_is_edge && self.has_edges {
1429+
self.inner.next_edge().map(|node| Edge(node))
14821430
} else {
1483-
None
1431+
self.inner.next_kv().map(|(k, v)| Elem(k, v))
14841432
}
14851433
}
14861434
}
14871435

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-
}
1504-
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-
}
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;
15621441

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-
}
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))
15821446
}
15831447
}
15841448
}
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)