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