diff --git a/fftma_module/gen/include/chunk_array.h b/fftma_module/gen/include/chunk_array.h index 7ab85e8..630ccb4 100644 --- a/fftma_module/gen/include/chunk_array.h +++ b/fftma_module/gen/include/chunk_array.h @@ -7,15 +7,18 @@ #include #include -#define MAX_CHUNK_SIZE 2048 +typedef struct buffer { + double* data; + size_t init_pos; +}buffer_t; typedef struct chunk_array { char* filename; - size_t init_pos; size_t chunk_size; size_t total_size; FILE* fp; - double* data; + buffer_t* buffer1; + buffer_t* buffer2; }chunk_array_t; chunk_array_t* chunk_array_create(char* filename, size_t total_size); diff --git a/fftma_module/gen/lib_src/chunk_array.c b/fftma_module/gen/lib_src/chunk_array.c index a584a22..13158d4 100644 --- a/fftma_module/gen/lib_src/chunk_array.c +++ b/fftma_module/gen/lib_src/chunk_array.c @@ -1,36 +1,79 @@ #include "chunk_array.h" #include "stdbool.h" +#include "stdlib.h" + +#define MAX_CHUNK_SIZE 2048*2048 + +int get_mod(chunk_array_t* chunk_array,int init_pos) { + int mod; + if (chunk_array->total_size - init_pos > chunk_array->chunk_size ) { + mod = chunk_array->chunk_size; + } else { + mod = chunk_array->total_size - init_pos; + } + return mod; +} + +bool inside_buffer(chunk_array_t* chunk_array,int init_pos, size_t pos) { + if (posinit_pos + chunk_array->chunk_size-1) { + return false; + } + return true; +} void chunk_array_free(chunk_array_t* chunk_array) { fclose(chunk_array->fp); - free(chunk_array->data); + buffer_free(chunk_array->buffer1); + buffer_free(chunk_array->buffer2); free(chunk_array); } void chunk_array_flush(chunk_array_t* chunk_array) { - size_t mod; - if (chunk_array->total_size - chunk_array->init_pos > chunk_array->chunk_size ) { - mod = chunk_array->chunk_size; - } else { - mod = chunk_array->total_size - chunk_array->init_pos; - } - fseek(chunk_array->fp, chunk_array->init_pos * sizeof(double), SEEK_SET); - fwrite(chunk_array->data, sizeof(double), mod, chunk_array->fp); + buffer_flush(chunk_array, chunk_array->buffer1); + buffer_flush(chunk_array, chunk_array->buffer2); +} + +void buffer_flush(chunk_array_t* chunk_array, buffer_t* buffer) { + int mod = get_mod(chunk_array, buffer->init_pos); + fseek(chunk_array->fp, buffer->init_pos * sizeof(double), SEEK_SET); + fwrite(buffer->data, sizeof(double), mod, chunk_array->fp); } -bool chunk_array_update(chunk_array_t* chunk_array, size_t pos) { - chunk_array_flush(chunk_array); + +void buffer_update(chunk_array_t* chunk_array, buffer_t* buffer, size_t pos) { + buffer_flush(chunk_array, buffer); int new_init = pos/chunk_array->chunk_size; - chunk_array->init_pos = new_init * chunk_array->chunk_size; + buffer->init_pos = new_init * chunk_array->chunk_size; - fseek(chunk_array->fp, chunk_array->init_pos * sizeof(double), SEEK_SET); - fread(chunk_array->data, sizeof(double), chunk_array->chunk_size, chunk_array->fp); + fseek(chunk_array->fp, buffer->init_pos * sizeof(double), SEEK_SET); + fread(buffer->data, sizeof(double), chunk_array->chunk_size, chunk_array->fp); +} + +buffer_t* buffer_create() { + buffer_t * buffer = (buffer_t*)malloc(sizeof(buffer_t)); + + if (buffer == NULL) return NULL; + + buffer->data = malloc(MAX_CHUNK_SIZE * sizeof(double)); + + if (buffer->data == NULL) { + free(buffer); + return NULL; + } + + buffer->init_pos = 0; + + return buffer; +} + +void buffer_free(buffer_t* buffer) { + free(buffer->data); + free(buffer); } chunk_array_t* chunk_array_create(char* filename, size_t total_size) { chunk_array_t* chunk_array = (chunk_array_t*)malloc(sizeof(chunk_array_t)); - chunk_array->fp = fopen(filename, "r+"); if (chunk_array == NULL || chunk_array->fp == NULL) { @@ -41,50 +84,78 @@ chunk_array_t* chunk_array_create(char* filename, size_t total_size) { } } - chunk_array->data = malloc(MAX_CHUNK_SIZE * sizeof(double)); + chunk_array->buffer1 = buffer_create(); - if (MAX_CHUNK_SIZE > 0 && chunk_array->data == NULL) { + if (chunk_array->buffer1 == NULL) { + fclose(chunk_array->fp); free(chunk_array); return NULL; } - fread(chunk_array->data, sizeof(double), MAX_CHUNK_SIZE, chunk_array->fp); + chunk_array->buffer2 = buffer_create(); + + if (chunk_array->buffer2 == NULL) { + fclose(chunk_array->fp); + buffer_free(chunk_array->buffer1); + free(chunk_array); + return NULL; + } + fread(chunk_array->buffer1->data, sizeof(double), MAX_CHUNK_SIZE, chunk_array->fp); + chunk_array->buffer1->init_pos = 0; + fread(chunk_array->buffer2->data, sizeof(double), MAX_CHUNK_SIZE, chunk_array->fp); + chunk_array->buffer2->init_pos = MAX_CHUNK_SIZE; + chunk_array->filename = filename; - chunk_array->init_pos = 0; chunk_array->chunk_size = MAX_CHUNK_SIZE; chunk_array->total_size = total_size; return chunk_array; } -bool chunk_array_get(chunk_array_t* chunk_array, size_t pos, double *valor) { +buffer_t* chunk_array_update(chunk_array_t* chunk_array, size_t pos) { + int distance_to_1 = abs(chunk_array->buffer1->init_pos - pos); + int distance_to_2 = abs(chunk_array->buffer2->init_pos - pos); - if (posinit_pos || pos>chunk_array->init_pos + chunk_array->chunk_size-1) { - chunk_array_update(chunk_array, pos); - } - size_t mod; - if (chunk_array->total_size - chunk_array->init_pos > chunk_array->chunk_size ) { - mod = chunk_array->chunk_size; - } else { - mod = chunk_array->total_size - chunk_array->init_pos; + if (distance_to_1 < distance_to_2) { + buffer_update(chunk_array, chunk_array->buffer1, pos); + return chunk_array->buffer1; } - int real_pos = pos%mod; - *valor=chunk_array->data[real_pos]; + buffer_update(chunk_array, chunk_array->buffer2, pos); + return chunk_array->buffer2; +} + +bool chunk_array_get(chunk_array_t* chunk_array, size_t pos, double *valor) { + buffer_t* buffer; + if (inside_buffer(chunk_array, chunk_array->buffer1->init_pos, pos)) { + buffer = chunk_array->buffer1; + } + else if (inside_buffer(chunk_array, chunk_array->buffer2->init_pos, pos)) { + buffer = chunk_array->buffer2; + } + else { + // need to update one buffer + buffer = chunk_array_update(chunk_array, pos); + } + + int real_pos = pos%get_mod(chunk_array, buffer->init_pos); + *valor=buffer->data[real_pos]; return true; } bool chunk_array_save(chunk_array_t* chunk_array, size_t pos, double valor) { - if (posinit_pos || pos>chunk_array->init_pos + chunk_array->chunk_size-1) { - chunk_array_update(chunk_array,pos); - } - size_t mod; - if (chunk_array->total_size - chunk_array->init_pos > chunk_array->chunk_size ) { - mod = chunk_array->chunk_size; - } else { - mod = chunk_array->total_size - chunk_array->init_pos; + buffer_t* buffer; + if (inside_buffer(chunk_array, chunk_array->buffer1->init_pos, pos)) { + buffer = chunk_array->buffer1; } - chunk_array->data[pos%mod]=valor; - + else if (inside_buffer(chunk_array, chunk_array->buffer2->init_pos, pos)) { + buffer = chunk_array->buffer2; + } + else { + // need to update one buffer + buffer = chunk_array_update(chunk_array, pos); + } + int real_pos = pos%get_mod(chunk_array, buffer->init_pos); + buffer->data[real_pos]=valor; return true; } \ No newline at end of file