64 lines
1.6 KiB
C
64 lines
1.6 KiB
C
#include "sequences.h"
|
|
|
|
#include <assert.h>
|
|
#include <exceptions.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <utilities.h>
|
|
#include <pthread.h>
|
|
|
|
typedef struct SEQUENCES_Sequence {
|
|
unsigned int count;
|
|
pthread_key_t tl_next_ndx;
|
|
double seq[];
|
|
} SEQUENCES_Sequence;
|
|
|
|
SEQUENCES_Sequence *SEQUENCES_new(unsigned int count, double numbers[]) {
|
|
assert(count > 0);
|
|
SEQUENCES_Sequence *seq = malloc(sizeof(SEQUENCES_Sequence) + count * sizeof(numbers[0]));
|
|
if (!seq) {
|
|
Throw(E_MALLOC_FAILED);
|
|
}
|
|
seq->count = count;
|
|
memcpy(seq->seq, numbers, count * sizeof(numbers[0]));
|
|
pthread_key_create(&seq->tl_next_ndx, free);
|
|
return seq;
|
|
}
|
|
|
|
void SEQUENCES_delete(SEQUENCES_Sequence *sequence) {
|
|
assert(sequence);
|
|
/* TODO: Is this needed? */
|
|
size_t* ndx = pthread_getspecific(sequence->tl_next_ndx);
|
|
if (ndx) {
|
|
free(ndx);
|
|
}
|
|
pthread_key_delete(sequence->tl_next_ndx);
|
|
free(sequence);
|
|
}
|
|
|
|
double SEQUENCES_next(SEQUENCES_Sequence *sequence) {
|
|
assert(sequence);
|
|
size_t* ndx = pthread_getspecific(sequence->tl_next_ndx);
|
|
if (!ndx) {
|
|
ndx = calloc(1, sizeof(size_t));
|
|
pthread_setspecific(sequence->tl_next_ndx, ndx);
|
|
}
|
|
double val = sequence->seq[*ndx];
|
|
*ndx = (*ndx + 1) % sequence->count;
|
|
return val;
|
|
}
|
|
|
|
SEQUENCES_Sequence *SEQUENCES_copy(SEQUENCES_Sequence *sequence) {
|
|
SEQUENCES_Sequence *seq = SEQUENCES_new(sequence->count, sequence->seq);
|
|
return seq;
|
|
}
|
|
|
|
SEQUENCES_Sequence *SEQUENCES_new_random(unsigned int count) {
|
|
assert(count >= 1);
|
|
double rands[count];
|
|
for (unsigned int ndx = 0; ndx < count; ndx++) {
|
|
rands[ndx] = UTILITIES_random_double(0, 1);
|
|
}
|
|
return SEQUENCES_new(count, rands);
|
|
}
|