@@ -77,6 +77,24 @@ pub struct Node<K, V> {
77
77
_capacity : uint ,
78
78
}
79
79
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
+
80
98
/// Rounds up to a multiple of a power of two. Returns the closest multiple
81
99
/// of `target_alignment` that is higher or equal to `unrounded`.
82
100
///
@@ -342,7 +360,8 @@ impl<K, V> Node<K, V> {
342
360
}
343
361
344
362
#[ 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 ( ) ;
346
365
let ( keys, vals) = self . as_slices ( ) ;
347
366
let edges: & [ _ ] = if self . is_leaf ( ) {
348
367
& [ ]
@@ -354,12 +373,18 @@ impl<K, V> Node<K, V> {
354
373
} )
355
374
}
356
375
} ;
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
+ }
358
384
}
359
385
360
386
#[ 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 > {
363
388
unsafe { mem:: transmute ( self . as_slices_internal ( ) ) }
364
389
}
365
390
@@ -385,12 +410,12 @@ impl<K, V> Node<K, V> {
385
410
386
411
#[ inline]
387
412
pub fn edges < ' a > ( & ' a self ) -> & ' a [ Node < K , V > ] {
388
- self . as_slices_internal ( ) . 2
413
+ self . as_slices_internal ( ) . edges
389
414
}
390
415
391
416
#[ inline]
392
417
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
394
419
}
395
420
}
396
421
@@ -522,30 +547,11 @@ impl<K: Ord, V> Node<K, V> {
522
547
// FIXME(Gankro): Tune when to search linear or binary based on B (and maybe K/V).
523
548
// For the B configured as of this writing (B = 6), binary search was *significantly*
524
549
// 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 } ) ,
536
553
}
537
554
}
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
- }
549
555
}
550
556
551
557
// Public interface
@@ -1043,31 +1049,11 @@ impl<K, V> Node<K, V> {
1043
1049
}
1044
1050
1045
1051
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 ( )
1057
1053
}
1058
1054
1059
1055
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 ( )
1071
1057
}
1072
1058
1073
1059
pub fn into_iter ( self ) -> MoveTraversal < K , V > {
@@ -1311,22 +1297,27 @@ fn min_load_from_capacity(cap: uint) -> uint {
1311
1297
/// A trait for pairs of `Iterator`s, one over edges and the other over key/value pairs. This is
1312
1298
/// necessary, as the `MoveTraversalImpl` needs to have a destructor that deallocates the `Node`,
1313
1299
/// 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 > ;
1317
1306
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 > ;
1320
1309
}
1321
1310
1322
1311
/// A `TraversalImpl` that actually is backed by two iterators. This works in the non-moving case,
1323
1312
/// as no deallocation needs to be done.
1324
1313
struct ElemsAndEdges < Elems , Edges > ( Elems , Edges ) ;
1325
1314
1326
1315
impl < K , V , E , Elems : DoubleEndedIterator , Edges : DoubleEndedIterator >
1327
- TraversalImpl < K , V , E > for ElemsAndEdges < Elems , Edges >
1316
+ TraversalImpl for ElemsAndEdges < Elems , Edges >
1328
1317
where Elems : Iterator < Item =( K , V ) > , Edges : Iterator < Item =E >
1329
1318
{
1319
+ type Item = ( K , V ) ;
1320
+ type Edge = E ;
1330
1321
1331
1322
fn next_kv ( & mut self ) -> Option < ( K , V ) > { self . 0 . next ( ) }
1332
1323
fn next_kv_back ( & mut self ) -> Option < ( K , V ) > { self . 0 . next_back ( ) }
@@ -1347,7 +1338,10 @@ struct MoveTraversalImpl<K, V> {
1347
1338
is_leaf : bool
1348
1339
}
1349
1340
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
+
1351
1345
fn next_kv ( & mut self ) -> Option < ( K , V ) > {
1352
1346
match ( self . keys . next ( ) , self . vals . next ( ) ) {
1353
1347
( Some ( k) , Some ( v) ) => Some ( ( k, v) ) ,
@@ -1398,9 +1392,12 @@ struct AbsTraversal<Impl> {
1398
1392
has_edges : bool ,
1399
1393
}
1400
1394
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.
1402
1396
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.
1404
1401
Edge ( E ) ,
1405
1402
}
1406
1403
@@ -1417,32 +1414,175 @@ pub type MutTraversal<'a, K, V> = AbsTraversal<ElemsAndEdges<Zip<slice::Iter<'a,
1417
1414
/// An owning traversal over a node's entries and edges
1418
1415
pub type MoveTraversal < K , V > = AbsTraversal < MoveTraversalImpl < K , V > > ;
1419
1416
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 > {
1422
1420
type Item = TraversalItem < K , V , E > ;
1423
1421
1424
1422
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
+ }
1427
1428
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 ( )
1430
1482
} else {
1431
- self . inner . next_kv ( ) . map ( | ( k , v ) | Elem ( k , v ) )
1483
+ None
1432
1484
}
1433
1485
}
1434
1486
}
1435
1487
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
+ }
1441
1504
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
+ }
1446
1582
}
1447
1583
}
1448
1584
}
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