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