5#include "testing/testing.h"
25static void print_mem_saved(
const char *
id,
const BArrayStore *bs)
29 const double percent = size_expand ? ((size_real / size_expand) * 100.0) : -1.0;
30 printf(
"%s: %.8f%%\n",
id, percent);
54static TestChunk *testchunk_list_add_copydata(
ListBase *lb,
const void *data,
size_t data_len)
57 memcpy(data_copy, data, data_len);
73static char *testchunk_as_data(
ListBase *lb,
size_t *r_data_len)
77 data_len += tc->data_len;
79 char *data = (
char *)
MEM_mallocN(data_len, __func__);
82 memcpy(&data[i], tc->data, tc->data_len);
83 data_len += tc->data_len;
96 for (
int tc_index = 0; tc_index < tc_array_len; tc_index++) {
97 data_len += tc_array[tc_index]->
data_len;
99 char *data = (
char *)
MEM_mallocN(data_len, __func__);
101 for (
int tc_index = 0; tc_index < tc_array_len; tc_index++) {
138 memcpy(data_copy, data, data_len);
153 const size_t data_len,
160 const size_t data_stride_len = data_len * stride;
161 char *data_stride = (
char *)
MEM_mallocN(data_stride_len, __func__);
163 for (
size_t i = 0, i_stride = 0; i < data_len; i += 1, i_stride += stride) {
164 memset(&data_stride[i_stride], data[i], stride);
171#define testbuffer_list_state_from_string_array(lb, data_array) \
175 while ((data = data_array[i_++])) { \
176 testbuffer_list_state_from_data(lb, data, strlen(data)); \
183#define TESTBUFFER_STRINGS_CREATE(lb, ...) \
185 BLI_listbase_clear(lb); \
186 const char *data_array[] = {__VA_ARGS__ nullptr}; \
187 testbuffer_list_state_from_string_array((lb), data_array); \
192#define TESTBUFFER_STRINGS(stride, chunk_count, ...) \
195 TESTBUFFER_STRINGS_CREATE(&lb, __VA_ARGS__); \
197 testbuffer_run_tests_simple(&lb, stride, chunk_count); \
199 testbuffer_list_free(&lb); \
205 size_t data_state_len;
208 if (tb->
data_len != data_state_len) {
211 else if (memcmp(data_state, tb->
data, data_state_len) != 0) {
239 tb_prev = tb, tb = tb->next)
242 bs, tb->data, tb->data_len, (tb_prev ? tb_prev->state :
nullptr));
270 print_mem_saved(
"data", bs);
307 const uchar data[] =
"test";
317 const char data_src[] =
"test";
318 const char *data_dst;
322 EXPECT_STREQ(data_src, data_dst);
323 EXPECT_EQ(data_dst_len,
sizeof(data_src));
331 const char data_src[] =
"test";
332 const char *data_dst;
343 EXPECT_STREQ(data_src, data_dst);
347 EXPECT_STREQ(data_src, data_dst);
350 EXPECT_EQ(data_dst_len,
sizeof(data_src));
357 const char data_src_a[] =
"test";
358 const char data_src_b[] =
"####";
359 const char *data_dst;
369 EXPECT_STREQ(data_src_a, data_dst);
373 EXPECT_STREQ(data_src_b, data_dst);
389TEST(array_store, TextDupeIncreaseDecrease)
429 const char word_delim,
431 const int chunk_count,
432 const int random_seed)
438 for (
int i = 0, i_prev = 0; i < words_len; i++) {
439 if (
ELEM(words[i], word_delim,
'\0')) {
457#define WORDS words10k, sizeof(words10k)
458TEST(array_store, TextSentences_Chunk1)
462TEST(array_store, TextSentences_Chunk2)
466TEST(array_store, TextSentences_Chunk8)
470TEST(array_store, TextSentences_Chunk32)
474TEST(array_store, TextSentences_Chunk128)
478TEST(array_store, TextSentences_Chunk1024)
483TEST(array_store, TextSentences_Chunk3)
487TEST(array_store, TextSentences_Chunk13)
491TEST(array_store, TextSentences_Chunk131)
497TEST(array_store, TextWords_Chunk1)
501TEST(array_store, TextWords_Chunk2)
505TEST(array_store, TextWords_Chunk8)
509TEST(array_store, TextWords_Chunk32)
513TEST(array_store, TextWords_Chunk128)
517TEST(array_store, TextWords_Chunk1024)
522TEST(array_store, TextWords_Chunk3)
526TEST(array_store, TextWords_Chunk13)
530TEST(array_store, TextWords_Chunk131)
536TEST(array_store, TextSentencesRandom_Stride3_Chunk3)
540TEST(array_store, TextSentencesRandom_Stride8_Chunk8)
544TEST(array_store, TextSentencesRandom_Stride32_Chunk1)
548TEST(array_store, TextSentencesRandom_Stride12_Chunk512)
552TEST(array_store, TextSentencesRandom_Stride128_Chunk6)
571 value = (value / step) * step;
572 return min_i + value;
577 const size_t data_min_len,
578 const size_t data_max_len,
583 size_t data_len =
rand_range_i(rng, data_min_len, data_max_len + stride, stride);
584 char *data = (
char *)
MEM_mallocN(data_len, __func__);
586 if (lb->
last ==
nullptr) {
591 if (tb_last->
data_len >= data_len) {
592 memcpy(data, tb_last->
data, data_len);
600 for (
int i = 0; i < mutate; i++) {
616 if (data_len < data_max_len) {
619 memmove(&data[offset + stride], &data[offset], data_len - (offset + stride));
624 case MUTATE_REMOVE: {
626 if (data_len > data_min_len) {
627 memmove(&data[offset], &data[offset + stride], data_len - (offset + stride));
632 case MUTATE_ROTATE: {
633 int items = data_len / stride;
639 case MUTATE_RANDOMIZE: {
656 const int items_size_max,
657 const int items_total,
659 const int chunk_count,
660 const int random_seed,
667 const size_t data_min_len = items_size_min * stride;
668 const size_t data_max_len = items_size_max * stride;
672 for (
int i = 0; i < items_total; i++) {
683TEST(array_store, TestData_Stride1_Chunk32_Mutate2)
687TEST(array_store, TestData_Stride8_Chunk512_Mutate2)
691TEST(array_store, TestData_Stride12_Chunk48_Mutate2)
695TEST(array_store, TestData_Stride32_Chunk64_Mutate1)
699TEST(array_store, TestData_Stride32_Chunk64_Mutate8)
708 const int chunks_per_buffer,
710 const int chunk_count,
711 const int random_seed)
714 const size_t chunk_size_bytes = stride * chunk_count;
715 for (
int i = 0; i < chunks_per_buffer; i++) {
716 char *data_chunk = (
char *)
MEM_mallocN(chunk_size_bytes, __func__);
727 const int items_total,
729 const int chunk_count,
730 const int random_seed)
741 for (
int i = 0; i < chunks_per_buffer; i++, tc = tc->
next) {
742 chunks_array[i] = tc;
752 for (
int i = 0; i < items_total; i++) {
756 BLI_assert(data_len == chunks_per_buffer * chunk_count * stride);
768 size_t expected_size = chunks_per_buffer * chunk_count * stride;
776TEST(array_store, TestChunk_Rand8_Stride1_Chunk64)
780TEST(array_store, TestChunk_Rand32_Stride1_Chunk64)
784TEST(array_store, TestChunk_Rand64_Stride8_Chunk32)
788TEST(array_store, TestChunk_Rand31_Stride11_Chunk21)
798static void *file_read_binary_as_mem(
const char *filepath,
size_t pad_bytes,
size_t *r_size)
800 FILE *fp = fopen(filepath,
"rb");
804 long int filelen_read;
805 fseek(fp, 0
L, SEEK_END);
806 const long int filelen = ftell(fp);
810 fseek(fp, 0
L, SEEK_SET);
813 if (mem ==
nullptr) {
817 filelen_read = fread(mem, 1, filelen, fp);
818 if ((filelen_read != filelen) || ferror(fp)) {
824 *r_size = filelen_read;
833TEST(array_store, PlainTextFiles)
839 for (
int i = 0; i < 629; i++) {
846 data = file_read_binary_as_mem(
str, 0, &data_len);
856 print_mem_saved(
"source code forward", bs);
867 print_mem_saved(
"source code backwards", bs);
Efficient in-memory storage of multiple similar arrays.
BArrayState * BLI_array_store_state_add(BArrayStore *bs, const void *data, size_t data_len, const BArrayState *state_reference)
void BLI_array_store_state_remove(BArrayStore *bs, BArrayState *state)
size_t BLI_array_store_calc_size_expanded_get(const BArrayStore *bs)
bool BLI_array_store_is_valid(BArrayStore *bs)
size_t BLI_array_store_state_size_get(BArrayState *state)
void * BLI_array_store_state_data_get_alloc(BArrayState *state, size_t *r_data_len)
void BLI_array_store_destroy(BArrayStore *bs)
size_t BLI_array_store_calc_size_compacted_get(const BArrayStore *bs)
BArrayStore * BLI_array_store_create(unsigned int stride, unsigned int chunk_count)
static void random_data_mutate_helper(const int items_size_min, const int items_size_max, const int items_total, const int stride, const int chunk_count, const int random_seed, const int mutate)
#define TESTBUFFER_STRINGS(stride, chunk_count,...)
static void testbuffer_list_state_from_data__stride_expand(ListBase *lb, const char *data, const size_t data_len, const size_t stride)
#define TESTBUFFER_STRINGS_CREATE(lb,...)
static TestChunk * testchunk_list_add(ListBase *lb, const void *data, size_t data_len)
static void testbuffer_list_state_random_data(ListBase *lb, const size_t stride, const size_t data_min_len, const size_t data_max_len, const uint mutate, RNG *rng)
static void testbuffer_list_store_populate(BArrayStore *bs, ListBase *lb)
static void testbuffer_list_store_clear(BArrayStore *bs, ListBase *lb)
static bool testbuffer_item_validate(TestBuffer *tb)
static void testbuffer_list_data_randomize(ListBase *lb, uint random_seed)
static TestBuffer * testbuffer_list_add_copydata(ListBase *lb, const void *data, size_t data_len)
static void random_chunk_mutate_helper(const int chunks_per_buffer, const int items_total, const int stride, const int chunk_count, const int random_seed)
static void testbuffer_run_tests(BArrayStore *bs, ListBase *lb)
static void testchunk_list_free(ListBase *lb)
static void testbuffer_run_tests_single(BArrayStore *bs, ListBase *lb)
static bool testbuffer_list_validate(const ListBase *lb)
static void random_chunk_generate(ListBase *lb, const int chunks_per_buffer, const int stride, const int chunk_count, const int random_seed)
static TestBuffer * testbuffer_list_add(ListBase *lb, const void *data, size_t data_len)
static char * testchunk_as_data_array(TestChunk **tc_array, int tc_array_len, size_t *r_data_len)
static void testbuffer_list_state_from_data(ListBase *lb, const char *data, const size_t data_len)
static void plain_text_helper(const char *words, int words_len, const char word_delim, const int stride, const int chunk_count, const int random_seed)
static void testbuffer_run_tests_simple(ListBase *lb, const int stride, const int chunk_count)
static void testbuffer_list_free(ListBase *lb)
static uint rand_range_i(RNG *rng, uint min_i, uint max_i, uint step)
Generic array manipulation API.
void _bli_array_wrap(void *arr_v, uint arr_len, size_t arr_stride, int dir)
#define BLI_assert_unreachable()
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void void void void void void void BLI_listbase_reverse(struct ListBase *lb) ATTR_NONNULL(1)
void BLI_rng_shuffle_array(struct RNG *rng, void *data, unsigned int elem_size_i, unsigned int elem_num) ATTR_NONNULL(1
struct RNG * BLI_rng_new(unsigned int seed)
void BLI_rng_free(struct RNG *rng) ATTR_NONNULL(1)
unsigned int BLI_rng_get_uint(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_rng_get_char_n(RNG *rng, char *bytes, size_t bytes_len) ATTR_NONNULL(1
void BLI_array_randomize(void *data, unsigned int elem_size, unsigned int elem_num, unsigned int seed)
size_t BLI_snprintf(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
Read Guarded memory(de)allocation.
#define MEM_reallocN(vmemh, len)
void *(* MEM_mallocN)(size_t len, const char *str)
void MEM_freeN(void *vmemh)