rsys

Basic data structures and low-level features
git clone git://git.meso-star.fr/rsys.git
Log | Files | Refs | README | LICENSE

commit 6bf6ec08e1e2a8f52bf62478c1af49401f259ae4
parent d8a5a72c8c45adcbe8c9b393133bf1e4ff8db62f
Author: vaplv <vaplv@free.fr>
Date:   Wed, 22 Nov 2017 08:59:20 +0100

Remove the big buffer data structure

Diffstat:
Mcmake/CMakeLists.txt | 3---
Dsrc/big_buffer.c | 36------------------------------------
Dsrc/big_buffer.h | 434-------------------------------------------------------------------------------
3 files changed, 0 insertions(+), 473 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -39,7 +39,6 @@ set(VERSION_PATCH 0) set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) set(RSYS_FILES_SRC - big_buffer.c clock_time.c cstr.c image.c @@ -65,7 +64,6 @@ set(RSYS_FILES_INC io_c99.h) set(RSYS_FILES_INC_API algorithm.h - big_buffer.h binary_heap.h clock_time.h condition.h @@ -169,7 +167,6 @@ if(NOT NO_TEST) new_test(test_algorithm) new_test(test_atomic) - new_test(test_big_buffer rsys) new_test(test_binary_heap rsys) new_test(test_cstr rsys) new_test(test_double2 ${MATH_LIB}) diff --git a/src/big_buffer.c b/src/big_buffer.c @@ -1,36 +0,0 @@ -/* Copyright (C) 2013-2017 Vincent Forest (vaplv@free.fr) - * - * The RSys library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The RSys library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */ - -#define _POSIX_C_SOURCE 200112L /* ftruncate support */ - -#include "big_buffer.h" - -#ifdef COMPILER_CL - #include <io.h> /* _chsize support */ -#else - #include <unistd.h> /* ftruncate support */ -#endif - -res_T -truncate__(FILE* file, const size_t sz) -{ - ASSERT(file); -#ifdef OS_WINDOWS - return _chsize(_fileno(file), (long)sz) == 0 ? RES_OK : RES_IO_ERR; -#else - return ftruncate(fileno(file), (off_t)sz) == 0 ? RES_OK : RES_IO_ERR; -#endif -} - diff --git a/src/big_buffer.h b/src/big_buffer.h @@ -1,434 +0,0 @@ -/* Copyright (C) 2013-2017 Vincent Forest (vaplv@free.fr) - * - * The RSys library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The RSys library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */ - -#if !defined(BIGBUF_NAME) && !defined(BIGBUF_DATA) -#ifndef BIGBUF_H -#define BIGBUF_H - -#include "rsys.h" -#include "math.h" - -#include <stdio.h> -#include <string.h> - -/* Internal enumerate used to define the mode of the buffered data */ -enum bigbuf_mode__ { BIGBUF_READ__, BIGBUF_WRITE__ }; - -enum bigbuf_flag { - BIGBUF_LOAD_STREAM = BIT(1) -}; - -RSYS_API res_T -truncate__ - (FILE* file, - const size_t sz); - -#endif /* BIGBUF_H */ -#else - -/* - * Generate the big buffer data type and functions wrt the following macros: - * - BIGBUF_NAME: prefix of the big buffer functions & type; - * - BIGBUF_DATA: type of the data registered into the big buffer; - * - BIGBUF_ALIGNMENT: optional alignment of the buffer that stores the in - * buffered data of the big buffer. By default use the maximum between the - * default alignment of the BIGBUF_DATA and 16 bytes; - * BIGBUF_DATA is buffered - * - * The name of the generated type is: struct bigbuf_<BIGBUF_NAME> and the - * rule to generate the function name is bigbuf_<BIGBUF_NAME>_<FUNCTION_NAME>. - */ - -#ifndef BIGBUF_NAME - #error "Missing the BIGBUF_NAME macro defining the structure name" -#endif -#ifndef BIGBUF_DATA - #error "Missing the BIGBUF_DATA macro defining the buffer data type" -#endif - -#define BIGBUF__ CONCAT(bigbuf_, BIGBUF_NAME) -#define BIGBUF_FUNC__(Func) CONCAT(CONCAT(CONCAT(bigbuf_, BIGBUF_NAME),_), Func) -#ifndef BIGBUF_ALIGNMENT - #define BIGBUF_ALIGNMENT__ MMAX(ALIGNOF(BIGBUF_DATA), 16) -#else - STATIC_ASSERT(IS_POW2(BIGBUF_ALIGNMENT), - BIGBUF_ALIGNMENT_must_be_a_power_of_2); - #define BIGBUF_ALIGNMENT__ MMAX(ALIGNOF(BIGBUF_DATA), 16) -#endif - -struct BIGBUF__ { - struct { /* Buffered data */ - BIGBUF_DATA* data; - size_t capacity; - size_t size; - } buf; - - enum bigbuf_mode__ mode; /* Mode of the buffered data */ - - FILE* file; /* Stream where buffer data are written */ - size_t buf_index; /* Id of the first big buffer item store into `buf' */ - size_t size; /* Number of items stored into the big buffer */ - long head; /* Position indicator into `file' toward the first data */ - long end; /* Position indicator into `file' behind the last data */ - int temp_file; /* Define if `file' is a temporary file or not */ - - struct mem_allocator* allocator; -}; - -/******************************************************************************* - * Internal helper functions - ******************************************************************************/ -static INLINE res_T -BIGBUF_FUNC__(flush__)(struct BIGBUF__* bigbuf) -{ - BIGBUF_DATA* buf_data; - size_t buf_size, write_size; - long cur, offset; - int err; - res_T res = RES_OK; - ASSERT(bigbuf); - - if(bigbuf->mode == BIGBUF_READ__) goto exit; - if(!bigbuf->buf.size) goto exit; - - buf_size = bigbuf->buf.size; - buf_data = bigbuf->buf.data; - - cur = ftell(bigbuf->file); - offset = (long)(sizeof(BIGBUF_DATA)*bigbuf->buf_index) - cur + bigbuf->head; - err = fseek(bigbuf->file, offset, SEEK_CUR); - if(err < 0) { - res = RES_IO_ERR; - goto error; - } - - write_size = fwrite(buf_data, sizeof(BIGBUF_DATA), buf_size, bigbuf->file); - - if(bigbuf->buf_index + buf_size == bigbuf->size) { - bigbuf->end = bigbuf->end + (long)write_size * (long)sizeof(BIGBUF_DATA); - } - - if(write_size == buf_size) { - bigbuf->buf.size = 0; /* Clear buffered data */ - bigbuf->buf_index = bigbuf->size; - } else if(write_size) { - size_t cp_size = buf_size - write_size; - memmove(buf_data, buf_data + write_size, cp_size); - bigbuf->buf.size = cp_size; - bigbuf->buf_index = bigbuf->buf_index + write_size; - res = RES_IO_ERR; - } else { - res = RES_IO_ERR; - } - if(res != RES_OK) goto error; - -exit: - return res; -error: - goto exit; -} - -static INLINE res_T -BIGBUF_FUNC__(fetch__)(struct BIGBUF__* bigbuf, const size_t index) -{ - BIGBUF_DATA* buf_data; - size_t buf_size; - size_t buf_index; - size_t read_size; - long cur, offset; - int err; - res_T res = RES_OK; - ASSERT(bigbuf && index < bigbuf->size); - - if(index>=bigbuf->buf_index && index<bigbuf->buf_index + bigbuf->buf.size) - goto exit; - - buf_size = bigbuf->buf.size; - buf_data = bigbuf->buf.data; - - if(bigbuf->mode == BIGBUF_WRITE__) { - res = BIGBUF_FUNC__(flush__)(bigbuf); - if(res != RES_OK) goto error; - } - - buf_index = index / bigbuf->buf.capacity * bigbuf->buf.capacity; - - cur = ftell(bigbuf->file); - offset = (long)(sizeof(BIGBUF_DATA)*buf_index) - cur + bigbuf->head; - err = fseek(bigbuf->file, offset, SEEK_CUR); - if(err < 0) { - res = RES_IO_ERR; - goto error; - } - - buf_size = MMIN(bigbuf->size - buf_index, bigbuf->buf.capacity); - bigbuf->buf.size = buf_size; - - read_size = fread(buf_data, sizeof(BIGBUF_DATA), buf_size, bigbuf->file); - bigbuf->buf_index = buf_index; - bigbuf->mode = BIGBUF_READ__; - - if(read_size != buf_size) { - bigbuf->buf.size = read_size; - res = RES_IO_ERR; - goto error; - } - -exit: - return res; -error: - goto exit; -} - -/******************************************************************************* - * Big buffer API - ******************************************************************************/ -static INLINE res_T -BIGBUF_FUNC__(flush)(struct BIGBUF__* bigbuf) -{ - size_t write_size; - int err; - res_T res = RES_OK; - ASSERT(bigbuf); - - /* Flush buffered data */ - res = BIGBUF_FUNC__(flush__)(bigbuf); - if(res != RES_OK) goto error; - - /* Write the big buffer header */ - err = fseek(bigbuf->file, bigbuf->head - (long)sizeof(size_t), SEEK_SET); - if(err < 0) { - res = RES_IO_ERR; - goto error; - } - write_size = fwrite(&bigbuf->size, sizeof(size_t), 1, bigbuf->file); - if(write_size != 1) { - res = RES_IO_ERR; - goto error; - } - -exit: - return res; -error: - goto exit; -} - -static INLINE void -BIGBUF_FUNC__(release)(struct BIGBUF__* bigbuf) -{ - ASSERT(bigbuf); - if(bigbuf->file) { - CHECK(BIGBUF_FUNC__(flush)(bigbuf), RES_OK); - if(bigbuf->temp_file) fclose(bigbuf->file); - } - if(bigbuf->buf.data) MEM_RM(bigbuf->allocator, bigbuf->buf.data); -} - -static INLINE res_T -BIGBUF_FUNC__(init) - (struct mem_allocator* allocator, /* May be NULL <=> use default allocator */ - const size_t bufsz, /* # buffered data */ - FILE* stream, /* May be NULL <=> internally manage the stream */ - int mask, /* Combination of bigbuf_flag */ - struct BIGBUF__* bigbuf) -{ - size_t size; - res_T res = RES_OK; - ASSERT(bigbuf); - memset(bigbuf, 0, sizeof(struct BIGBUF__)); - - if(!stream && (mask & BIGBUF_LOAD_STREAM)) { - res = RES_BAD_ARG; - goto error; - } - if(!bufsz) { - res = RES_BAD_ARG; - goto error; - } - - bigbuf->allocator = allocator ? allocator : &mem_default_allocator; - bigbuf->buf.capacity = bufsz; - size = bigbuf->buf.capacity * sizeof(BIGBUF_DATA); - - bigbuf->buf.data = MEM_ALLOC_ALIGNED - (bigbuf->allocator, size, BIGBUF_ALIGNMENT__); - if(!bigbuf->buf.data) { - res = RES_MEM_ERR; - goto error; - } - memset(bigbuf->buf.data, 0, size); - bigbuf->buf.size = 0; - - if(stream) { - bigbuf->file = stream; - bigbuf->temp_file = 0; - } else { - bigbuf->file = tmpfile(); - if(!bigbuf->file) { - res = RES_IO_ERR; - goto error; - } - bigbuf->temp_file = 1; - } - - if(mask & BIGBUF_LOAD_STREAM) { - /* Read the big buffer header */ - size_t rsize = fread(&bigbuf->size, sizeof(size_t), 1, bigbuf->file); - if(rsize != 1) { - res = RES_IO_ERR; - goto error; - } - } else { - /* Reserve space for the big buffer header storing the big buffer size */ - size_t wsize; - bigbuf->size = 0; - wsize = fwrite(&bigbuf->size, sizeof(size_t), 1, bigbuf->file); - if(wsize != 1) { - res = RES_IO_ERR; - goto error; - } - } - - bigbuf->buf_index = bigbuf->size; - bigbuf->head = ftell(bigbuf->file); - bigbuf->end = bigbuf->head + (long)bigbuf->size * (long)sizeof(BIGBUF_DATA); - bigbuf->mode = BIGBUF_WRITE__; - -exit: - return res; -error: - /* Reset the file to NULL to not flush buffered data during bigbuf release */ - if(bigbuf->temp_file) fclose(bigbuf->file); - bigbuf->file = NULL; - BIGBUF_FUNC__(release)(bigbuf); - goto exit; -} - -static INLINE res_T -BIGBUF_FUNC__(push_back)(struct BIGBUF__* bigbuf, const BIGBUF_DATA* data) -{ - ASSERT(bigbuf); - - if(bigbuf->size == SIZE_MAX) return RES_MEM_ERR; - if(bigbuf->mode == BIGBUF_READ__) { - bigbuf->buf.size = 0; /* Clear buffered data */ - bigbuf->buf_index = bigbuf->size; - } - - ASSERT(bigbuf->buf.size < bigbuf->buf.capacity); - bigbuf->buf.data[bigbuf->buf.size++] = *data; /* Push back */ - bigbuf->mode = BIGBUF_WRITE__; - ++bigbuf->size; - - if(bigbuf->buf.size == bigbuf->buf.capacity) { - return BIGBUF_FUNC__(flush__)(bigbuf); - } else { - return RES_OK; - } -} - -static FINLINE size_t -BIGBUF_FUNC__(size_get)(const struct BIGBUF__* bigbuf) -{ - ASSERT(bigbuf); - return bigbuf->size; -} - -static INLINE res_T -BIGBUF_FUNC__(resize)(struct BIGBUF__* bigbuf, const size_t size) -{ - res_T res = RES_OK; - ASSERT(bigbuf); - - if(size == bigbuf->size) goto exit; - - if(size < bigbuf->size) { - if(bigbuf->buf_index >= size) { - /* Clear all buffered data */ - bigbuf->buf.size = 0; - bigbuf->buf_index = size; - } - if(bigbuf->buf_index + bigbuf->buf.size > size) { - /* Clear some buffered data */ - bigbuf->buf.size = size - bigbuf->buf_index; - } - } - bigbuf->size = size; - bigbuf->end = bigbuf->head + (long)(bigbuf->size*sizeof(BIGBUF_DATA)); - - res = truncate__ - (bigbuf->file, bigbuf->size*sizeof(BIGBUF_DATA) + sizeof(size_t)/*header*/); - if(res != RES_OK) goto error; - -exit: - return res; -error: - goto exit; -} - -static FINLINE res_T -BIGBUF_FUNC__(clear)(struct BIGBUF__* bigbuf) -{ - return BIGBUF_FUNC__(resize)(bigbuf, 0); -} - -static INLINE res_T -BIGBUF_FUNC__(set) - (struct BIGBUF__* bigbuf, const size_t at, const BIGBUF_DATA* data) -{ - res_T res = RES_OK; - ASSERT(bigbuf && data); - - if(at >= bigbuf->size) { - res = RES_BAD_ARG; - goto error; - } - - res = BIGBUF_FUNC__(fetch__)(bigbuf, at); - if(res != RES_OK) goto error; - - ASSERT(at >= bigbuf->buf_index); - bigbuf->buf.data[at - bigbuf->buf_index] = *data; - bigbuf->mode = BIGBUF_WRITE__; - -exit: - return res; -error: - goto exit; -} - -static INLINE const BIGBUF_DATA* -BIGBUF_FUNC__(at)(struct BIGBUF__* bigbuf, const size_t at) -{ - res_T res = RES_OK; (void)res; - ASSERT(bigbuf && at < bigbuf->size); - - res = BIGBUF_FUNC__(fetch__)(bigbuf, at); - ASSERT(res == RES_OK); - - ASSERT(at >= bigbuf->buf_index); - return bigbuf->buf.data + at - bigbuf->buf_index; -} - -#undef BIGBUF_ALIGNMENT -#undef BIGBUF_DATA -#undef BIGBUF_NAME - -#undef BIGBUF__ -#undef BIGBUF_ALIGNMENT__ -#undef BIGBUF_FUNC__ - -#endif /* !BIGBUF_NAME || !BIGBUF_TYPE */ -