@@ -4567,6 +4567,136 @@ tsk_tree_position_step(tsk_tree_position_t *self, int direction)
45674567 return ret ;
45684568}
45694569
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+
45704700/* ======================================================== *
45714701 * Tree
45724702 * ======================================================== */
@@ -5606,20 +5736,48 @@ static int
56065736tsk_tree_seek_from_null (tsk_tree_t * self , double x , tsk_flags_t TSK_UNUSED (options ))
56075737{
56085738 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 ;
56095748
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 -- ;
56155752 }
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 ) {
56195770 goto out ;
56205771 }
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+ }
56215780 }
5622- ret = 0 ;
56235781out :
56245782 return ret ;
56255783}
0 commit comments