/* Wrap a function for processing a single block to process an entire buffer in * parallel. */ int64_t bshuf_blocked_wrap_fun(bshufBlockFunDef fun, void* in, void* out, const size_t size, const size_t elem_size, size_t block_size) { size_t ii; ioc_chain C; ioc_init(&C, in, out); int64_t err = 0, count, cum_count = 0; size_t last_block_size; if (block_size == 0) { block_size = bshuf_default_block_size(elem_size); } if (block_size < 0 || block_size % BSHUF_BLOCKED_MULT) return -81; #if defined(_OPENMP) #pragma omp parallel for schedule(dynamic, 1) \ private(count) reduction(+ : cum_count) #endif for (ii = 0; ii < size / block_size; ii ++) { count = fun(&C, block_size, elem_size); if (count < 0) err = count; cum_count += count; } last_block_size = size % block_size; last_block_size = last_block_size - last_block_size % BSHUF_BLOCKED_MULT; if (last_block_size) { count = fun(&C, last_block_size, elem_size); if (count < 0) err = count; cum_count += count; } if (err < 0) return err; size_t leftover_bytes = size % BSHUF_BLOCKED_MULT * elem_size; size_t this_iter; char *last_in = (char *) ioc_get_in(&C, &this_iter); ioc_set_next_in(&C, &this_iter, (void *) (last_in + leftover_bytes)); char *last_out = (char *) ioc_get_out(&C, &this_iter); ioc_set_next_out(&C, &this_iter, (void *) (last_out + leftover_bytes)); memcpy(last_out, last_in, leftover_bytes); ioc_destroy(&C); return cum_count + leftover_bytes; }
size_t bshuf_compress_lz4_bound(const size_t size, const size_t elem_size, size_t block_size) { size_t bound, leftover; if (block_size == 0) { block_size = bshuf_default_block_size(elem_size); } if (block_size < 0 || block_size % BSHUF_BLOCKED_MULT) return -81; // Note that each block gets a 4 byte header. // Size of full blocks. bound = (LZ4_compressBound(block_size * elem_size) + 4) * (size / block_size); // Size of partial blocks, if any. leftover = ((size % block_size) / BSHUF_BLOCKED_MULT) * BSHUF_BLOCKED_MULT; if (leftover) bound += LZ4_compressBound(leftover * elem_size) + 4; // Size of uncompressed data not fitting into any blocks. bound += (size % BSHUF_BLOCKED_MULT) * elem_size; return bound; }