1*35238bceSAndroid Build Coastguard Worker #ifndef _DEPOOLHASHARRAY_H 2*35238bceSAndroid Build Coastguard Worker #define _DEPOOLHASHARRAY_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 hash-array 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 "dePoolHash.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 dePoolHashArray_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 hash-array (array with hash) class interface. 38*35238bceSAndroid Build Coastguard Worker * \param TYPENAME Type name of the declared hash-array. 39*35238bceSAndroid Build Coastguard Worker * \param KEYTYPE Type of the key. 40*35238bceSAndroid Build Coastguard Worker * \param VALUETYPE Type of the value. 41*35238bceSAndroid Build Coastguard Worker * \param KEYARRAYTYPE Type of the key array. 42*35238bceSAndroid Build Coastguard Worker * \param VALUEARRAYTYPE Type of the value array. 43*35238bceSAndroid Build Coastguard Worker * 44*35238bceSAndroid Build Coastguard Worker * \todo [petri] Description. 45*35238bceSAndroid Build Coastguard Worker * 46*35238bceSAndroid Build Coastguard Worker * The functions for operating the hash are: 47*35238bceSAndroid Build Coastguard Worker * \todo [petri] Figure out how to comment these in Doxygen-style. 48*35238bceSAndroid Build Coastguard Worker * 49*35238bceSAndroid Build Coastguard Worker * \todo [pyry] HashArray_find() will break if dePoolArray implementation changes. 50*35238bceSAndroid Build Coastguard Worker * 51*35238bceSAndroid Build Coastguard Worker * \code 52*35238bceSAndroid Build Coastguard Worker * HashArray* HashArray_create (deMemPool* pool); 53*35238bceSAndroid Build Coastguard Worker * int HashArray_getNumElements (const HashArray* hashArray); 54*35238bceSAndroid Build Coastguard Worker * Value* HashArray_find (Hash* hashArray, Key key); 55*35238bceSAndroid Build Coastguard Worker * bool HashArray_insert (Hash* hashArray, Key key, Value value); 56*35238bceSAndroid Build Coastguard Worker * bool HashArray_copyToArray (Hash* hashArray, KeyArray* keys, ValueArray* values); 57*35238bceSAndroid Build Coastguard Worker * \endcode 58*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/ 59*35238bceSAndroid Build Coastguard Worker #define DE_DECLARE_POOL_HASH_ARRAY(TYPENAME, KEYTYPE, VALUETYPE, KEYARRAYTYPE, VALUEARRAYTYPE) \ 60*35238bceSAndroid Build Coastguard Worker \ 61*35238bceSAndroid Build Coastguard Worker DE_DECLARE_POOL_ARRAY(TYPENAME##Array, VALUETYPE); \ 62*35238bceSAndroid Build Coastguard Worker DE_DECLARE_POOL_HASH(TYPENAME##Hash, KEYTYPE, int); \ 63*35238bceSAndroid Build Coastguard Worker \ 64*35238bceSAndroid Build Coastguard Worker typedef struct TYPENAME_s \ 65*35238bceSAndroid Build Coastguard Worker { \ 66*35238bceSAndroid Build Coastguard Worker TYPENAME##Hash *hash; \ 67*35238bceSAndroid Build Coastguard Worker TYPENAME##Array *array; \ 68*35238bceSAndroid Build Coastguard Worker } TYPENAME; /* NOLINT(TYPENAME) */ \ 69*35238bceSAndroid Build Coastguard Worker \ 70*35238bceSAndroid Build Coastguard Worker TYPENAME *TYPENAME##_create(deMemPool *pool); \ 71*35238bceSAndroid Build Coastguard Worker bool TYPENAME##_insert(DE_PTR_TYPE(TYPENAME) hashArray, KEYTYPE key, VALUETYPE value); \ 72*35238bceSAndroid Build Coastguard Worker bool TYPENAME##_copyToArray(const TYPENAME *hashArray, DE_PTR_TYPE(KEYARRAYTYPE) keys, \ 73*35238bceSAndroid Build Coastguard Worker DE_PTR_TYPE(VALUEARRAYTYPE) values); \ 74*35238bceSAndroid Build Coastguard Worker \ 75*35238bceSAndroid Build Coastguard Worker DE_INLINE int TYPENAME##_getNumElements(const TYPENAME *hashArray) DE_UNUSED_FUNCTION; \ 76*35238bceSAndroid Build Coastguard Worker DE_INLINE VALUETYPE *TYPENAME##_find(const TYPENAME *hashArray, KEYTYPE key) DE_UNUSED_FUNCTION; \ 77*35238bceSAndroid Build Coastguard Worker DE_INLINE void TYPENAME##_reset(DE_PTR_TYPE(TYPENAME) hashArray) DE_UNUSED_FUNCTION; \ 78*35238bceSAndroid Build Coastguard Worker \ 79*35238bceSAndroid Build Coastguard Worker DE_INLINE int TYPENAME##_getNumElements(const TYPENAME *hashArray) \ 80*35238bceSAndroid Build Coastguard Worker { \ 81*35238bceSAndroid Build Coastguard Worker return TYPENAME##Array_getNumElements(hashArray->array); \ 82*35238bceSAndroid Build Coastguard Worker } \ 83*35238bceSAndroid Build Coastguard Worker \ 84*35238bceSAndroid Build Coastguard Worker DE_INLINE VALUETYPE *TYPENAME##_find(const TYPENAME *hashArray, KEYTYPE key) \ 85*35238bceSAndroid Build Coastguard Worker { \ 86*35238bceSAndroid Build Coastguard Worker int *ndxPtr = TYPENAME##Hash_find(hashArray->hash, key); \ 87*35238bceSAndroid Build Coastguard Worker if (!ndxPtr) \ 88*35238bceSAndroid Build Coastguard Worker return DE_NULL; \ 89*35238bceSAndroid Build Coastguard Worker else \ 90*35238bceSAndroid Build Coastguard Worker { \ 91*35238bceSAndroid Build Coastguard Worker int ndx = *ndxPtr; \ 92*35238bceSAndroid Build Coastguard Worker DE_ASSERT(ndx >= 0 && ndx < hashArray->array->numElements); \ 93*35238bceSAndroid Build Coastguard Worker { \ 94*35238bceSAndroid Build Coastguard Worker int pageNdx = (ndx >> DE_ARRAY_ELEMENTS_PER_PAGE_LOG2); \ 95*35238bceSAndroid Build Coastguard Worker int subNdx = ndx & ((1 << DE_ARRAY_ELEMENTS_PER_PAGE_LOG2) - 1); \ 96*35238bceSAndroid Build Coastguard Worker return &((VALUETYPE *)hashArray->array->pageTable[pageNdx])[subNdx]; \ 97*35238bceSAndroid Build Coastguard Worker } \ 98*35238bceSAndroid Build Coastguard Worker } \ 99*35238bceSAndroid Build Coastguard Worker } \ 100*35238bceSAndroid Build Coastguard Worker \ 101*35238bceSAndroid Build Coastguard Worker DE_INLINE void TYPENAME##_reset(DE_PTR_TYPE(TYPENAME) hashArray) \ 102*35238bceSAndroid Build Coastguard Worker { \ 103*35238bceSAndroid Build Coastguard Worker TYPENAME##Hash_reset(hashArray->hash); \ 104*35238bceSAndroid Build Coastguard Worker TYPENAME##Array_reset(hashArray->array); \ 105*35238bceSAndroid Build Coastguard Worker } \ 106*35238bceSAndroid Build Coastguard Worker \ 107*35238bceSAndroid Build Coastguard Worker struct TYPENAME##Unused_s \ 108*35238bceSAndroid Build Coastguard Worker { \ 109*35238bceSAndroid Build Coastguard Worker int unused; \ 110*35238bceSAndroid Build Coastguard Worker } 111*35238bceSAndroid Build Coastguard Worker 112*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*! 113*35238bceSAndroid Build Coastguard Worker * \brief Implement a template pool hash-array class. 114*35238bceSAndroid Build Coastguard Worker * \param TYPENAME Type name of the declared hash. 115*35238bceSAndroid Build Coastguard Worker * \param KEYTYPE Type of the key. 116*35238bceSAndroid Build Coastguard Worker * \param VALUETYPE Type of the value. 117*35238bceSAndroid Build Coastguard Worker * \param KEYARRAYTYPE Type of the key array. 118*35238bceSAndroid Build Coastguard Worker * \param VALUEARRAYTYPE Type of the value array. 119*35238bceSAndroid Build Coastguard Worker * \param HASHFUNC Function used for hashing the key. 120*35238bceSAndroid Build Coastguard Worker * \param CMPFUNC Function used for exact matching of the keys. 121*35238bceSAndroid Build Coastguard Worker * 122*35238bceSAndroid Build Coastguard Worker * This macro has implements the hash declared with DE_DECLARE_POOL_HASH. 123*35238bceSAndroid Build Coastguard Worker * Usually this macro should be used from a .c file, since the macro expands 124*35238bceSAndroid Build Coastguard Worker * into multiple functions. The TYPENAME, KEYTYPE, and VALUETYPE parameters 125*35238bceSAndroid Build Coastguard Worker * must match those of the declare macro. 126*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/ 127*35238bceSAndroid Build Coastguard Worker #define DE_IMPLEMENT_POOL_HASH_ARRAY(TYPENAME, KEYTYPE, VALUETYPE, KEYARRAYTYPE, VALUEARRAYTYPE, KEYHASHFUNC, \ 128*35238bceSAndroid Build Coastguard Worker KEYCMPFUNC) \ 129*35238bceSAndroid Build Coastguard Worker \ 130*35238bceSAndroid Build Coastguard Worker DE_IMPLEMENT_POOL_HASH(TYPENAME##Hash, KEYTYPE, int, KEYHASHFUNC, KEYCMPFUNC); \ 131*35238bceSAndroid Build Coastguard Worker \ 132*35238bceSAndroid Build Coastguard Worker TYPENAME *TYPENAME##_create(deMemPool *pool) \ 133*35238bceSAndroid Build Coastguard Worker { \ 134*35238bceSAndroid Build Coastguard Worker DE_PTR_TYPE(TYPENAME) hashArray = DE_POOL_NEW(pool, TYPENAME); \ 135*35238bceSAndroid Build Coastguard Worker if (!hashArray) \ 136*35238bceSAndroid Build Coastguard Worker return DE_NULL; \ 137*35238bceSAndroid Build Coastguard Worker if ((hashArray->hash = TYPENAME##Hash_create(pool)) == DE_NULL) \ 138*35238bceSAndroid Build Coastguard Worker return DE_NULL; \ 139*35238bceSAndroid Build Coastguard Worker if ((hashArray->array = TYPENAME##Array_create(pool)) == DE_NULL) \ 140*35238bceSAndroid Build Coastguard Worker return DE_NULL; \ 141*35238bceSAndroid Build Coastguard Worker return hashArray; \ 142*35238bceSAndroid Build Coastguard Worker } \ 143*35238bceSAndroid Build Coastguard Worker \ 144*35238bceSAndroid Build Coastguard Worker bool TYPENAME##_insert(DE_PTR_TYPE(TYPENAME) hashArray, KEYTYPE key, VALUETYPE value) \ 145*35238bceSAndroid Build Coastguard Worker { \ 146*35238bceSAndroid Build Coastguard Worker int numElements = TYPENAME##Array_getNumElements(hashArray->array); \ 147*35238bceSAndroid Build Coastguard Worker DE_ASSERT(TYPENAME##Hash_getNumElements(hashArray->hash) == numElements); \ 148*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!TYPENAME##Hash_find(hashArray->hash, key)); \ 149*35238bceSAndroid Build Coastguard Worker if (!TYPENAME##Array_setSize(hashArray->array, numElements + 1) || \ 150*35238bceSAndroid Build Coastguard Worker !TYPENAME##Hash_insert(hashArray->hash, key, numElements)) \ 151*35238bceSAndroid Build Coastguard Worker return false; \ 152*35238bceSAndroid Build Coastguard Worker TYPENAME##Array_set(hashArray->array, numElements, value); \ 153*35238bceSAndroid Build Coastguard Worker return true; \ 154*35238bceSAndroid Build Coastguard Worker } \ 155*35238bceSAndroid Build Coastguard Worker \ 156*35238bceSAndroid Build Coastguard Worker bool TYPENAME##_copyToArray(const TYPENAME *hashArray, DE_PTR_TYPE(KEYARRAYTYPE) keys, \ 157*35238bceSAndroid Build Coastguard Worker DE_PTR_TYPE(VALUEARRAYTYPE) values) \ 158*35238bceSAndroid Build Coastguard Worker { \ 159*35238bceSAndroid Build Coastguard Worker int numElements = TYPENAME##Array_getNumElements(hashArray->array); \ 160*35238bceSAndroid Build Coastguard Worker TYPENAME##Hash *hash = hashArray->hash; \ 161*35238bceSAndroid Build Coastguard Worker TYPENAME##HashIter iter; \ 162*35238bceSAndroid Build Coastguard Worker DE_ASSERT(TYPENAME##Hash_getNumElements(hashArray->hash) == numElements); \ 163*35238bceSAndroid Build Coastguard Worker if ((keys && !KEYARRAYTYPE##_setSize(keys, numElements)) || \ 164*35238bceSAndroid Build Coastguard Worker (values && !VALUEARRAYTYPE##_setSize(values, numElements))) \ 165*35238bceSAndroid Build Coastguard Worker return false; \ 166*35238bceSAndroid Build Coastguard Worker for (TYPENAME##HashIter_init(hash, &iter); TYPENAME##HashIter_hasItem(&iter); TYPENAME##HashIter_next(&iter)) \ 167*35238bceSAndroid Build Coastguard Worker { \ 168*35238bceSAndroid Build Coastguard Worker KEYTYPE key = TYPENAME##HashIter_getKey(&iter); \ 169*35238bceSAndroid Build Coastguard Worker int ndx = TYPENAME##HashIter_getValue(&iter); \ 170*35238bceSAndroid Build Coastguard Worker if (keys) \ 171*35238bceSAndroid Build Coastguard Worker KEYARRAYTYPE##_set(keys, ndx, key); \ 172*35238bceSAndroid Build Coastguard Worker if (values) \ 173*35238bceSAndroid Build Coastguard Worker VALUEARRAYTYPE##_set(values, ndx, TYPENAME##Array_get(hashArray->array, ndx)); \ 174*35238bceSAndroid Build Coastguard Worker } \ 175*35238bceSAndroid Build Coastguard Worker return true; \ 176*35238bceSAndroid Build Coastguard Worker } \ 177*35238bceSAndroid Build Coastguard Worker \ 178*35238bceSAndroid Build Coastguard Worker struct TYPENAME##Unused2_s \ 179*35238bceSAndroid Build Coastguard Worker { \ 180*35238bceSAndroid Build Coastguard Worker int unused; \ 181*35238bceSAndroid Build Coastguard Worker } 182*35238bceSAndroid Build Coastguard Worker 183*35238bceSAndroid Build Coastguard Worker #endif /* _DEPOOLHASHARRAY_H */ 184