@@ -6532,6 +6532,90 @@ tsk_tree_seek_from_null(tsk_tree_t *self, double x, tsk_flags_t TSK_UNUSED(optio
6532
6532
return ret ;
6533
6533
}
6534
6534
6535
+ static int TSK_WARN_UNUSED
6536
+ tsk_tree_seek_forward (tsk_tree_t * self , tsk_id_t index )
6537
+ {
6538
+ int ret = 0 ;
6539
+ tsk_table_collection_t * tables = self -> tree_sequence -> tables ;
6540
+ const tsk_id_t * restrict edge_parent = tables -> edges .parent ;
6541
+ const tsk_id_t * restrict edge_child = tables -> edges .child ;
6542
+ const double * restrict edge_left = tables -> edges .left ;
6543
+ const double * restrict edge_right = tables -> edges .right ;
6544
+ double interval_left , e_left ;
6545
+ const double old_right = self -> interval .right ;
6546
+ tsk_id_t j , e ;
6547
+ tsk_tree_position_t tree_pos ;
6548
+
6549
+ ret = tsk_tree_position_seek_forward (& self -> tree_pos , index );
6550
+ if (ret != 0 ) {
6551
+ goto out ;
6552
+ }
6553
+ tree_pos = self -> tree_pos ;
6554
+ interval_left = tree_pos .interval .left ;
6555
+
6556
+ for (j = tree_pos .out .start ; j != tree_pos .out .stop ; j ++ ) {
6557
+ e = tree_pos .out .order [j ];
6558
+ e_left = edge_left [e ];
6559
+ if (e_left <= old_right ) {
6560
+ tsk_bug_assert (edge_parent [e ] != TSK_NULL );
6561
+ tsk_tree_remove_edge (self , edge_parent [e ], edge_child [e ]);
6562
+ }
6563
+ tsk_bug_assert (e_left < interval_left );
6564
+ }
6565
+
6566
+ for (j = tree_pos .in .start ; j != tree_pos .in .stop ; j ++ ) {
6567
+ e = tree_pos .in .order [j ];
6568
+ if (edge_left [e ] <= interval_left && interval_left < edge_right [e ]) {
6569
+ tsk_tree_insert_edge (self , edge_parent [e ], edge_child [e ], e );
6570
+ }
6571
+ }
6572
+ tsk_tree_update_index_and_interval (self );
6573
+ out :
6574
+ return ret ;
6575
+ }
6576
+
6577
+ static int TSK_WARN_UNUSED
6578
+ tsk_tree_seek_backward (tsk_tree_t * self , tsk_id_t index )
6579
+ {
6580
+ int ret = 0 ;
6581
+ tsk_table_collection_t * tables = self -> tree_sequence -> tables ;
6582
+ const tsk_id_t * restrict edge_parent = tables -> edges .parent ;
6583
+ const tsk_id_t * restrict edge_child = tables -> edges .child ;
6584
+ const double * restrict edge_left = tables -> edges .left ;
6585
+ const double * restrict edge_right = tables -> edges .right ;
6586
+ double interval_right , e_right ;
6587
+ const double old_right = self -> interval .right ;
6588
+ tsk_id_t j , e ;
6589
+ tsk_tree_position_t tree_pos ;
6590
+
6591
+ ret = tsk_tree_position_seek_backward (& self -> tree_pos , index );
6592
+ if (ret != 0 ) {
6593
+ goto out ;
6594
+ }
6595
+ tree_pos = self -> tree_pos ;
6596
+ interval_right = tree_pos .interval .right ;
6597
+
6598
+ for (j = tree_pos .out .start ; j != tree_pos .out .stop ; j -- ) {
6599
+ e = tree_pos .out .order [j ];
6600
+ e_right = edge_right [e ];
6601
+ if (e_right >= old_right ) {
6602
+ tsk_bug_assert (edge_parent [e ] != TSK_NULL );
6603
+ tsk_tree_remove_edge (self , edge_parent [e ], edge_child [e ]);
6604
+ }
6605
+ tsk_bug_assert (e_right > interval_right );
6606
+ }
6607
+
6608
+ for (j = tree_pos .in .start ; j != tree_pos .in .stop ; j -- ) {
6609
+ e = tree_pos .in .order [j ];
6610
+ if (edge_right [e ] >= interval_right && interval_right > edge_left [e ]) {
6611
+ tsk_tree_insert_edge (self , edge_parent [e ], edge_child [e ], e );
6612
+ }
6613
+ }
6614
+ tsk_tree_update_index_and_interval (self );
6615
+ out :
6616
+ return ret ;
6617
+ }
6618
+
6535
6619
int TSK_WARN_UNUSED
6536
6620
tsk_tree_seek_index (tsk_tree_t * self , tsk_id_t tree , tsk_flags_t options )
6537
6621
{
@@ -6551,40 +6635,23 @@ tsk_tree_seek_index(tsk_tree_t *self, tsk_id_t tree, tsk_flags_t options)
6551
6635
static int TSK_WARN_UNUSED
6552
6636
tsk_tree_seek_linear (tsk_tree_t * self , double x , tsk_flags_t TSK_UNUSED (options ))
6553
6637
{
6554
- const double L = tsk_treeseq_get_sequence_length (self -> tree_sequence );
6555
6638
const double t_l = self -> interval .left ;
6556
- const double t_r = self -> interval .right ;
6557
6639
int ret = 0 ;
6558
- double distance_left , distance_right ;
6640
+ tsk_id_t index ;
6641
+ const tsk_size_t num_trees = self -> tree_sequence -> num_trees ;
6642
+ const double * restrict breakpoints = self -> tree_sequence -> breakpoints ;
6643
+
6644
+ index = (tsk_id_t ) tsk_search_sorted (breakpoints , num_trees + 1 , x );
6645
+ if (breakpoints [index ] > x ) {
6646
+ index -- ;
6647
+ }
6559
6648
6560
6649
if (x < t_l ) {
6561
- /* |-----|-----|========|---------| */
6562
- /* 0 x t_l t_r L */
6563
- distance_left = t_l - x ;
6564
- distance_right = L - t_r + x ;
6565
- } else {
6566
- /* |------|========|------|-------| */
6567
- /* 0 t_l t_r x L */
6568
- distance_right = x - t_r ;
6569
- distance_left = t_l + L - x ;
6570
- }
6571
- if (distance_right <= distance_left ) {
6572
- while (!tsk_tree_position_in_interval (self , x )) {
6573
- ret = tsk_tree_next (self );
6574
- if (ret < 0 ) {
6575
- goto out ;
6576
- }
6577
- }
6650
+ ret = tsk_tree_seek_backward (self , index );
6578
6651
} else {
6579
- while (!tsk_tree_position_in_interval (self , x )) {
6580
- ret = tsk_tree_prev (self );
6581
- if (ret < 0 ) {
6582
- goto out ;
6583
- }
6584
- }
6652
+ ret = tsk_tree_seek_forward (self , index );
6585
6653
}
6586
- ret = 0 ;
6587
- out :
6654
+ tsk_bug_assert (tsk_tree_position_in_interval (self , x ));
6588
6655
return ret ;
6589
6656
}
6590
6657
0 commit comments