Skip to content

Commit cbc6512

Browse files
committed
Remove qsort
1 parent 6f1fea4 commit cbc6512

File tree

1 file changed

+38
-55
lines changed

1 file changed

+38
-55
lines changed

c/tskit/genotypes.c

Lines changed: 38 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -37,34 +37,6 @@
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-
6840
static inline uint32_t
6941
tsk_haplotype_ctz64(uint64_t x)
7042
{
@@ -121,12 +93,11 @@ static int
12193
tsk_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+
185163
out:
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

Comments
 (0)