Skip to content

Commit ed8329b

Browse files
authored
Completely hide NodeIterator from public name spaces. (#100)
1 parent ab0cfb9 commit ed8329b

File tree

5 files changed

+90
-79
lines changed

5 files changed

+90
-79
lines changed

src/_macros.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,18 @@ macro_rules! table_row_access {
216216
};
217217
}
218218

219+
macro_rules! iterator_for_nodeiterator {
220+
($ty: ty) => {
221+
impl Iterator for $ty {
222+
type Item = crate::tsk_id_t;
223+
fn next(&mut self) -> Option<Self::Item> {
224+
self.next_node();
225+
self.current_node()
226+
}
227+
}
228+
};
229+
}
230+
219231
#[cfg(test)]
220232
mod test {
221233
use crate::error::TskitError;

src/ffi.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ impl<T: Copy> WrappedTskArray<T> {
4444
///
4545
/// This function returns the raw C pointer,
4646
/// and is thus unsafe.
47-
pub unsafe fn as_ptr(&self) -> *const T {
47+
pub fn as_ptr(&self) -> *const T {
4848
self.array
4949
}
5050

src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ pub use node_table::{NodeTable, NodeTableRow};
9393
pub use population_table::{PopulationTable, PopulationTableRow};
9494
pub use site_table::{SiteTable, SiteTableRow};
9595
pub use table_collection::TableCollection;
96-
pub use traits::NodeIterator;
9796
pub use traits::NodeListGenerator;
9897
pub use traits::TableAccess;
9998
pub use traits::TskitTypeAccess;

src/traits.rs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -197,18 +197,3 @@ pub trait NodeListGenerator: TableAccess {
197197
self.nodes().create_node_id_vector(f)
198198
}
199199
}
200-
201-
/// Trait defining iteration over nodes.
202-
pub trait NodeIterator {
203-
fn next_node(&mut self);
204-
fn current_node(&mut self) -> Option<tsk_id_t>;
205-
}
206-
207-
impl Iterator for dyn NodeIterator {
208-
type Item = tsk_id_t;
209-
210-
fn next(&mut self) -> Option<tsk_id_t> {
211-
self.next_node();
212-
self.current_node()
213-
}
214-
}

src/trees.rs

Lines changed: 77 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use crate::EdgeTable;
55
use crate::IndividualTable;
66
use crate::MigrationTable;
77
use crate::MutationTable;
8-
use crate::NodeIterator;
98
use crate::NodeTable;
109
use crate::PopulationTable;
1110
use crate::SimplificationOptions;
@@ -30,7 +29,11 @@ pub struct Tree {
3029
flags: TreeFlags,
3130
}
3231

33-
pub type BoxedNodeIterator = Box<dyn NodeIterator>;
32+
// Trait defining iteration over nodes.
33+
trait NodeIterator {
34+
fn next_node(&mut self);
35+
fn current_node(&mut self) -> Option<tsk_id_t>;
36+
}
3437

3538
drop_for_tskit_type!(Tree, tsk_tree_free);
3639
tskit_type_access!(Tree, ll_bindings::tsk_tree_t);
@@ -203,26 +206,27 @@ impl Tree {
203206
rv
204207
}
205208

206-
/// Return a [`NodeIterator`] from the node `u` to the root of the tree.
209+
/// Return an [`Iterator`] from the node `u` to the root of the tree.
207210
///
208211
/// # Errors
209212
///
210213
/// [`TskitError::IndexError`] if `u` is out of range.
211-
pub fn path_to_root(&self, u: tsk_id_t) -> Result<BoxedNodeIterator, TskitError> {
212-
let iter = PathToRootIterator::new(self, u)?;
213-
Ok(Box::new(iter))
214+
pub fn path_to_root(
215+
&self,
216+
u: tsk_id_t,
217+
) -> Result<impl Iterator<Item = tsk_id_t> + '_, TskitError> {
218+
PathToRootIterator::new(self, u)
214219
}
215220

216-
/// Return a [`NodeIterator`] over the children of node `u`.
221+
/// Return an [`Iterator`] over the children of node `u`.
217222
///
218223
/// # Errors
219224
///
220225
/// [`TskitError::IndexError`] if `u` is out of range.
221-
pub fn children(&self, u: tsk_id_t) -> Result<BoxedNodeIterator, TskitError> {
222-
let iter = ChildIterator::new(self, u)?;
223-
Ok(Box::new(iter))
226+
pub fn children(&self, u: tsk_id_t) -> Result<impl Iterator<Item = tsk_id_t> + '_, TskitError> {
227+
ChildIterator::new(&self, u)
224228
}
225-
/// Return a [`NodeIterator`] over the sample nodes descending from node `u`.
229+
/// Return an [`Iterator`] over the sample nodes descending from node `u`.
226230
///
227231
/// # Note
228232
///
@@ -234,19 +238,18 @@ impl Tree {
234238
///
235239
/// [`TskitError::NotTrackingSamples`] if [`TreeFlags::SAMPLE_LISTS`] was not used
236240
/// to initialize `self`.
237-
pub fn samples(&self, u: tsk_id_t) -> Result<BoxedNodeIterator, TskitError> {
238-
let iter = SamplesIterator::new(self, u)?;
239-
Ok(Box::new(iter))
241+
pub fn samples(&self, u: tsk_id_t) -> Result<impl Iterator<Item = tsk_id_t> + '_, TskitError> {
242+
SamplesIterator::new(self, u)
240243
}
241244

242-
/// Return a [`NodeIterator`] over the roots of the tree.
245+
/// Return an [`Iterator`] over the roots of the tree.
243246
///
244247
/// # Note
245248
///
246249
/// For a tree with multiple roots, the iteration starts
247250
/// at the left root.
248-
pub fn roots(&self) -> BoxedNodeIterator {
249-
Box::new(RootIterator::new(self))
251+
pub fn roots(&self) -> impl Iterator<Item = tsk_id_t> + '_ {
252+
RootIterator::new(self)
250253
}
251254

252255
/// Return all roots as a vector.
@@ -260,15 +263,15 @@ impl Tree {
260263
v
261264
}
262265

263-
/// Return a [`NodeIterator`] over all nodes in the tree.
266+
/// Return an [`Iterator`] over all nodes in the tree.
264267
///
265268
/// # Parameters
266269
///
267270
/// * `order`: A value from [`NodeTraversalOrder`] specifying the
268271
/// iteration order.
269-
pub fn traverse_nodes(&self, order: NodeTraversalOrder) -> BoxedNodeIterator {
272+
pub fn traverse_nodes(&self, order: NodeTraversalOrder) -> impl Iterator<Item = tsk_id_t> + '_ {
270273
match order {
271-
NodeTraversalOrder::Preorder => Box::new(PreorderNodeIterator::new(&self)),
274+
NodeTraversalOrder::Preorder => PreorderNodeIterator::new(&self),
272275
}
273276
}
274277

@@ -396,21 +399,19 @@ pub enum NodeTraversalOrder {
396399
Preorder,
397400
}
398401

399-
struct PreorderNodeIterator {
402+
struct PreorderNodeIterator<'a> {
400403
root_stack: Vec<i32>,
401404
node_stack: Vec<i32>,
402-
left_child: crate::ffi::TskIdArray,
403-
right_sib: crate::ffi::TskIdArray,
405+
tree: &'a Tree,
404406
current_node_: Option<tsk_id_t>,
405407
}
406408

407-
impl PreorderNodeIterator {
408-
fn new(tree: &Tree) -> Self {
409+
impl<'a> PreorderNodeIterator<'a> {
410+
fn new(tree: &'a Tree) -> Self {
409411
let mut rv = PreorderNodeIterator {
410412
root_stack: tree.roots_to_vec(),
411413
node_stack: vec![],
412-
left_child: tree.left_child_array(),
413-
right_sib: tree.right_sib_array(),
414+
tree,
414415
current_node_: None,
415416
};
416417
rv.root_stack.reverse();
@@ -421,15 +422,15 @@ impl PreorderNodeIterator {
421422
}
422423
}
423424

424-
impl NodeIterator for PreorderNodeIterator {
425+
impl NodeIterator for PreorderNodeIterator<'_> {
425426
fn next_node(&mut self) {
426427
self.current_node_ = self.node_stack.pop();
427428
match self.current_node_ {
428429
Some(u) => {
429-
let mut c = self.left_child[u];
430+
let mut c = self.tree.left_child(u).unwrap();
430431
while c != TSK_NULL {
431432
self.node_stack.push(c);
432-
c = self.right_sib[c];
433+
c = self.tree.right_sib(c).unwrap();
433434
}
434435
}
435436
None => {
@@ -445,30 +446,32 @@ impl NodeIterator for PreorderNodeIterator {
445446
}
446447
}
447448

448-
struct RootIterator {
449+
iterator_for_nodeiterator!(PreorderNodeIterator<'_>);
450+
451+
struct RootIterator<'a> {
449452
current_root: Option<tsk_id_t>,
450453
next_root: tsk_id_t,
451-
right_sib: crate::ffi::TskIdArray,
454+
tree: &'a Tree,
452455
}
453456

454-
impl RootIterator {
455-
fn new(tree: &Tree) -> Self {
457+
impl<'a> RootIterator<'a> {
458+
fn new(tree: &'a Tree) -> Self {
456459
RootIterator {
457460
current_root: None,
458461
next_root: tree.inner.left_root,
459-
right_sib: tree.right_sib_array(),
462+
tree,
460463
}
461464
}
462465
}
463466

464-
impl NodeIterator for RootIterator {
467+
impl NodeIterator for RootIterator<'_> {
465468
fn next_node(&mut self) {
466469
self.current_root = match self.next_root {
467470
TSK_NULL => None,
468471
r => {
469472
assert!(r >= 0);
470473
let cr = Some(r);
471-
self.next_root = self.right_sib[r];
474+
self.next_root = self.tree.right_sib(r).unwrap();
472475
cr
473476
}
474477
};
@@ -479,32 +482,34 @@ impl NodeIterator for RootIterator {
479482
}
480483
}
481484

482-
struct ChildIterator {
485+
iterator_for_nodeiterator!(RootIterator<'_>);
486+
487+
struct ChildIterator<'a> {
483488
current_child: Option<tsk_id_t>,
484489
next_child: tsk_id_t,
485-
right_sib: crate::ffi::TskIdArray,
490+
tree: &'a Tree,
486491
}
487492

488-
impl ChildIterator {
489-
fn new(tree: &Tree, u: tsk_id_t) -> Result<Self, TskitError> {
493+
impl<'a> ChildIterator<'a> {
494+
fn new(tree: &'a Tree, u: tsk_id_t) -> Result<Self, TskitError> {
490495
let c = tree.left_child(u)?;
491496

492497
Ok(ChildIterator {
493498
current_child: None,
494499
next_child: c,
495-
right_sib: tree.right_sib_array(),
500+
tree,
496501
})
497502
}
498503
}
499504

500-
impl NodeIterator for ChildIterator {
505+
impl NodeIterator for ChildIterator<'_> {
501506
fn next_node(&mut self) {
502507
self.current_child = match self.next_child {
503508
TSK_NULL => None,
504509
r => {
505510
assert!(r >= 0);
506511
let cr = Some(r);
507-
self.next_child = self.right_sib[r];
512+
self.next_child = self.tree.right_sib(r).unwrap();
508513
cr
509514
}
510515
};
@@ -515,33 +520,35 @@ impl NodeIterator for ChildIterator {
515520
}
516521
}
517522

518-
struct PathToRootIterator {
523+
iterator_for_nodeiterator!(ChildIterator<'_>);
524+
525+
struct PathToRootIterator<'a> {
519526
current_node: Option<tsk_id_t>,
520527
next_node: tsk_id_t,
521-
parent: crate::ffi::TskIdArray,
528+
tree: &'a Tree,
522529
}
523530

524-
impl PathToRootIterator {
525-
fn new(tree: &Tree, u: tsk_id_t) -> Result<Self, TskitError> {
531+
impl<'a> PathToRootIterator<'a> {
532+
fn new(tree: &'a Tree, u: tsk_id_t) -> Result<Self, TskitError> {
526533
match u >= tree.num_nodes as tsk_id_t {
527534
true => Err(TskitError::IndexError),
528535
false => Ok(PathToRootIterator {
529536
current_node: None,
530537
next_node: u,
531-
parent: tree.parent_array(),
538+
tree,
532539
}),
533540
}
534541
}
535542
}
536543

537-
impl NodeIterator for PathToRootIterator {
544+
impl NodeIterator for PathToRootIterator<'_> {
538545
fn next_node(&mut self) {
539546
self.current_node = match self.next_node {
540547
TSK_NULL => None,
541548
r => {
542549
assert!(r >= 0);
543550
let cr = Some(r);
544-
self.next_node = self.parent[r];
551+
self.next_node = self.tree.parent(r).unwrap();
545552
cr
546553
}
547554
};
@@ -552,41 +559,47 @@ impl NodeIterator for PathToRootIterator {
552559
}
553560
}
554561

555-
struct SamplesIterator {
562+
iterator_for_nodeiterator!(PathToRootIterator<'_>);
563+
564+
struct SamplesIterator<'a> {
556565
current_node: Option<tsk_id_t>,
557566
next_sample_index: tsk_id_t,
558567
last_sample_index: tsk_id_t,
559-
next_sample: crate::ffi::TskIdArray,
560-
samples: crate::ffi::TskIdArray,
568+
tree: &'a Tree,
569+
//next_sample: crate::ffi::TskIdArray,
570+
//samples: crate::ffi::TskIdArray,
561571
}
562572

563-
impl SamplesIterator {
564-
fn new(tree: &Tree, u: tsk_id_t) -> Result<Self, TskitError> {
573+
impl<'a> SamplesIterator<'a> {
574+
fn new(tree: &'a Tree, u: tsk_id_t) -> Result<Self, TskitError> {
565575
let rv = SamplesIterator {
566576
current_node: None,
567577
next_sample_index: tree.left_sample(u)?,
568578
last_sample_index: tree.right_sample(u)?,
569-
next_sample: tree.next_sample_array()?,
570-
samples: tree.samples_array()?,
579+
tree,
571580
};
572581

573582
Ok(rv)
574583
}
575584
}
576585

577-
impl NodeIterator for SamplesIterator {
586+
impl NodeIterator for SamplesIterator<'_> {
578587
fn next_node(&mut self) {
579588
self.current_node = match self.next_sample_index {
580589
TSK_NULL => None,
581590
r => {
582591
if r == self.last_sample_index {
583-
let cr = Some(self.samples[r]);
592+
//let cr = Some(self.tree.samples(r).unwrap());
593+
let cr = Some(unsafe { *(*self.tree.as_ptr()).samples.offset(r as isize) });
584594
self.next_sample_index = TSK_NULL;
585595
cr
586596
} else {
587597
assert!(r >= 0);
588-
let cr = Some(self.samples[r]);
589-
self.next_sample_index = self.next_sample[r];
598+
//let cr = Some(self.tree.samples(r).unwrap());
599+
let cr = Some(unsafe { *(*self.tree.as_ptr()).samples.offset(r as isize) });
600+
//self.next_sample_index = self.next_sample[r];
601+
self.next_sample_index =
602+
unsafe { *(*self.tree.as_ptr()).next_sample.offset(r as isize) };
590603
cr
591604
}
592605
}
@@ -598,6 +611,8 @@ impl NodeIterator for SamplesIterator {
598611
}
599612
}
600613

614+
iterator_for_nodeiterator!(SamplesIterator<'_>);
615+
601616
/// A tree sequence.
602617
///
603618
/// This is a thin wrapper around the C type `tsk_treeseq_t`.

0 commit comments

Comments
 (0)