/*-------------------------------------------------------------------------
 * drawElements Memory Pool Library
 * --------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Memory pool array class.
 *
 * Features of the pooled arrays:
 * - single indirection layer (grows exponentially)
 * - constant # elements per page
 * - recycles old indirection tables as element pages
 * - about 10% overhead on large arrays
 *//*--------------------------------------------------------------------*/

#include "dePoolArray.h"
#include "deInt32.h"

#include <stdlib.h>
#include <string.h>

/*--------------------------------------------------------------------*//*!
 * \internal
 * \brief Create a new pool array.
 * \param pool			Pool to allocate memory from.
 * \param elementSize	Size of the element to be put in array.
 * \param Pointer to the created array, or null on failure.
 *//*--------------------------------------------------------------------*/
dePoolArray* dePoolArray_create (deMemPool* pool, int elementSize)
{
	/* Alloc struct. */
	dePoolArray* arr = DE_POOL_NEW(pool, dePoolArray);
	if (!arr)
		return DE_NULL;

	/* Init array. */
	memset(arr, 0, sizeof(dePoolArray));
	arr->pool			= pool;
	arr->elementSize	= elementSize;

	return arr;
}

/*--------------------------------------------------------------------*//*!
 * \internal
 * \brief Ensure that the array can hold at least N elements.
 * \param arr	Array pointer.
 * \param size	Number of elements for which to reserve memory.
 * \param True on success, false on failure.
 *//*--------------------------------------------------------------------*/
deBool			dePoolArray_reserve			(dePoolArray* arr, int size)
{
	if (size >= arr->capacity)
	{
		void*	oldPageTable			= DE_NULL;
		int		oldPageTableSize		= 0;

		int		newCapacity				= deAlign32(size, 1 << DE_ARRAY_ELEMENTS_PER_PAGE_LOG2);
		int		reqPageTableCapacity	= newCapacity >> DE_ARRAY_ELEMENTS_PER_PAGE_LOG2;

		if (arr->pageTableCapacity < reqPageTableCapacity)
		{
			int		newPageTableCapacity	= deMax32(2*arr->pageTableCapacity, reqPageTableCapacity);
			void**	newPageTable			= (void**)deMemPool_alloc(arr->pool, (size_t)newPageTableCapacity * sizeof(void*));
			int		i;

			if (!newPageTable)
				return DE_FALSE;

			for (i = 0; i < arr->pageTableCapacity; i++)
				newPageTable[i] = arr->pageTable[i];

			for (; i < newPageTableCapacity; i++)
				newPageTable[i] = DE_NULL;

			/* Grab information about old page table for recycling purposes. */
			oldPageTable		= arr->pageTable;
			oldPageTableSize	= arr->pageTableCapacity * (int)sizeof(void*);

			arr->pageTable			= newPageTable;
			arr->pageTableCapacity	= newPageTableCapacity;
		}

		/* Allocate new pages. */
		{
			int pageAllocSize = arr->elementSize << DE_ARRAY_ELEMENTS_PER_PAGE_LOG2;
			int pageTableNdx = arr->capacity >> DE_ARRAY_ELEMENTS_PER_PAGE_LOG2;

			/* Allocate new pages from recycled old page table. */
			while (oldPageTableSize >= pageAllocSize)
			{
				void* newPage = oldPageTable;
				DE_ASSERT(arr->pageTableCapacity > pageTableNdx); /* \todo [petri] is this always true? */
				DE_ASSERT(!arr->pageTable[pageTableNdx]);
				arr->pageTable[pageTableNdx++] = newPage;

				oldPageTable = (void*)((deUint8*)oldPageTable + pageAllocSize);
				oldPageTableSize -= pageAllocSize;
			}

			/* Allocate the rest of the needed pages from the pool. */
			for (; pageTableNdx < reqPageTableCapacity; pageTableNdx++)
			{
				void* newPage = deMemPool_alloc(arr->pool, (size_t)pageAllocSize);
				if (!newPage)
					return DE_FALSE;

				DE_ASSERT(!arr->pageTable[pageTableNdx]);
				arr->pageTable[pageTableNdx] = newPage;
			}

			arr->capacity = pageTableNdx << DE_ARRAY_ELEMENTS_PER_PAGE_LOG2;
			DE_ASSERT(arr->capacity >= newCapacity);
		}
	}

	return DE_TRUE;
}

/*--------------------------------------------------------------------*//*!
 * \internal
 * \brief Set the size of the array (also reserves capacity).
 * \param arr	Array pointer.
 * \param size	New size of the array (in elements).
 * \param True on success, false on failure.
 *//*--------------------------------------------------------------------*/
deBool			dePoolArray_setSize			(dePoolArray* arr, int size)
{
	if (!dePoolArray_reserve(arr, size))
		return DE_FALSE;

	arr->numElements = size;
	return DE_TRUE;
}

DE_DECLARE_POOL_ARRAY(dePoolIntArray, int);
DE_DECLARE_POOL_ARRAY(dePoolInt16Array, deInt16);

/*--------------------------------------------------------------------*//*!
 * \internal
 * \brief Test array functionality.
 *//*--------------------------------------------------------------------*/
void dePoolArray_selfTest (void)
{
	deMemPool*			pool	= deMemPool_createRoot(DE_NULL, 0);
	dePoolIntArray*		arr		= dePoolIntArray_create(pool);
	dePoolInt16Array*	arr16	= dePoolInt16Array_create(pool);
	int					i;

	/* Test pushBack(). */
	for (i = 0; i < 5000; i++)
	{
		/* Dummy alloc to try to break alignments. */
		deMemPool_alloc(pool, 1);

		dePoolIntArray_pushBack(arr, i);
		dePoolInt16Array_pushBack(arr16, (deInt16)i);
	}

	DE_TEST_ASSERT(dePoolIntArray_getNumElements(arr) == 5000);
	DE_TEST_ASSERT(dePoolInt16Array_getNumElements(arr16) == 5000);
	for (i = 0; i < 5000; i++)
	{
		DE_TEST_ASSERT(dePoolIntArray_get(arr, i) == i);
		DE_TEST_ASSERT(dePoolInt16Array_get(arr16, i) == i);
	}

	/* Test popBack(). */
	for (i = 0; i < 1000; i++)
	{
		DE_TEST_ASSERT(dePoolIntArray_popBack(arr) == (4999 - i));
		DE_TEST_ASSERT(dePoolInt16Array_popBack(arr16) == (4999 - i));
	}

	DE_TEST_ASSERT(dePoolIntArray_getNumElements(arr) == 4000);
	DE_TEST_ASSERT(dePoolInt16Array_getNumElements(arr16) == 4000);
	for (i = 0; i < 4000; i++)
	{
		DE_TEST_ASSERT(dePoolIntArray_get(arr, i) == i);
		DE_TEST_ASSERT(dePoolInt16Array_get(arr16, i) == i);
	}

	/* Test setSize(). */
	dePoolIntArray_setSize(arr, 1000);
	dePoolInt16Array_setSize(arr16, 1000);
	for (i = 1000; i < 5000; i++)
	{
		dePoolIntArray_pushBack(arr, i);
		dePoolInt16Array_pushBack(arr16, (deInt16)i);
	}

	DE_TEST_ASSERT(dePoolIntArray_getNumElements(arr) == 5000);
	DE_TEST_ASSERT(dePoolInt16Array_getNumElements(arr16) == 5000);
	for (i = 0; i < 5000; i++)
	{
		DE_TEST_ASSERT(dePoolIntArray_get(arr, i) == i);
		DE_TEST_ASSERT(dePoolInt16Array_get(arr16, i) == i);
	}

	/* Test set() and pushBack() with reserve(). */
	arr = dePoolIntArray_create(pool);
	dePoolIntArray_setSize(arr, 1500);
	dePoolIntArray_reserve(arr, 2000);
	for (i = 0; i < 1500; i++)
		dePoolIntArray_set(arr, i, i);
	for (; i < 5000; i++)
		dePoolIntArray_pushBack(arr, i);

	DE_TEST_ASSERT(dePoolIntArray_getNumElements(arr) == 5000);
	for (i = 0; i < 5000; i++)
	{
		int val = dePoolIntArray_get(arr, i);
		DE_TEST_ASSERT(val == i);
	}

	deMemPool_destroy(pool);
}
