Browse code

Use AoS instead of SoA; don't use qsort_r

Fixes Bus Error on BSDs due to qsort_r not being the same qsort_r as
linux.

John Hawthorn authored on 17/09/2014 17:43:01 • John Hawthorn committed on 18/09/2014 02:11:14
Showing 2 changed files

... ...
@@ -1,4 +1,3 @@
1
-#define _GNU_SOURCE
2 1
 #include <stdlib.h>
3 2
 #include <stdio.h>
4 3
 
... ...
@@ -7,13 +6,13 @@
7 6
 
8 7
 #define INITIAL_CAPACITY 1
9 8
 
10
-static int cmpchoice(size_t *idx1, size_t *idx2, double *choices_score) {
11
-	double score1 = choices_score[*idx1];
12
-	double score2 = choices_score[*idx2];
9
+static int cmpchoice(const void *_idx1, const void *_idx2) {
10
+	const struct scored_position *a = _idx1;
11
+	const struct scored_position *b = _idx2;
13 12
 
14
-	if(score1 == score2)
13
+	if(a->score == b->score)
15 14
 		return 0;
16
-	else if(score1 < score2)
15
+	else if(a->score < b->score)
17 16
 		return 1;
18 17
 	else
19 18
 		return -1;
... ...
@@ -21,10 +20,9 @@ static int cmpchoice(size_t *idx1, size_t *idx2, double *choices_score) {
21 20
 
22 21
 static void choices_resize(choices_t *c, int new_capacity){
23 22
 	c->strings = realloc(c->strings, new_capacity * sizeof(const char *));
24
-	c->scores  = realloc(c->scores,  new_capacity * sizeof(double));
25
-	c->sorted  = realloc(c->sorted,  new_capacity * sizeof(size_t));
23
+	c->results = realloc(c->results, new_capacity * sizeof(struct scored_position));
26 24
 
27
-	if(!c->strings || !c->scores || !c->sorted){
25
+	if(!c->strings || !c->results){
28 26
 		fprintf(stderr, "Error: Can't allocate memory\n");
29 27
 		abort();
30 28
 	}
... ...
@@ -37,16 +35,14 @@ static void choices_resize(choices_t *c, int new_capacity){
37 35
 
38 36
 void choices_init(choices_t *c){
39 37
 	c->strings = NULL;
40
-	c->scores  = NULL;
41
-	c->sorted  = NULL;
38
+	c->results = NULL;
42 39
 	c->capacity = c->size = 0;
43 40
 	c->selection = c->available = 0;
44 41
 	choices_resize(c, INITIAL_CAPACITY);
45 42
 }
46 43
 void choices_free(choices_t *c){
47 44
 	free(c->strings);
48
-	free(c->scores);
49
-	free(c->sorted);
45
+	free(c->results);
50 46
 };
51 47
 
52 48
 void choices_add(choices_t *c, const char *choice){
... ...
@@ -66,23 +62,24 @@ void choices_search(choices_t *c, const char *search){
66 62
 
67 63
 	for(size_t i = 0; i < c->size; i++){
68 64
 		if(has_match(search, c->strings[i])){
69
-			c->scores[i] = match(search, c->strings[i]);
70
-			c->sorted[c->available++] = i;
65
+			c->results[c->available].position = i;
66
+			c->results[c->available].score = match(search, c->strings[i]);
67
+			c->available++;
71 68
 		}
72 69
 	}
73 70
 
74
-	qsort_r(c->sorted, c->available, sizeof(size_t), (int (*)(const void *, const void *, void *))cmpchoice, c->scores);
71
+	qsort(c->results, c->available, sizeof(struct scored_position), cmpchoice);
75 72
 }
76 73
 
77 74
 const char *choices_get(choices_t *c, size_t n){
78 75
 	if(n < c->available){
79
-		return c->strings[c->sorted[n]];
76
+		return c->strings[c->results[n].position];
80 77
 	}else{
81 78
 		return NULL;
82 79
 	}
83 80
 }
84 81
 double choices_getscore(choices_t *c, size_t n){
85
-	return c->scores[c->sorted[n]];;
82
+	return c->results[n].score;;
86 83
 }
87 84
 
88 85
 void choices_prev(choices_t *c){
... ...
@@ -1,14 +1,18 @@
1 1
 #ifndef CHOICES_H
2 2
 #define CHOICES_H CHOICES_H
3 3
 
4
+struct scored_position {
5
+	size_t position;
6
+	double score;
7
+};
8
+
4 9
 typedef struct {
5 10
 	size_t capacity;
6 11
 	size_t size;
7 12
 
8 13
 	const char **strings;
9
-	double *scores;
14
+	struct scored_position *results;
10 15
 
11
-	size_t *sorted;
12 16
 	size_t available;
13 17
 	size_t selection;
14 18
 } choices_t;