Skip to content

Commit 94e0a04

Browse files
committed
more
1 parent 0550c4d commit 94e0a04

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

src/sys/tree.rs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,26 @@ impl<'treeseq> LLTree<'treeseq> {
123123
unsafe { bindings::tsk_tree_get_num_tracked_samples(self.as_ptr(), u.into(), np) };
124124
handle_tsk_return_value!(code, n.into())
125125
}
126+
127+
pub fn left_sample(&self, u: NodeId) -> Option<NodeId> {
128+
super::tsk_column_access::<NodeId, _, _, _>(
129+
u,
130+
self.as_ref().left_sample,
131+
self.treeseq.num_nodes_raw(),
132+
)
133+
}
134+
135+
pub fn right_sample(&self, u: NodeId) -> Option<NodeId> {
136+
super::tsk_column_access::<NodeId, _, _, _>(
137+
u,
138+
self.as_ref().right_sample,
139+
self.treeseq.num_nodes_raw(),
140+
)
141+
}
142+
143+
pub fn samples(&self, u: NodeId) -> Result<impl Iterator<Item = NodeId> + '_, TskitError> {
144+
Ok(NodeIteratorAdapter(SamplesIterator::new(self, u)?))
145+
}
126146
}
127147

128148
// Trait defining iteration over nodes.
@@ -194,3 +214,63 @@ impl NodeIterator for PreorderNodeIterator<'_> {
194214
self.current_node
195215
}
196216
}
217+
218+
struct SamplesIterator<'a> {
219+
current_node: Option<NodeId>,
220+
next_sample_index: NodeId,
221+
last_sample_index: NodeId,
222+
tree: &'a LLTree<'a>,
223+
}
224+
225+
impl<'a> SamplesIterator<'a> {
226+
fn new(tree: &'a LLTree<'a>, u: NodeId) -> Result<Self, TskitError> {
227+
match tree.flags.contains(TreeFlags::SAMPLE_LISTS) {
228+
false => Err(TskitError::NotTrackingSamples {}),
229+
true => {
230+
let next_sample_index = match tree.left_sample(u) {
231+
Some(x) => x,
232+
None => NodeId::NULL,
233+
};
234+
let last_sample_index = match tree.right_sample(u) {
235+
Some(x) => x,
236+
None => NodeId::NULL,
237+
};
238+
Ok(SamplesIterator {
239+
current_node: None,
240+
next_sample_index,
241+
last_sample_index,
242+
tree,
243+
})
244+
}
245+
}
246+
}
247+
}
248+
249+
impl NodeIterator for SamplesIterator<'_> {
250+
fn next_node(&mut self) {
251+
self.current_node = match self.next_sample_index {
252+
NodeId::NULL => None,
253+
r => {
254+
let raw = crate::sys::bindings::tsk_id_t::from(r);
255+
if r == self.last_sample_index {
256+
let cr =
257+
Some(unsafe { *(*self.tree.as_ptr()).samples.offset(raw as isize) }.into());
258+
self.next_sample_index = NodeId::NULL;
259+
cr
260+
} else {
261+
assert!(r >= 0);
262+
let cr =
263+
Some(unsafe { *(*self.tree.as_ptr()).samples.offset(raw as isize) }.into());
264+
//self.next_sample_index = self.next_sample[r];
265+
self.next_sample_index =
266+
unsafe { *(*self.tree.as_ptr()).next_sample.offset(raw as isize) }.into();
267+
cr
268+
}
269+
}
270+
};
271+
}
272+
273+
fn current_node(&mut self) -> Option<NodeId> {
274+
self.current_node
275+
}
276+
}

src/trees/tree.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,13 @@ impl<'treeseq> Tree<'treeseq> {
128128
) -> Result<SizeType, TskitError> {
129129
self.inner.num_tracked_samples(u.into())
130130
}
131+
132+
pub fn samples<N: Into<NodeId> + Copy>(
133+
&self,
134+
u: N,
135+
) -> Result<impl Iterator<Item = NodeId> + '_, TskitError> {
136+
self.inner.samples(u.into())
137+
}
131138
}
132139

133140
impl<'ts> streaming_iterator::StreamingIterator for Tree<'ts> {

0 commit comments

Comments
 (0)