@@ -5777,6 +5777,90 @@ tsk_tree_seek_from_null(tsk_tree_t *self, double x, tsk_flags_t TSK_UNUSED(optio
5777
5777
return ret ;
5778
5778
}
5779
5779
5780
+ static int TSK_WARN_UNUSED
5781
+ tsk_tree_seek_forward (tsk_tree_t * self , tsk_id_t index )
5782
+ {
5783
+ int ret = 0 ;
5784
+ tsk_table_collection_t * tables = self -> tree_sequence -> tables ;
5785
+ const tsk_id_t * restrict edge_parent = tables -> edges .parent ;
5786
+ const tsk_id_t * restrict edge_child = tables -> edges .child ;
5787
+ const double * restrict edge_left = tables -> edges .left ;
5788
+ const double * restrict edge_right = tables -> edges .right ;
5789
+ double interval_left , e_left ;
5790
+ const double old_right = self -> interval .right ;
5791
+ tsk_id_t j , e ;
5792
+ tsk_tree_position_t tree_pos ;
5793
+
5794
+ ret = tsk_tree_position_seek_forward (& self -> tree_pos , index );
5795
+ if (ret != 0 ) {
5796
+ goto out ;
5797
+ }
5798
+ tree_pos = self -> tree_pos ;
5799
+ interval_left = tree_pos .interval .left ;
5800
+
5801
+ for (j = tree_pos .out .start ; j != tree_pos .out .stop ; j ++ ) {
5802
+ e = tree_pos .out .order [j ];
5803
+ e_left = edge_left [e ];
5804
+ if (e_left <= old_right ) {
5805
+ tsk_bug_assert (edge_parent [e ] != TSK_NULL );
5806
+ tsk_tree_remove_edge (self , edge_parent [e ], edge_child [e ]);
5807
+ }
5808
+ tsk_bug_assert (e_left < interval_left );
5809
+ }
5810
+
5811
+ for (j = tree_pos .in .start ; j != tree_pos .in .stop ; j ++ ) {
5812
+ e = tree_pos .in .order [j ];
5813
+ if (edge_left [e ] <= interval_left && interval_left < edge_right [e ]) {
5814
+ tsk_tree_insert_edge (self , edge_parent [e ], edge_child [e ], e );
5815
+ }
5816
+ }
5817
+ tsk_tree_update_index_and_interval (self );
5818
+ out :
5819
+ return ret ;
5820
+ }
5821
+
5822
+ static int TSK_WARN_UNUSED
5823
+ tsk_tree_seek_backward (tsk_tree_t * self , tsk_id_t index )
5824
+ {
5825
+ int ret = 0 ;
5826
+ tsk_table_collection_t * tables = self -> tree_sequence -> tables ;
5827
+ const tsk_id_t * restrict edge_parent = tables -> edges .parent ;
5828
+ const tsk_id_t * restrict edge_child = tables -> edges .child ;
5829
+ const double * restrict edge_left = tables -> edges .left ;
5830
+ const double * restrict edge_right = tables -> edges .right ;
5831
+ double interval_right , e_right ;
5832
+ const double old_right = self -> interval .right ;
5833
+ tsk_id_t j , e ;
5834
+ tsk_tree_position_t tree_pos ;
5835
+
5836
+ ret = tsk_tree_position_seek_backward (& self -> tree_pos , index );
5837
+ if (ret != 0 ) {
5838
+ goto out ;
5839
+ }
5840
+ tree_pos = self -> tree_pos ;
5841
+ interval_right = tree_pos .interval .right ;
5842
+
5843
+ for (j = tree_pos .out .start ; j != tree_pos .out .stop ; j -- ) {
5844
+ e = tree_pos .out .order [j ];
5845
+ e_right = edge_right [e ];
5846
+ if (e_right >= old_right ) {
5847
+ tsk_bug_assert (edge_parent [e ] != TSK_NULL );
5848
+ tsk_tree_remove_edge (self , edge_parent [e ], edge_child [e ]);
5849
+ }
5850
+ tsk_bug_assert (e_right > interval_right );
5851
+ }
5852
+
5853
+ for (j = tree_pos .in .start ; j != tree_pos .in .stop ; j -- ) {
5854
+ e = tree_pos .in .order [j ];
5855
+ if (edge_right [e ] >= interval_right && interval_right > edge_left [e ]) {
5856
+ tsk_tree_insert_edge (self , edge_parent [e ], edge_child [e ], e );
5857
+ }
5858
+ }
5859
+ tsk_tree_update_index_and_interval (self );
5860
+ out :
5861
+ return ret ;
5862
+ }
5863
+
5780
5864
int TSK_WARN_UNUSED
5781
5865
tsk_tree_seek_index (tsk_tree_t * self , tsk_id_t tree , tsk_flags_t options )
5782
5866
{
@@ -5796,40 +5880,23 @@ tsk_tree_seek_index(tsk_tree_t *self, tsk_id_t tree, tsk_flags_t options)
5796
5880
static int TSK_WARN_UNUSED
5797
5881
tsk_tree_seek_linear (tsk_tree_t * self , double x , tsk_flags_t TSK_UNUSED (options ))
5798
5882
{
5799
- const double L = tsk_treeseq_get_sequence_length (self -> tree_sequence );
5800
5883
const double t_l = self -> interval .left ;
5801
- const double t_r = self -> interval .right ;
5802
5884
int ret = 0 ;
5803
- double distance_left , distance_right ;
5885
+ tsk_id_t index ;
5886
+ const tsk_size_t num_trees = self -> tree_sequence -> num_trees ;
5887
+ const double * restrict breakpoints = self -> tree_sequence -> breakpoints ;
5888
+
5889
+ index = (tsk_id_t ) tsk_search_sorted (breakpoints , num_trees + 1 , x );
5890
+ if (breakpoints [index ] > x ) {
5891
+ index -- ;
5892
+ }
5804
5893
5805
5894
if (x < t_l ) {
5806
- /* |-----|-----|========|---------| */
5807
- /* 0 x t_l t_r L */
5808
- distance_left = t_l - x ;
5809
- distance_right = L - t_r + x ;
5895
+ ret = tsk_tree_seek_backward (self , index );
5810
5896
} else {
5811
- /* |------|========|------|-------| */
5812
- /* 0 t_l t_r x L */
5813
- distance_right = x - t_r ;
5814
- distance_left = t_l + L - x ;
5815
- }
5816
- if (distance_right <= distance_left ) {
5817
- while (!tsk_tree_position_in_interval (self , x )) {
5818
- ret = tsk_tree_next (self );
5819
- if (ret < 0 ) {
5820
- goto out ;
5821
- }
5822
- }
5823
- } else {
5824
- while (!tsk_tree_position_in_interval (self , x )) {
5825
- ret = tsk_tree_prev (self );
5826
- if (ret < 0 ) {
5827
- goto out ;
5828
- }
5829
- }
5897
+ ret = tsk_tree_seek_forward (self , index );
5830
5898
}
5831
- ret = 0 ;
5832
- out :
5899
+ tsk_bug_assert (tsk_tree_position_in_interval (self , x ));
5833
5900
return ret ;
5834
5901
}
5835
5902
0 commit comments