@@ -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+ }
0 commit comments