1*35238bceSAndroid Build Coastguard Worker #ifndef _DEPOOLHASHSET_H 2*35238bceSAndroid Build Coastguard Worker #define _DEPOOLHASHSET_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-set 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 "dePoolSet.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 dePoolHashSet_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-set (hash of sets) class interface. 38*35238bceSAndroid Build Coastguard Worker * \param TYPENAME Type name of the declared hash-set. 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 * 42*35238bceSAndroid Build Coastguard Worker * \todo [petri] Description. 43*35238bceSAndroid Build Coastguard Worker * 44*35238bceSAndroid Build Coastguard Worker * The functions for operating the hash are: 45*35238bceSAndroid Build Coastguard Worker * \todo [petri] Figure out how to comment these in Doxygen-style. 46*35238bceSAndroid Build Coastguard Worker * 47*35238bceSAndroid Build Coastguard Worker * \code 48*35238bceSAndroid Build Coastguard Worker * HashSet* HashSet_create (deMemPool* pool); 49*35238bceSAndroid Build Coastguard Worker * int HashSet_getNumElements (const HashSet* hashSet); 50*35238bceSAndroid Build Coastguard Worker * Set<Value>* HashSet_find (const HashSet* hashSet, Key key); TODO: better API 51*35238bceSAndroid Build Coastguard Worker * Hash<Set*>* HashSet_getHash (const HashSet* hashSet); TODO: better API 52*35238bceSAndroid Build Coastguard Worker * bool HashSet_insert (HashSet* hashSet, Key key, Value value); 53*35238bceSAndroid Build Coastguard Worker * void HashSet_delete (HashSet* hashSet, Key key, Value value); 54*35238bceSAndroid Build Coastguard Worker * bool HashSet_exists (const HashSet* hashSet, Key key, Value value); 55*35238bceSAndroid Build Coastguard Worker * \endcode 56*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/ 57*35238bceSAndroid Build Coastguard Worker #define DE_DECLARE_POOL_HASH_SET(TYPENAME, KEYTYPE, VALUETYPE) \ 58*35238bceSAndroid Build Coastguard Worker \ 59*35238bceSAndroid Build Coastguard Worker DE_DECLARE_POOL_SET(TYPENAME##Set, VALUETYPE); \ 60*35238bceSAndroid Build Coastguard Worker DE_DECLARE_POOL_HASH(TYPENAME##Hash, KEYTYPE, TYPENAME##Set *); \ 61*35238bceSAndroid Build Coastguard Worker typedef struct TYPENAME##_s \ 62*35238bceSAndroid Build Coastguard Worker { \ 63*35238bceSAndroid Build Coastguard Worker TYPENAME##Hash *hash; \ 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 *hashSet) DE_UNUSED_FUNCTION; \ 68*35238bceSAndroid Build Coastguard Worker DE_INLINE TYPENAME##Hash *TYPENAME##_getHash(const TYPENAME *hashSet) DE_UNUSED_FUNCTION; \ 69*35238bceSAndroid Build Coastguard Worker DE_INLINE bool TYPENAME##_insert(DE_PTR_TYPE(TYPENAME) hashSet, KEYTYPE key, VALUETYPE value) DE_UNUSED_FUNCTION; \ 70*35238bceSAndroid Build Coastguard Worker DE_INLINE bool TYPENAME##_safeInsert(DE_PTR_TYPE(TYPENAME) hashSet, KEYTYPE key, VALUETYPE value) \ 71*35238bceSAndroid Build Coastguard Worker DE_UNUSED_FUNCTION; \ 72*35238bceSAndroid Build Coastguard Worker DE_INLINE TYPENAME##Set *TYPENAME##_find(const TYPENAME *hashSet, KEYTYPE key) DE_UNUSED_FUNCTION; \ 73*35238bceSAndroid Build Coastguard Worker DE_INLINE void TYPENAME##_delete(DE_PTR_TYPE(TYPENAME) hashSet, KEYTYPE key, VALUETYPE value) DE_UNUSED_FUNCTION; \ 74*35238bceSAndroid Build Coastguard Worker DE_INLINE bool TYPENAME##_exists(const TYPENAME *hashSet, KEYTYPE key, VALUETYPE value) DE_UNUSED_FUNCTION; \ 75*35238bceSAndroid Build Coastguard Worker \ 76*35238bceSAndroid Build Coastguard Worker DE_INLINE TYPENAME *TYPENAME##_create(deMemPool *pool) \ 77*35238bceSAndroid Build Coastguard Worker { \ 78*35238bceSAndroid Build Coastguard Worker DE_PTR_TYPE(TYPENAME) hashSet = DE_POOL_NEW(pool, TYPENAME); \ 79*35238bceSAndroid Build Coastguard Worker if (!hashSet) \ 80*35238bceSAndroid Build Coastguard Worker return DE_NULL; \ 81*35238bceSAndroid Build Coastguard Worker if ((hashSet->hash = TYPENAME##Hash_create(pool)) == DE_NULL) \ 82*35238bceSAndroid Build Coastguard Worker return DE_NULL; \ 83*35238bceSAndroid Build Coastguard Worker return hashSet; \ 84*35238bceSAndroid Build Coastguard Worker } \ 85*35238bceSAndroid Build Coastguard Worker \ 86*35238bceSAndroid Build Coastguard Worker DE_INLINE int TYPENAME##_getNumElements(const TYPENAME *hashSet) \ 87*35238bceSAndroid Build Coastguard Worker { \ 88*35238bceSAndroid Build Coastguard Worker return TYPENAME##Hash_getNumElements(hashSet->hash); \ 89*35238bceSAndroid Build Coastguard Worker } \ 90*35238bceSAndroid Build Coastguard Worker \ 91*35238bceSAndroid Build Coastguard Worker DE_INLINE TYPENAME##Hash *TYPENAME##_getHash(const TYPENAME *hashSet) \ 92*35238bceSAndroid Build Coastguard Worker { \ 93*35238bceSAndroid Build Coastguard Worker return hashSet->hash; \ 94*35238bceSAndroid Build Coastguard Worker } \ 95*35238bceSAndroid Build Coastguard Worker \ 96*35238bceSAndroid Build Coastguard Worker DE_INLINE bool TYPENAME##_insert(DE_PTR_TYPE(TYPENAME) hashSet, KEYTYPE key, VALUETYPE value) \ 97*35238bceSAndroid Build Coastguard Worker { \ 98*35238bceSAndroid Build Coastguard Worker TYPENAME##Set **setPtr = TYPENAME##Hash_find(hashSet->hash, key); \ 99*35238bceSAndroid Build Coastguard Worker TYPENAME##Set *set = setPtr ? *setPtr : DE_NULL; \ 100*35238bceSAndroid Build Coastguard Worker if (!set) \ 101*35238bceSAndroid Build Coastguard Worker { \ 102*35238bceSAndroid Build Coastguard Worker set = TYPENAME##Set_create(hashSet->hash->pool); \ 103*35238bceSAndroid Build Coastguard Worker if (!set) \ 104*35238bceSAndroid Build Coastguard Worker return false; \ 105*35238bceSAndroid Build Coastguard Worker if (!TYPENAME##Set_insert(set, value)) \ 106*35238bceSAndroid Build Coastguard Worker return false; \ 107*35238bceSAndroid Build Coastguard Worker return TYPENAME##Hash_insert(hashSet->hash, key, set); \ 108*35238bceSAndroid Build Coastguard Worker } \ 109*35238bceSAndroid Build Coastguard Worker else \ 110*35238bceSAndroid Build Coastguard Worker { \ 111*35238bceSAndroid Build Coastguard Worker return TYPENAME##Set_insert(set, value); \ 112*35238bceSAndroid Build Coastguard Worker } \ 113*35238bceSAndroid Build Coastguard Worker } \ 114*35238bceSAndroid Build Coastguard Worker \ 115*35238bceSAndroid Build Coastguard Worker DE_INLINE bool TYPENAME##_safeInsert(DE_PTR_TYPE(TYPENAME) hashSet, KEYTYPE key, VALUETYPE value) \ 116*35238bceSAndroid Build Coastguard Worker { \ 117*35238bceSAndroid Build Coastguard Worker TYPENAME##Set **setPtr = TYPENAME##Hash_find(hashSet->hash, key); \ 118*35238bceSAndroid Build Coastguard Worker TYPENAME##Set *set = setPtr ? *setPtr : DE_NULL; \ 119*35238bceSAndroid Build Coastguard Worker if (!set) \ 120*35238bceSAndroid Build Coastguard Worker { \ 121*35238bceSAndroid Build Coastguard Worker return TYPENAME##_insert(hashSet, key, value); \ 122*35238bceSAndroid Build Coastguard Worker } \ 123*35238bceSAndroid Build Coastguard Worker else \ 124*35238bceSAndroid Build Coastguard Worker { \ 125*35238bceSAndroid Build Coastguard Worker return TYPENAME##Set_safeInsert(set, value); \ 126*35238bceSAndroid Build Coastguard Worker } \ 127*35238bceSAndroid Build Coastguard Worker } \ 128*35238bceSAndroid Build Coastguard Worker \ 129*35238bceSAndroid Build Coastguard Worker DE_INLINE TYPENAME##Set *TYPENAME##_find(const TYPENAME *hashSet, KEYTYPE key) \ 130*35238bceSAndroid Build Coastguard Worker { \ 131*35238bceSAndroid Build Coastguard Worker TYPENAME##Set **setPtr = TYPENAME##Hash_find(hashSet->hash, key); \ 132*35238bceSAndroid Build Coastguard Worker return setPtr ? *setPtr : DE_NULL; \ 133*35238bceSAndroid Build Coastguard Worker } \ 134*35238bceSAndroid Build Coastguard Worker \ 135*35238bceSAndroid Build Coastguard Worker DE_INLINE void TYPENAME##_delete(DE_PTR_TYPE(TYPENAME) hashSet, KEYTYPE key, VALUETYPE value) \ 136*35238bceSAndroid Build Coastguard Worker { \ 137*35238bceSAndroid Build Coastguard Worker TYPENAME##Set **setPtr = TYPENAME##Hash_find(hashSet->hash, key); \ 138*35238bceSAndroid Build Coastguard Worker TYPENAME##Set *set; \ 139*35238bceSAndroid Build Coastguard Worker DE_ASSERT(setPtr); \ 140*35238bceSAndroid Build Coastguard Worker set = *setPtr; \ 141*35238bceSAndroid Build Coastguard Worker TYPENAME##Set_delete(set, value); \ 142*35238bceSAndroid Build Coastguard Worker } \ 143*35238bceSAndroid Build Coastguard Worker \ 144*35238bceSAndroid Build Coastguard Worker DE_INLINE bool TYPENAME##_exists(const TYPENAME *hashSet, KEYTYPE key, VALUETYPE value) \ 145*35238bceSAndroid Build Coastguard Worker { \ 146*35238bceSAndroid Build Coastguard Worker TYPENAME##Set **setPtr = TYPENAME##Hash_find(hashSet->hash, key); \ 147*35238bceSAndroid Build Coastguard Worker if (setPtr) \ 148*35238bceSAndroid Build Coastguard Worker return TYPENAME##Set_exists(*setPtr, value); \ 149*35238bceSAndroid Build Coastguard Worker else \ 150*35238bceSAndroid Build Coastguard Worker return false; \ 151*35238bceSAndroid Build Coastguard Worker } \ 152*35238bceSAndroid Build Coastguard Worker \ 153*35238bceSAndroid Build Coastguard Worker struct TYPENAME##Unused_s \ 154*35238bceSAndroid Build Coastguard Worker { \ 155*35238bceSAndroid Build Coastguard Worker int unused; \ 156*35238bceSAndroid Build Coastguard Worker } 157*35238bceSAndroid Build Coastguard Worker 158*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*! 159*35238bceSAndroid Build Coastguard Worker * \brief Implement a template pool hash-set class. 160*35238bceSAndroid Build Coastguard Worker * \param TYPENAME Type name of the declared hash. 161*35238bceSAndroid Build Coastguard Worker * \param KEYTYPE Type of the key. 162*35238bceSAndroid Build Coastguard Worker * \param VALUETYPE Type of the value. 163*35238bceSAndroid Build Coastguard Worker * \param HASHFUNC Function used for hashing the key. 164*35238bceSAndroid Build Coastguard Worker * \param CMPFUNC Function used for exact matching of the keys. 165*35238bceSAndroid Build Coastguard Worker * 166*35238bceSAndroid Build Coastguard Worker * This macro has implements the hash declared with DE_DECLARE_POOL_HASH. 167*35238bceSAndroid Build Coastguard Worker * Usually this macro should be used from a .c file, since the macro expands 168*35238bceSAndroid Build Coastguard Worker * into multiple functions. The TYPENAME, KEYTYPE, and VALUETYPE parameters 169*35238bceSAndroid Build Coastguard Worker * must match those of the declare macro. 170*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/ 171*35238bceSAndroid Build Coastguard Worker #define DE_IMPLEMENT_POOL_HASH_SET(TYPENAME, KEYTYPE, VALUETYPE, KEYHASHFUNC, KEYCMPFUNC, VALUEHASHFUNC, VALUECMPFUNC) \ 172*35238bceSAndroid Build Coastguard Worker DE_IMPLEMENT_POOL_SET(TYPENAME##Set, VALUETYPE, VALUEHASHFUNC, VALUECMPFUNC); \ 173*35238bceSAndroid Build Coastguard Worker DE_IMPLEMENT_POOL_HASH(TYPENAME##Hash, KEYTYPE, TYPENAME##Set *, KEYHASHFUNC, KEYCMPFUNC); \ 174*35238bceSAndroid Build Coastguard Worker struct TYPENAME##Unused2_s \ 175*35238bceSAndroid Build Coastguard Worker { \ 176*35238bceSAndroid Build Coastguard Worker int unused; \ 177*35238bceSAndroid Build Coastguard Worker } 178*35238bceSAndroid Build Coastguard Worker 179*35238bceSAndroid Build Coastguard Worker /* Copy-to-array templates. */ 180*35238bceSAndroid Build Coastguard Worker 181*35238bceSAndroid Build Coastguard Worker #if 0 182*35238bceSAndroid Build Coastguard Worker 183*35238bceSAndroid Build Coastguard Worker #define DE_DECLARE_POOL_HASH_TO_ARRAY(HASHTYPENAME, KEYARRAYTYPENAME, VALUEARRAYTYPENAME) \ 184*35238bceSAndroid Build Coastguard Worker bool HASHTYPENAME##_copyToArray(const HASHTYPENAME *set, KEYARRAYTYPENAME *keyArray, \ 185*35238bceSAndroid Build Coastguard Worker VALUEARRAYTYPENAME *valueArray); \ 186*35238bceSAndroid Build Coastguard Worker struct HASHTYPENAME##_##KEYARRAYTYPENAME##_##VALUEARRAYTYPENAME##_declare_unused \ 187*35238bceSAndroid Build Coastguard Worker { \ 188*35238bceSAndroid Build Coastguard Worker int unused; \ 189*35238bceSAndroid Build Coastguard Worker } 190*35238bceSAndroid Build Coastguard Worker 191*35238bceSAndroid Build Coastguard Worker #define DE_IMPLEMENT_POOL_HASH_TO_ARRAY(HASHTYPENAME, KEYARRAYTYPENAME, VALUEARRAYTYPENAME) \ 192*35238bceSAndroid Build Coastguard Worker bool HASHTYPENAME##_copyToArray(const HASHTYPENAME *hash, KEYARRAYTYPENAME *keyArray, \ 193*35238bceSAndroid Build Coastguard Worker VALUEARRAYTYPENAME *valueArray) \ 194*35238bceSAndroid Build Coastguard Worker { \ 195*35238bceSAndroid Build Coastguard Worker int numElements = hash->numElements; \ 196*35238bceSAndroid Build Coastguard Worker int arrayNdx = 0; \ 197*35238bceSAndroid Build Coastguard Worker int slotNdx; \ 198*35238bceSAndroid Build Coastguard Worker \ 199*35238bceSAndroid Build Coastguard Worker if ((keyArray && !KEYARRAYTYPENAME##_setSize(keyArray, numElements)) || \ 200*35238bceSAndroid Build Coastguard Worker (valueArray && !VALUEARRAYTYPENAME##_setSize(valueArray, numElements))) \ 201*35238bceSAndroid Build Coastguard Worker return false; \ 202*35238bceSAndroid Build Coastguard Worker \ 203*35238bceSAndroid Build Coastguard Worker for (slotNdx = 0; slotNdx < hash->slotTableSize; slotNdx++) \ 204*35238bceSAndroid Build Coastguard Worker { \ 205*35238bceSAndroid Build Coastguard Worker const HASHTYPENAME##Slot *slot = hash->slotTable[slotNdx]; \ 206*35238bceSAndroid Build Coastguard Worker while (slot) \ 207*35238bceSAndroid Build Coastguard Worker { \ 208*35238bceSAndroid Build Coastguard Worker int elemNdx; \ 209*35238bceSAndroid Build Coastguard Worker for (elemNdx = 0; elemNdx < slot->numUsed; elemNdx++) \ 210*35238bceSAndroid Build Coastguard Worker { \ 211*35238bceSAndroid Build Coastguard Worker if (keyArray) \ 212*35238bceSAndroid Build Coastguard Worker KEYARRAYTYPENAME##_set(keyArray, arrayNdx, slot->keys[elemNdx]); \ 213*35238bceSAndroid Build Coastguard Worker if (valueArray) \ 214*35238bceSAndroid Build Coastguard Worker VALUEARRAYTYPENAME##_set(valueArray, arrayNdx, slot->values[elemNdx]); \ 215*35238bceSAndroid Build Coastguard Worker arrayNdx++; \ 216*35238bceSAndroid Build Coastguard Worker } \ 217*35238bceSAndroid Build Coastguard Worker slot = slot->nextSlot; \ 218*35238bceSAndroid Build Coastguard Worker } \ 219*35238bceSAndroid Build Coastguard Worker } \ 220*35238bceSAndroid Build Coastguard Worker DE_ASSERT(arrayNdx == numElements); \ 221*35238bceSAndroid Build Coastguard Worker return true; \ 222*35238bceSAndroid Build Coastguard Worker } \ 223*35238bceSAndroid Build Coastguard Worker struct HASHTYPENAME##_##KEYARRAYTYPENAME##_##VALUEARRAYTYPENAME##_implement_unused \ 224*35238bceSAndroid Build Coastguard Worker { \ 225*35238bceSAndroid Build Coastguard Worker int unused; \ 226*35238bceSAndroid Build Coastguard Worker } 227*35238bceSAndroid Build Coastguard Worker 228*35238bceSAndroid Build Coastguard Worker #endif 229*35238bceSAndroid Build Coastguard Worker 230*35238bceSAndroid Build Coastguard Worker #endif /* _DEPOOLHASHSET_H */ 231