Home | History | Annotate | Download | only in depool
      1 #ifndef _DEPOOLHEAP_H
      2 #define _DEPOOLHEAP_H
      3 /*-------------------------------------------------------------------------
      4  * drawElements Memory Pool Library
      5  * --------------------------------
      6  *
      7  * Copyright 2014 The Android Open Source Project
      8  *
      9  * Licensed under the Apache License, Version 2.0 (the "License");
     10  * you may not use this file except in compliance with the License.
     11  * You may obtain a copy of the License at
     12  *
     13  *      http://www.apache.org/licenses/LICENSE-2.0
     14  *
     15  * Unless required by applicable law or agreed to in writing, software
     16  * distributed under the License is distributed on an "AS IS" BASIS,
     17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     18  * See the License for the specific language governing permissions and
     19  * limitations under the License.
     20  *
     21  *//*!
     22  * \file
     23  * \brief Memory pool heap class.
     24  *//*--------------------------------------------------------------------*/
     25 
     26 #include "deDefs.h"
     27 #include "deMemPool.h"
     28 #include "dePoolArray.h"
     29 
     30 DE_BEGIN_EXTERN_C
     31 
     32 void			dePoolHeap_selfTest			(void);
     33 
     34 DE_END_EXTERN_C
     35 
     36 /*--------------------------------------------------------------------*//*!
     37  * \brief Declare a template pool heap class.
     38  * \param TYPENAME	Type name of the declared heap.
     39  * \param VALUETYPE	Type of the value contained in the heap.
     40  * \param CMPFUNC	Comparison function of two elements returning (-1, 0, +1).
     41  *
     42  * This macro declares a pool heap with all the necessary functions for
     43  * operating with it. All allocated memory is taken from the memory pool
     44  * given to the constructor.
     45  *
     46  * The functions for operating the heap are:
     47  *
     48  * \code
     49  * Heap*    Heap_create            (deMemPool* pool);
     50  * int      Heap_getNumElements    (const Heap* heap);
     51  * deBool   Heap_reserve           (Heap* heap, int size);
     52  * void		Heap_reset             (Heap* heap);
     53  * deBool   Heap_push              (Heap* heap, Element elem);
     54  * Element  Heap_popMin            (Heap* heap);
     55  * \endcode
     56 *//*--------------------------------------------------------------------*/
     57 #define DE_DECLARE_POOL_HEAP(TYPENAME, VALUETYPE, CMPFUNC)		\
     58     \
     59 DE_DECLARE_POOL_ARRAY(TYPENAME##Array, VALUETYPE);		\
     60 \
     61 typedef struct TYPENAME##_s    \
     62 {    \
     63 	TYPENAME##Array*	array;		\
     64 } TYPENAME; /* NOLINT(TYPENAME) */  \
     65 \
     66 DE_INLINE TYPENAME*	TYPENAME##_create			(deMemPool* pool);													\
     67 DE_INLINE int		TYPENAME##_getNumElements	(const TYPENAME* heap)							DE_UNUSED_FUNCTION;	\
     68 DE_INLINE deBool	TYPENAME##_reserve			(DE_PTR_TYPE(TYPENAME) heap, int capacity)		DE_UNUSED_FUNCTION;	\
     69 DE_INLINE void		TYPENAME##_reset			(DE_PTR_TYPE(TYPENAME) heap)					DE_UNUSED_FUNCTION;	\
     70 DE_INLINE void		TYPENAME##_moveDown			(DE_PTR_TYPE(TYPENAME) heap, int ndx)			DE_UNUSED_FUNCTION;	\
     71 DE_INLINE void		TYPENAME##_moveUp			(DE_PTR_TYPE(TYPENAME) heap, int ndx)			DE_UNUSED_FUNCTION;	\
     72 DE_INLINE deBool	TYPENAME##_push				(DE_PTR_TYPE(TYPENAME) heap, VALUETYPE elem)	DE_UNUSED_FUNCTION;	\
     73 DE_INLINE VALUETYPE	TYPENAME##_popMin			(DE_PTR_TYPE(TYPENAME) heap)					DE_UNUSED_FUNCTION;	\
     74 \
     75 DE_INLINE TYPENAME* TYPENAME##_create (deMemPool* pool)    \
     76 {    \
     77 	DE_PTR_TYPE(TYPENAME) heap = DE_POOL_NEW(pool, TYPENAME);	\
     78 	if (!heap)				\
     79 		return DE_NULL;		\
     80 	heap->array = TYPENAME##Array_create(pool);	\
     81 	if (!heap->array)		\
     82 		return DE_NULL;		\
     83 	return heap;			\
     84 }    \
     85 \
     86 DE_INLINE int TYPENAME##_getNumElements (const TYPENAME* heap)    \
     87 {    \
     88 	return TYPENAME##Array_getNumElements(heap->array);    \
     89 }    \
     90 \
     91 DE_INLINE deBool TYPENAME##_reserve (DE_PTR_TYPE(TYPENAME) heap, int capacity)    \
     92 {    \
     93 	return TYPENAME##Array_reserve(heap->array, capacity);    \
     94 }    \
     95 \
     96 DE_INLINE void TYPENAME##_reset (DE_PTR_TYPE(TYPENAME) heap)    \
     97 {    \
     98 	TYPENAME##Array_setSize(heap->array, 0);    \
     99 }    \
    100 \
    101 DE_INLINE void TYPENAME##_moveDown (DE_PTR_TYPE(TYPENAME) heap, int ndx)    \
    102 {   \
    103 	TYPENAME##Array*	array		= heap->array;	\
    104 	int					numElements	= TYPENAME##Array_getNumElements(array);	\
    105 	for (;;)	\
    106 	{	\
    107 		int childNdx0	= 2*ndx + 1;								\
    108 		if (childNdx0 < numElements)	\
    109 		{	\
    110 			int childNdx1	= deMin32(childNdx0 + 1, numElements - 1);	\
    111 			int childCmpRes	= CMPFUNC(TYPENAME##Array_get(array, childNdx0), TYPENAME##Array_get(array, childNdx1)); \
    112 			int minChildNdx	= (childCmpRes == 1) ? childNdx1 : childNdx0;	\
    113 			int cmpRes		= CMPFUNC(TYPENAME##Array_get(array, ndx), TYPENAME##Array_get(array, minChildNdx)); \
    114 			if (cmpRes == 1)	\
    115 			{	\
    116 				TYPENAME##Array_swap(array, ndx, minChildNdx);	\
    117 				ndx = minChildNdx;	\
    118 			}	\
    119 			else	\
    120 				break;	\
    121 		}	\
    122 		else	\
    123 			break;	\
    124 	}	\
    125 }    \
    126 \
    127 DE_INLINE void TYPENAME##_moveUp (DE_PTR_TYPE(TYPENAME) heap, int ndx)    \
    128 {    \
    129 	TYPENAME##Array* array = heap->array;	\
    130 	while (ndx > 0)	\
    131 	{	\
    132 		int parentNdx	= (ndx-1) >> 1;								\
    133 		int cmpRes		= CMPFUNC(TYPENAME##Array_get(array, ndx), TYPENAME##Array_get(array, parentNdx)); \
    134 		if (cmpRes == -1)	\
    135 		{	\
    136 			TYPENAME##Array_swap(array, ndx, parentNdx);	\
    137 			ndx = parentNdx;	\
    138 		}	\
    139 		else	\
    140 			break;	\
    141 	}	\
    142 }    \
    143 \
    144 DE_INLINE deBool TYPENAME##_push (DE_PTR_TYPE(TYPENAME) heap, VALUETYPE elem)    \
    145 {    \
    146 	TYPENAME##Array* array = heap->array;	\
    147 	int numElements = TYPENAME##Array_getNumElements(array);	\
    148 	if (!TYPENAME##Array_setSize(array, numElements + 1)) \
    149 		return DE_FALSE; \
    150 	TYPENAME##Array_set(array, numElements, elem); \
    151 	TYPENAME##_moveUp(heap, numElements);	\
    152 	return DE_TRUE;    \
    153 }    \
    154 \
    155 DE_INLINE VALUETYPE TYPENAME##_popMin (DE_PTR_TYPE(TYPENAME) heap)    \
    156 {    \
    157 	TYPENAME##Array* array = heap->array;	\
    158 	VALUETYPE	tmp			= TYPENAME##Array_get(array, 0);	\
    159 	int			numElements	= TYPENAME##Array_getNumElements(array);	\
    160 	TYPENAME##Array_set(array, 0, TYPENAME##Array_get(array, numElements-1));	\
    161 	TYPENAME##Array_setSize(array, numElements-1);	\
    162 	TYPENAME##_moveDown(heap, 0);	\
    163 	return tmp;	\
    164 }    \
    165 \
    166 struct TYPENAME##Dummy_s { int dummy; }
    167 
    168 #endif /* _DEPOOLHEAP_H */
    169