summaryrefslogtreecommitdiff
path: root/src/choices.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/choices.c')
-rw-r--r--src/choices.c46
1 files changed, 39 insertions, 7 deletions
diff --git a/src/choices.c b/src/choices.c
index 619e339..2c789b6 100644
--- a/src/choices.c
+++ b/src/choices.c
@@ -138,9 +138,13 @@ size_t choices_available(choices_t *c) {
return c->available;
}
+#define BATCH_SIZE 512
+
struct search_job {
+ pthread_mutex_t lock;
choices_t *choices;
const char *search;
+ size_t processed;
};
struct worker {
@@ -151,19 +155,41 @@ struct worker {
size_t available;
};
+static void worker_get_next_batch(struct search_job *job, size_t *start, size_t *end) {
+ pthread_mutex_lock(&job->lock);
+
+ *start = job->processed;
+
+ job->processed += BATCH_SIZE;
+ if (job->processed > job->choices->size) {
+ job->processed = job->choices->size;
+ }
+
+ *end = job->processed;
+
+ pthread_mutex_unlock(&job->lock);
+}
+
static void *choices_search_worker(void *data) {
struct worker *w = (struct worker *)data;
struct search_job *job = w->job;
const choices_t *c = job->choices;
- size_t start = (w->worker_num) * c->size / c->worker_count;
- size_t end = (w->worker_num + 1) * c->size / c->worker_count;
+ size_t start, end;
+
+ for(;;) {
+ worker_get_next_batch(job, &start, &end);
+
+ if(start == end) {
+ break;
+ }
- for(size_t i = start; i < end; i++) {
- if (has_match(job->search, c->strings[i])) {
- w->results[w->available].str = c->strings[i];
- w->results[w->available].score = match(job->search, c->strings[i]);
- w->available++;
+ for(size_t i = start; i < end; i++) {
+ if (has_match(job->search, c->strings[i])) {
+ w->results[w->available].str = c->strings[i];
+ w->results[w->available].score = match(job->search, c->strings[i]);
+ w->available++;
+ }
}
}
@@ -176,6 +202,10 @@ void choices_search(choices_t *c, const char *search) {
struct search_job *job = calloc(1, sizeof(struct search_job));
job->search = search;
job->choices = c;
+ if (pthread_mutex_init(&job->lock, NULL) != 0) {
+ fprintf(stderr, "Error: pthread_mutex_init failed\n");
+ abort();
+ }
/* allocate storage for our results */
c->results = malloc(c->size * sizeof(struct scored_result));
@@ -208,6 +238,8 @@ void choices_search(choices_t *c, const char *search) {
free(w->results);
}
+
+ pthread_mutex_destroy(&job->lock);
free(workers);
if(*search) {