xref: /aosp_15_r20/external/deqp/framework/delibs/depool/dePoolHashSet.h (revision 35238bce31c2a825756842865a792f8cf7f89930)
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