@@ -4567,6 +4567,136 @@ tsk_tree_position_step(tsk_tree_position_t *self, int direction)
4567
4567
return ret ;
4568
4568
}
4569
4569
4570
+ int TSK_WARN_UNUSED
4571
+ tsk_tree_position_seek_forward (tsk_tree_position_t * self , tsk_id_t index )
4572
+ {
4573
+ int ret = 0 ;
4574
+ const tsk_table_collection_t * tables = self -> tree_sequence -> tables ;
4575
+ const tsk_id_t M = (tsk_id_t ) tables -> edges .num_rows ;
4576
+ const tsk_id_t num_trees = (tsk_id_t ) self -> tree_sequence -> num_trees ;
4577
+ const double * restrict left_coords = tables -> edges .left ;
4578
+ const tsk_id_t * restrict left_order = tables -> indexes .edge_insertion_order ;
4579
+ const double * restrict right_coords = tables -> edges .right ;
4580
+ const tsk_id_t * restrict right_order = tables -> indexes .edge_removal_order ;
4581
+ const double * restrict breakpoints = self -> tree_sequence -> breakpoints ;
4582
+ tsk_id_t j , left_current_index , right_current_index ;
4583
+ double left ;
4584
+
4585
+ tsk_bug_assert (index >= self -> index && index < num_trees );
4586
+
4587
+ if (self -> index == -1 ) {
4588
+ self -> interval .right = 0 ;
4589
+ self -> in .stop = 0 ;
4590
+ self -> out .stop = 0 ;
4591
+ self -> direction = TSK_DIR_FORWARD ;
4592
+ }
4593
+
4594
+ if (self -> direction == TSK_DIR_FORWARD ) {
4595
+ left_current_index = self -> in .stop ;
4596
+ right_current_index = self -> out .stop ;
4597
+ } else {
4598
+ left_current_index = self -> out .stop + 1 ;
4599
+ right_current_index = self -> in .stop + 1 ;
4600
+ }
4601
+
4602
+ self -> direction = TSK_DIR_FORWARD ;
4603
+ left = breakpoints [index ];
4604
+
4605
+ j = right_current_index ;
4606
+ self -> out .start = j ;
4607
+ while (j < M && right_coords [right_order [j ]] <= left ) {
4608
+ j ++ ;
4609
+ }
4610
+ self -> out .stop = j ;
4611
+
4612
+ if (self -> index == -1 ) {
4613
+ self -> out .start = self -> out .stop ;
4614
+ }
4615
+
4616
+ j = left_current_index ;
4617
+ while (j < M && right_coords [left_order [j ]] <= left ) {
4618
+ j ++ ;
4619
+ }
4620
+ self -> in .start = j ;
4621
+ while (j < M && left_coords [left_order [j ]] <= left ) {
4622
+ j ++ ;
4623
+ }
4624
+ self -> in .stop = j ;
4625
+
4626
+ self -> interval .left = left ;
4627
+ self -> interval .right = breakpoints [index + 1 ];
4628
+ self -> out .order = right_order ;
4629
+ self -> in .order = left_order ;
4630
+ self -> index = index ;
4631
+ return ret ;
4632
+ }
4633
+
4634
+ int TSK_WARN_UNUSED
4635
+ tsk_tree_position_seek_backward (tsk_tree_position_t * self , tsk_id_t index )
4636
+ {
4637
+ int ret = 0 ;
4638
+ const tsk_table_collection_t * tables = self -> tree_sequence -> tables ;
4639
+ const tsk_id_t M = (tsk_id_t ) tables -> edges .num_rows ;
4640
+ const double sequence_length = tables -> sequence_length ;
4641
+ const tsk_id_t num_trees = (tsk_id_t ) self -> tree_sequence -> num_trees ;
4642
+ const double * restrict left_coords = tables -> edges .left ;
4643
+ const tsk_id_t * restrict left_order = tables -> indexes .edge_insertion_order ;
4644
+ const double * restrict right_coords = tables -> edges .right ;
4645
+ const tsk_id_t * restrict right_order = tables -> indexes .edge_removal_order ;
4646
+ const double * restrict breakpoints = self -> tree_sequence -> breakpoints ;
4647
+ tsk_id_t j , left_current_index , right_current_index ;
4648
+ double right ;
4649
+
4650
+ if (self -> index == -1 ) {
4651
+ self -> index = num_trees ;
4652
+ self -> interval .left = sequence_length ;
4653
+ self -> in .stop = M - 1 ;
4654
+ self -> out .stop = M - 1 ;
4655
+ self -> direction = TSK_DIR_REVERSE ;
4656
+ }
4657
+ tsk_bug_assert (index <= self -> index );
4658
+
4659
+ if (self -> direction == TSK_DIR_REVERSE ) {
4660
+ left_current_index = self -> out .stop ;
4661
+ right_current_index = self -> in .stop ;
4662
+ } else {
4663
+ left_current_index = self -> in .stop - 1 ;
4664
+ right_current_index = self -> out .stop - 1 ;
4665
+ }
4666
+
4667
+ self -> direction = TSK_DIR_REVERSE ;
4668
+ right = breakpoints [index + 1 ];
4669
+
4670
+ j = left_current_index ;
4671
+ self -> out .start = j ;
4672
+ while (j >= 0 && left_coords [left_order [j ]] >= right ) {
4673
+ j -- ;
4674
+ }
4675
+ self -> out .stop = j ;
4676
+
4677
+ if (self -> index == num_trees ) {
4678
+ self -> out .start = self -> out .stop ;
4679
+ }
4680
+
4681
+ j = right_current_index ;
4682
+ while (j >= 0 && left_coords [right_order [j ]] >= right ) {
4683
+ j -- ;
4684
+ }
4685
+ self -> in .start = j ;
4686
+ while (j >= 0 && right_coords [right_order [j ]] >= right ) {
4687
+ j -- ;
4688
+ }
4689
+ self -> in .stop = j ;
4690
+
4691
+ self -> interval .right = right ;
4692
+ self -> interval .left = breakpoints [index ];
4693
+ self -> out .order = left_order ;
4694
+ self -> in .order = right_order ;
4695
+ self -> index = index ;
4696
+
4697
+ return ret ;
4698
+ }
4699
+
4570
4700
/* ======================================================== *
4571
4701
* Tree
4572
4702
* ======================================================== */
@@ -5606,20 +5736,48 @@ static int
5606
5736
tsk_tree_seek_from_null (tsk_tree_t * self , double x , tsk_flags_t TSK_UNUSED (options ))
5607
5737
{
5608
5738
int ret = 0 ;
5739
+ tsk_table_collection_t * tables = self -> tree_sequence -> tables ;
5740
+ const tsk_id_t * restrict edge_parent = tables -> edges .parent ;
5741
+ const tsk_id_t * restrict edge_child = tables -> edges .child ;
5742
+ const double * restrict edge_left = tables -> edges .left ;
5743
+ const double * restrict edge_right = tables -> edges .right ;
5744
+ const double * restrict breakpoints = self -> tree_sequence -> breakpoints ;
5745
+ const tsk_size_t num_trees = self -> tree_sequence -> num_trees ;
5746
+ const double L = tsk_treeseq_get_sequence_length (self -> tree_sequence );
5747
+ tsk_id_t j , e , index ;
5609
5748
5610
- tsk_bug_assert (self -> index == -1 );
5611
-
5612
- ret = tsk_tree_next (self );
5613
- if (ret < 0 ) {
5614
- goto out ;
5749
+ index = (tsk_id_t ) tsk_search_sorted (breakpoints , num_trees + 1 , x );
5750
+ if (breakpoints [index ] > x ) {
5751
+ index -- ;
5615
5752
}
5616
- while (!tsk_tree_position_in_interval (self , x )) {
5617
- ret = tsk_tree_next (self );
5618
- if (ret < 0 ) {
5753
+
5754
+ if (x <= L / 2.0 ) {
5755
+ ret = tsk_tree_position_seek_forward (& self -> tree_pos , index );
5756
+ if (ret != 0 ) {
5757
+ goto out ;
5758
+ }
5759
+ tsk_tree_update_index_and_interval (self );
5760
+ for (j = self -> tree_pos .in .start ; j != self -> tree_pos .in .stop ; j ++ ) {
5761
+ e = self -> tree_pos .in .order [j ];
5762
+ if (edge_left [e ] <= self -> interval .left
5763
+ && self -> interval .left < edge_right [e ]) {
5764
+ tsk_tree_insert_edge (self , edge_parent [e ], edge_child [e ], e );
5765
+ }
5766
+ }
5767
+ } else {
5768
+ ret = tsk_tree_position_seek_backward (& self -> tree_pos , index );
5769
+ if (ret != 0 ) {
5619
5770
goto out ;
5620
5771
}
5772
+ tsk_tree_update_index_and_interval (self );
5773
+ for (j = self -> tree_pos .in .start ; j != self -> tree_pos .in .stop ; j -- ) {
5774
+ e = self -> tree_pos .in .order [j ];
5775
+ if (edge_right [e ] >= self -> interval .right
5776
+ && self -> interval .right > edge_left [e ]) {
5777
+ tsk_tree_insert_edge (self , edge_parent [e ], edge_child [e ], e );
5778
+ }
5779
+ }
5621
5780
}
5622
- ret = 0 ;
5623
5781
out :
5624
5782
return ret ;
5625
5783
}
0 commit comments