/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* Copyright (c) 2021 Brett Sheffield <bacs@librecast.net> */

#include "test.h"
#include "testdata.h"
#include <librecast/mtree.h>
#include <errno.h>

#ifdef TEST_STRESS
# define TEST_SIZE 1073741825
#else
# define TEST_SIZE 209715110
#endif

/* nice powers of two hide bugs */
static_assert(__builtin_popcount(TEST_SIZE) > 1, "TEST_SIZE must not be a power of 2");

int main(void)
{
	const size_t nthreads = 16;
	char *data;
	pthread_t tid[nthreads];
	q_t q = {0};
	mtree_t tree = {0};
	int rc;

	test_name("mtree_build() - preallocated job queue");

	data = malloc(TEST_SIZE);
	assert(data);

	test_random_bytes(data, TEST_SIZE);

	/* initialize queue and threadpool */
	q_init(&q);
	q_pool_create(tid, nthreads, q_job_seek, &q);

	rc = mtree_init(&tree, TEST_SIZE);
	test_assert(rc == 0, "mtree_init()");
	if (rc == -1) goto exit_0;

	rc = mtree_build(&tree, data, &q);
	test_assert(rc == 0, "mtree_build()");
#ifdef HEXDUMP
	mtree_hexdump(&tree, stderr);
#endif

	mtree_free(&tree);
exit_0:
	/* destroy threads, free queue */
	q_pool_destroy(tid, nthreads);
	q_free(&q);
	free(data);

	return test_status;
}
