3737
3838#include <tskit/genotypes.h>
3939
40- typedef struct {
41- tsk_id_t edge_id ;
42- tsk_id_t child ;
43- double left ;
44- } tsk_haplotype_edge_sort_t ;
45-
46- static int
47- tsk_haplotype_edge_sort_cmp (const void * aa , const void * bb )
48- {
49- const tsk_haplotype_edge_sort_t * a = (const tsk_haplotype_edge_sort_t * ) aa ;
50- const tsk_haplotype_edge_sort_t * b = (const tsk_haplotype_edge_sort_t * ) bb ;
51-
52- if (a -> child == b -> child ) {
53- if (a -> left < b -> left ) {
54- return -1 ;
55- } else if (a -> left > b -> left ) {
56- return 1 ;
57- }
58- if (a -> edge_id < b -> edge_id ) {
59- return -1 ;
60- } else if (a -> edge_id > b -> edge_id ) {
61- return 1 ;
62- }
63- return 0 ;
64- }
65- return a -> child < b -> child ? -1 : 1 ;
66- }
67-
6840static inline uint32_t
6941tsk_haplotype_ctz64 (uint64_t x )
7042{
@@ -121,12 +93,11 @@ static int
12193tsk_haplotype_build_parent_index (tsk_haplotype_t * self )
12294{
12395 int ret = 0 ;
124- tsk_size_t j ;
12596 const tsk_table_collection_t * tables = self -> tree_sequence -> tables ;
12697 const tsk_edge_table_t * edges = & tables -> edges ;
98+ const tsk_id_t * edges_child = edges -> child ;
12799 tsk_size_t num_edges = edges -> num_rows ;
128- tsk_haplotype_edge_sort_t * sorted = NULL ;
129- int32_t * offsets = NULL ;
100+ int32_t * child_counts = NULL ;
130101
131102 if (num_edges == 0 ) {
132103 self -> parent_edge_index = NULL ;
@@ -143,48 +114,60 @@ tsk_haplotype_build_parent_index(tsk_haplotype_t *self)
143114 goto out ;
144115 }
145116
146- sorted = tsk_malloc (num_edges * sizeof (* sorted ));
147117 self -> parent_edge_index = tsk_malloc (num_edges * sizeof (* self -> parent_edge_index ));
148118 self -> parent_index_range
149119 = tsk_malloc (self -> num_nodes * 2 * sizeof (* self -> parent_index_range ));
150- offsets = tsk_calloc (self -> num_nodes + 1 , sizeof (* offsets ));
151- if (sorted == NULL || self -> parent_edge_index == NULL
120+ child_counts = tsk_calloc (self -> num_nodes , sizeof (* child_counts ));
121+ if (self -> parent_edge_index == NULL
152122 || (self -> num_nodes > 0 && self -> parent_index_range == NULL )
153- || offsets == NULL ) {
123+ || child_counts == NULL ) {
154124 ret = tsk_trace_error (TSK_ERR_NO_MEMORY );
155125 goto out ;
156126 }
157127
158- for (j = 0 ; j < num_edges ; j ++ ) {
159- sorted [j ].edge_id = (tsk_id_t ) j ;
160- sorted [j ].child = edges -> child [j ];
161- sorted [j ].left = edges -> left [j ];
162- }
163- qsort (sorted , num_edges , sizeof (* sorted ), tsk_haplotype_edge_sort_cmp );
164-
165- for (j = 0 ; j < num_edges ; j ++ ) {
166- tsk_id_t child = sorted [j ].child ;
128+ for (tsk_size_t j = 0 ; j < num_edges ; j ++ ) {
129+ tsk_id_t child = edges_child [j ];
167130 if (child >= 0 && child < (tsk_id_t ) self -> num_nodes ) {
168- offsets [child + 1 ]++ ;
131+ if (child_counts [child ] == INT32_MAX ) {
132+ ret = tsk_trace_error (TSK_ERR_UNSUPPORTED_OPERATION );
133+ goto out ;
134+ }
135+ child_counts [child ]++ ;
169136 }
170137 }
171- for (j = 0 ; j < (tsk_size_t ) self -> num_nodes ; j ++ ) {
172- offsets [j + 1 ] += offsets [j ];
173- self -> parent_index_range [2 * j ] = offsets [j ];
174- self -> parent_index_range [2 * j + 1 ] = offsets [j + 1 ];
138+
139+ int32_t current_start = 0 ;
140+ for (tsk_size_t u = 0 ; u < (tsk_size_t ) self -> num_nodes ; u ++ ) {
141+ int32_t offset = (int32_t )(u * 2 );
142+ self -> parent_index_range [offset ] = current_start ;
143+ self -> parent_index_range [offset + 1 ] = current_start ;
144+ current_start += child_counts [u ];
175145 }
176146
177- for (j = 0 ; j < num_edges ; j ++ ) {
178- tsk_id_t child = sorted [j ]. child ;
147+ for (tsk_size_t j = 0 ; j < num_edges ; j ++ ) {
148+ tsk_id_t child = edges_child [j ];
179149 if (child >= 0 && child < (tsk_id_t ) self -> num_nodes ) {
180- int32_t pos = offsets [child ]++ ;
181- self -> parent_edge_index [pos ] = sorted [j ].edge_id ;
150+ int32_t end_offset = (int32_t )(child * 2 + 1 );
151+ int32_t pos = self -> parent_index_range [end_offset ];
152+ self -> parent_edge_index [pos ] = (tsk_id_t ) j ;
153+ self -> parent_index_range [end_offset ] = pos + 1 ;
182154 }
183155 }
184156
157+ for (tsk_size_t u = 0 ; u < (tsk_size_t ) self -> num_nodes ; u ++ ) {
158+ int32_t offset = (int32_t )(u * 2 );
159+ int32_t end = self -> parent_index_range [offset + 1 ];
160+ self -> parent_index_range [offset ] = end - child_counts [u ];
161+ }
162+
185163out :
186- tsk_safe_free (sorted );
187- tsk_safe_free (offsets );
164+ if (ret != 0 ) {
165+ tsk_safe_free (self -> parent_edge_index );
166+ self -> parent_edge_index = NULL ;
167+ tsk_safe_free (self -> parent_index_range );
168+ self -> parent_index_range = NULL ;
169+ }
170+ tsk_safe_free (child_counts );
188171 return ret ;
189172}
190173
0 commit comments