xref: /aosp_15_r20/external/deqp/framework/delibs/depool/dePoolHash.h (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker #ifndef _DEPOOLHASH_H
2*35238bceSAndroid Build Coastguard Worker #define _DEPOOLHASH_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 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 #include "deInt32.h"
30*35238bceSAndroid Build Coastguard Worker 
31*35238bceSAndroid Build Coastguard Worker #include <string.h> /* memset() */
32*35238bceSAndroid Build Coastguard Worker 
33*35238bceSAndroid Build Coastguard Worker enum
34*35238bceSAndroid Build Coastguard Worker {
35*35238bceSAndroid Build Coastguard Worker     DE_HASH_ELEMENTS_PER_SLOT = 4
36*35238bceSAndroid Build Coastguard Worker };
37*35238bceSAndroid Build Coastguard Worker 
38*35238bceSAndroid Build Coastguard Worker DE_BEGIN_EXTERN_C
39*35238bceSAndroid Build Coastguard Worker 
40*35238bceSAndroid Build Coastguard Worker void dePoolHash_selfTest(void);
41*35238bceSAndroid Build Coastguard Worker 
42*35238bceSAndroid Build Coastguard Worker DE_END_EXTERN_C
43*35238bceSAndroid Build Coastguard Worker 
44*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
45*35238bceSAndroid Build Coastguard Worker  * \brief Declare a template pool hash class interface.
46*35238bceSAndroid Build Coastguard Worker  * \param TYPENAME    Type name of the declared hash.
47*35238bceSAndroid Build Coastguard Worker  * \param KEYTYPE    Type of the key.
48*35238bceSAndroid Build Coastguard Worker  * \param VALUETYPE    Type of the value.
49*35238bceSAndroid Build Coastguard Worker  *
50*35238bceSAndroid Build Coastguard Worker  * This macro declares the interface for a hash. For the implementation of
51*35238bceSAndroid Build Coastguard Worker  * the hash, see DE_IMPLEMENT_POOL_HASH. Usually this macro is put into the
52*35238bceSAndroid Build Coastguard Worker  * header file and the implementation macro is put in some .c file.
53*35238bceSAndroid Build Coastguard Worker  *
54*35238bceSAndroid Build Coastguard Worker  * \todo [petri] Detailed description.
55*35238bceSAndroid Build Coastguard Worker  *
56*35238bceSAndroid Build Coastguard Worker  * The functions for operating the hash are:
57*35238bceSAndroid Build Coastguard Worker  * \todo [petri] Figure out how to comment these in Doxygen-style.
58*35238bceSAndroid Build Coastguard Worker  *
59*35238bceSAndroid Build Coastguard Worker  * \code
60*35238bceSAndroid Build Coastguard Worker  * Hash*    Hash_create            (deMemPool* pool);
61*35238bceSAndroid Build Coastguard Worker  * int      Hash_getNumElements    (const Hash* hash);
62*35238bceSAndroid Build Coastguard Worker  * Value*   Hash_find              (Hash* hash, Key key);
63*35238bceSAndroid Build Coastguard Worker  * bool   Hash_insert            (Hash* hash, Key key, Value value);
64*35238bceSAndroid Build Coastguard Worker  * void     Hash_delete            (Hash* hash, Key key);
65*35238bceSAndroid Build Coastguard Worker  * \endcode
66*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
67*35238bceSAndroid Build Coastguard Worker #define DE_DECLARE_POOL_HASH(TYPENAME, KEYTYPE, VALUETYPE)                                             \
68*35238bceSAndroid Build Coastguard Worker                                                                                                        \
69*35238bceSAndroid Build Coastguard Worker     typedef struct TYPENAME##Slot_s TYPENAME##Slot;                                                    \
70*35238bceSAndroid Build Coastguard Worker                                                                                                        \
71*35238bceSAndroid Build Coastguard Worker     struct TYPENAME##Slot_s                                                                            \
72*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
73*35238bceSAndroid Build Coastguard Worker         int numUsed;                                                                                   \
74*35238bceSAndroid Build Coastguard Worker         TYPENAME##Slot *nextSlot;                                                                      \
75*35238bceSAndroid Build Coastguard Worker         KEYTYPE keys[DE_HASH_ELEMENTS_PER_SLOT];                                                       \
76*35238bceSAndroid Build Coastguard Worker         VALUETYPE values[DE_HASH_ELEMENTS_PER_SLOT];                                                   \
77*35238bceSAndroid Build Coastguard Worker     };                                                                                                 \
78*35238bceSAndroid Build Coastguard Worker                                                                                                        \
79*35238bceSAndroid Build Coastguard Worker     typedef struct TYPENAME##_s                                                                        \
80*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
81*35238bceSAndroid Build Coastguard Worker         deMemPool *pool;                                                                               \
82*35238bceSAndroid Build Coastguard Worker         int numElements;                                                                               \
83*35238bceSAndroid Build Coastguard Worker                                                                                                        \
84*35238bceSAndroid Build Coastguard Worker         int slotTableSize;                                                                             \
85*35238bceSAndroid Build Coastguard Worker         TYPENAME##Slot **slotTable;                                                                    \
86*35238bceSAndroid Build Coastguard Worker         TYPENAME##Slot *slotFreeList;                                                                  \
87*35238bceSAndroid Build Coastguard Worker     } TYPENAME; /* NOLINT(TYPENAME) */                                                                 \
88*35238bceSAndroid Build Coastguard Worker                                                                                                        \
89*35238bceSAndroid Build Coastguard Worker     typedef struct TYPENAME##Iter_s                                                                    \
90*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
91*35238bceSAndroid Build Coastguard Worker         const TYPENAME *hash;                                                                          \
92*35238bceSAndroid Build Coastguard Worker         int curSlotIndex;                                                                              \
93*35238bceSAndroid Build Coastguard Worker         const TYPENAME##Slot *curSlot;                                                                 \
94*35238bceSAndroid Build Coastguard Worker         int curElemIndex;                                                                              \
95*35238bceSAndroid Build Coastguard Worker     } TYPENAME##Iter;                                                                                  \
96*35238bceSAndroid Build Coastguard Worker                                                                                                        \
97*35238bceSAndroid Build Coastguard Worker     TYPENAME *TYPENAME##_create(deMemPool *pool);                                                      \
98*35238bceSAndroid Build Coastguard Worker     void TYPENAME##_reset(DE_PTR_TYPE(TYPENAME) hash);                                                 \
99*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_reserve(DE_PTR_TYPE(TYPENAME) hash, int capacity);                                 \
100*35238bceSAndroid Build Coastguard Worker     VALUETYPE *TYPENAME##_find(const TYPENAME *hash, KEYTYPE key);                                     \
101*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_insert(DE_PTR_TYPE(TYPENAME) hash, KEYTYPE key, VALUETYPE value);                  \
102*35238bceSAndroid Build Coastguard Worker     void TYPENAME##_delete(DE_PTR_TYPE(TYPENAME) hash, KEYTYPE key);                                   \
103*35238bceSAndroid Build Coastguard Worker                                                                                                        \
104*35238bceSAndroid Build Coastguard Worker     DE_INLINE int TYPENAME##_getNumElements(const TYPENAME *hash) DE_UNUSED_FUNCTION;                  \
105*35238bceSAndroid Build Coastguard Worker     DE_INLINE void TYPENAME##Iter_init(const TYPENAME *hash, TYPENAME##Iter *iter) DE_UNUSED_FUNCTION; \
106*35238bceSAndroid Build Coastguard Worker     DE_INLINE bool TYPENAME##Iter_hasItem(const TYPENAME##Iter *iter) DE_UNUSED_FUNCTION;              \
107*35238bceSAndroid Build Coastguard Worker     DE_INLINE void TYPENAME##Iter_next(TYPENAME##Iter *iter) DE_UNUSED_FUNCTION;                       \
108*35238bceSAndroid Build Coastguard Worker     DE_INLINE KEYTYPE TYPENAME##Iter_getKey(const TYPENAME##Iter *iter) DE_UNUSED_FUNCTION;            \
109*35238bceSAndroid Build Coastguard Worker     DE_INLINE VALUETYPE TYPENAME##Iter_getValue(const TYPENAME##Iter *iter) DE_UNUSED_FUNCTION;        \
110*35238bceSAndroid Build Coastguard Worker                                                                                                        \
111*35238bceSAndroid Build Coastguard Worker     DE_INLINE int TYPENAME##_getNumElements(const TYPENAME *hash)                                      \
112*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
113*35238bceSAndroid Build Coastguard Worker         return hash->numElements;                                                                      \
114*35238bceSAndroid Build Coastguard Worker     }                                                                                                  \
115*35238bceSAndroid Build Coastguard Worker                                                                                                        \
116*35238bceSAndroid Build Coastguard Worker     DE_INLINE void TYPENAME##Iter_init(const TYPENAME *hash, TYPENAME##Iter *iter)                     \
117*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
118*35238bceSAndroid Build Coastguard Worker         iter->hash         = hash;                                                                     \
119*35238bceSAndroid Build Coastguard Worker         iter->curSlotIndex = 0;                                                                        \
120*35238bceSAndroid Build Coastguard Worker         iter->curSlot      = DE_NULL;                                                                  \
121*35238bceSAndroid Build Coastguard Worker         iter->curElemIndex = 0;                                                                        \
122*35238bceSAndroid Build Coastguard Worker         if (TYPENAME##_getNumElements(hash) > 0)                                                       \
123*35238bceSAndroid Build Coastguard Worker         {                                                                                              \
124*35238bceSAndroid Build Coastguard Worker             int slotTableSize = hash->slotTableSize;                                                   \
125*35238bceSAndroid Build Coastguard Worker             int slotNdx       = 0;                                                                     \
126*35238bceSAndroid Build Coastguard Worker             while (slotNdx < slotTableSize)                                                            \
127*35238bceSAndroid Build Coastguard Worker             {                                                                                          \
128*35238bceSAndroid Build Coastguard Worker                 if (hash->slotTable[slotNdx])                                                          \
129*35238bceSAndroid Build Coastguard Worker                     break;                                                                             \
130*35238bceSAndroid Build Coastguard Worker                 slotNdx++;                                                                             \
131*35238bceSAndroid Build Coastguard Worker             }                                                                                          \
132*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(slotNdx < slotTableSize);                                                        \
133*35238bceSAndroid Build Coastguard Worker             iter->curSlotIndex = slotNdx;                                                              \
134*35238bceSAndroid Build Coastguard Worker             iter->curSlot      = hash->slotTable[slotNdx];                                             \
135*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(iter->curSlot);                                                                  \
136*35238bceSAndroid Build Coastguard Worker         }                                                                                              \
137*35238bceSAndroid Build Coastguard Worker     }                                                                                                  \
138*35238bceSAndroid Build Coastguard Worker                                                                                                        \
139*35238bceSAndroid Build Coastguard Worker     DE_INLINE bool TYPENAME##Iter_hasItem(const TYPENAME##Iter *iter)                                  \
140*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
141*35238bceSAndroid Build Coastguard Worker         return (iter->curSlot != DE_NULL);                                                             \
142*35238bceSAndroid Build Coastguard Worker     }                                                                                                  \
143*35238bceSAndroid Build Coastguard Worker                                                                                                        \
144*35238bceSAndroid Build Coastguard Worker     DE_INLINE void TYPENAME##Iter_next(TYPENAME##Iter *iter)                                           \
145*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
146*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(TYPENAME##Iter_hasItem(iter));                                                       \
147*35238bceSAndroid Build Coastguard Worker         if (++iter->curElemIndex == iter->curSlot->numUsed)                                            \
148*35238bceSAndroid Build Coastguard Worker         {                                                                                              \
149*35238bceSAndroid Build Coastguard Worker             iter->curElemIndex = 0;                                                                    \
150*35238bceSAndroid Build Coastguard Worker             if (iter->curSlot->nextSlot)                                                               \
151*35238bceSAndroid Build Coastguard Worker             {                                                                                          \
152*35238bceSAndroid Build Coastguard Worker                 iter->curSlot = iter->curSlot->nextSlot;                                               \
153*35238bceSAndroid Build Coastguard Worker             }                                                                                          \
154*35238bceSAndroid Build Coastguard Worker             else                                                                                       \
155*35238bceSAndroid Build Coastguard Worker             {                                                                                          \
156*35238bceSAndroid Build Coastguard Worker                 const TYPENAME *hash = iter->hash;                                                     \
157*35238bceSAndroid Build Coastguard Worker                 int curSlotIndex     = iter->curSlotIndex;                                             \
158*35238bceSAndroid Build Coastguard Worker                 int slotTableSize    = hash->slotTableSize;                                            \
159*35238bceSAndroid Build Coastguard Worker                 while (++curSlotIndex < slotTableSize)                                                 \
160*35238bceSAndroid Build Coastguard Worker                 {                                                                                      \
161*35238bceSAndroid Build Coastguard Worker                     if (hash->slotTable[curSlotIndex])                                                 \
162*35238bceSAndroid Build Coastguard Worker                         break;                                                                         \
163*35238bceSAndroid Build Coastguard Worker                 }                                                                                      \
164*35238bceSAndroid Build Coastguard Worker                 iter->curSlotIndex = curSlotIndex;                                                     \
165*35238bceSAndroid Build Coastguard Worker                 if (curSlotIndex < slotTableSize)                                                      \
166*35238bceSAndroid Build Coastguard Worker                     iter->curSlot = hash->slotTable[curSlotIndex];                                     \
167*35238bceSAndroid Build Coastguard Worker                 else                                                                                   \
168*35238bceSAndroid Build Coastguard Worker                     iter->curSlot = DE_NULL;                                                           \
169*35238bceSAndroid Build Coastguard Worker             }                                                                                          \
170*35238bceSAndroid Build Coastguard Worker         }                                                                                              \
171*35238bceSAndroid Build Coastguard Worker     }                                                                                                  \
172*35238bceSAndroid Build Coastguard Worker                                                                                                        \
173*35238bceSAndroid Build Coastguard Worker     DE_INLINE KEYTYPE TYPENAME##Iter_getKey(const TYPENAME##Iter *iter)                                \
174*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
175*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(TYPENAME##Iter_hasItem(iter));                                                       \
176*35238bceSAndroid Build Coastguard Worker         return iter->curSlot->keys[iter->curElemIndex];                                                \
177*35238bceSAndroid Build Coastguard Worker     }                                                                                                  \
178*35238bceSAndroid Build Coastguard Worker                                                                                                        \
179*35238bceSAndroid Build Coastguard Worker     DE_INLINE VALUETYPE TYPENAME##Iter_getValue(const TYPENAME##Iter *iter)                            \
180*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
181*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(TYPENAME##Iter_hasItem(iter));                                                       \
182*35238bceSAndroid Build Coastguard Worker         return iter->curSlot->values[iter->curElemIndex];                                              \
183*35238bceSAndroid Build Coastguard Worker     }                                                                                                  \
184*35238bceSAndroid Build Coastguard Worker                                                                                                        \
185*35238bceSAndroid Build Coastguard Worker     struct TYPENAME##Unused_s                                                                          \
186*35238bceSAndroid Build Coastguard Worker     {                                                                                                  \
187*35238bceSAndroid Build Coastguard Worker         int unused;                                                                                    \
188*35238bceSAndroid Build Coastguard Worker     }
189*35238bceSAndroid Build Coastguard Worker 
190*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
191*35238bceSAndroid Build Coastguard Worker  * \brief Implement a template pool hash class.
192*35238bceSAndroid Build Coastguard Worker  * \param TYPENAME    Type name of the declared hash.
193*35238bceSAndroid Build Coastguard Worker  * \param KEYTYPE    Type of the key.
194*35238bceSAndroid Build Coastguard Worker  * \param VALUETYPE    Type of the value.
195*35238bceSAndroid Build Coastguard Worker  * \param HASHFUNC    Function used for hashing the key.
196*35238bceSAndroid Build Coastguard Worker  * \param CMPFUNC    Function used for exact matching of the keys.
197*35238bceSAndroid Build Coastguard Worker  *
198*35238bceSAndroid Build Coastguard Worker  * This macro has implements the hash declared with DE_DECLARE_POOL_HASH.
199*35238bceSAndroid Build Coastguard Worker  * Usually this macro should be used from a .c file, since the macro expands
200*35238bceSAndroid Build Coastguard Worker  * into multiple functions. The TYPENAME, KEYTYPE, and VALUETYPE parameters
201*35238bceSAndroid Build Coastguard Worker  * must match those of the declare macro.
202*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
203*35238bceSAndroid Build Coastguard Worker #define DE_IMPLEMENT_POOL_HASH(TYPENAME, KEYTYPE, VALUETYPE, HASHFUNC, CMPFUNC)                                       \
204*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
205*35238bceSAndroid Build Coastguard Worker     TYPENAME *TYPENAME##_create(deMemPool *pool)                                                                      \
206*35238bceSAndroid Build Coastguard Worker     {                                                                                                                 \
207*35238bceSAndroid Build Coastguard Worker         /* Alloc struct. */                                                                                           \
208*35238bceSAndroid Build Coastguard Worker         DE_PTR_TYPE(TYPENAME) hash = DE_POOL_NEW(pool, TYPENAME);                                                     \
209*35238bceSAndroid Build Coastguard Worker         if (!hash)                                                                                                    \
210*35238bceSAndroid Build Coastguard Worker             return DE_NULL;                                                                                           \
211*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
212*35238bceSAndroid Build Coastguard Worker         memset(hash, 0, sizeof(TYPENAME));                                                                            \
213*35238bceSAndroid Build Coastguard Worker         hash->pool = pool;                                                                                            \
214*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
215*35238bceSAndroid Build Coastguard Worker         return hash;                                                                                                  \
216*35238bceSAndroid Build Coastguard Worker     }                                                                                                                 \
217*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
218*35238bceSAndroid Build Coastguard Worker     void TYPENAME##_reset(DE_PTR_TYPE(TYPENAME) hash)                                                                 \
219*35238bceSAndroid Build Coastguard Worker     {                                                                                                                 \
220*35238bceSAndroid Build Coastguard Worker         int slotNdx;                                                                                                  \
221*35238bceSAndroid Build Coastguard Worker         for (slotNdx = 0; slotNdx < hash->slotTableSize; slotNdx++)                                                   \
222*35238bceSAndroid Build Coastguard Worker         {                                                                                                             \
223*35238bceSAndroid Build Coastguard Worker             TYPENAME##Slot *slot = hash->slotTable[slotNdx];                                                          \
224*35238bceSAndroid Build Coastguard Worker             while (slot)                                                                                              \
225*35238bceSAndroid Build Coastguard Worker             {                                                                                                         \
226*35238bceSAndroid Build Coastguard Worker                 TYPENAME##Slot *nextSlot = slot->nextSlot;                                                            \
227*35238bceSAndroid Build Coastguard Worker                 slot->nextSlot           = hash->slotFreeList;                                                        \
228*35238bceSAndroid Build Coastguard Worker                 hash->slotFreeList       = slot;                                                                      \
229*35238bceSAndroid Build Coastguard Worker                 slot->numUsed            = 0;                                                                         \
230*35238bceSAndroid Build Coastguard Worker                 slot                     = nextSlot;                                                                  \
231*35238bceSAndroid Build Coastguard Worker             }                                                                                                         \
232*35238bceSAndroid Build Coastguard Worker             hash->slotTable[slotNdx] = DE_NULL;                                                                       \
233*35238bceSAndroid Build Coastguard Worker         }                                                                                                             \
234*35238bceSAndroid Build Coastguard Worker         hash->numElements = 0;                                                                                        \
235*35238bceSAndroid Build Coastguard Worker     }                                                                                                                 \
236*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
237*35238bceSAndroid Build Coastguard Worker     TYPENAME##Slot *TYPENAME##_allocSlot(DE_PTR_TYPE(TYPENAME) hash)                                                  \
238*35238bceSAndroid Build Coastguard Worker     {                                                                                                                 \
239*35238bceSAndroid Build Coastguard Worker         TYPENAME##Slot *slot;                                                                                         \
240*35238bceSAndroid Build Coastguard Worker         if (hash->slotFreeList)                                                                                       \
241*35238bceSAndroid Build Coastguard Worker         {                                                                                                             \
242*35238bceSAndroid Build Coastguard Worker             slot               = hash->slotFreeList;                                                                  \
243*35238bceSAndroid Build Coastguard Worker             hash->slotFreeList = hash->slotFreeList->nextSlot;                                                        \
244*35238bceSAndroid Build Coastguard Worker         }                                                                                                             \
245*35238bceSAndroid Build Coastguard Worker         else                                                                                                          \
246*35238bceSAndroid Build Coastguard Worker             slot = (TYPENAME##Slot *)deMemPool_alloc(hash->pool, sizeof(TYPENAME##Slot) * DE_HASH_ELEMENTS_PER_SLOT); \
247*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
248*35238bceSAndroid Build Coastguard Worker         if (slot)                                                                                                     \
249*35238bceSAndroid Build Coastguard Worker         {                                                                                                             \
250*35238bceSAndroid Build Coastguard Worker             slot->nextSlot = DE_NULL;                                                                                 \
251*35238bceSAndroid Build Coastguard Worker             slot->numUsed  = 0;                                                                                       \
252*35238bceSAndroid Build Coastguard Worker         }                                                                                                             \
253*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
254*35238bceSAndroid Build Coastguard Worker         return slot;                                                                                                  \
255*35238bceSAndroid Build Coastguard Worker     }                                                                                                                 \
256*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
257*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_rehash(DE_PTR_TYPE(TYPENAME) hash, int newSlotTableSize)                                          \
258*35238bceSAndroid Build Coastguard Worker     {                                                                                                                 \
259*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(deIsPowerOfTwo32(newSlotTableSize) && newSlotTableSize > 0);                                        \
260*35238bceSAndroid Build Coastguard Worker         if (newSlotTableSize > hash->slotTableSize)                                                                   \
261*35238bceSAndroid Build Coastguard Worker         {                                                                                                             \
262*35238bceSAndroid Build Coastguard Worker             TYPENAME##Slot **oldSlotTable = hash->slotTable;                                                          \
263*35238bceSAndroid Build Coastguard Worker             TYPENAME##Slot **newSlotTable =                                                                           \
264*35238bceSAndroid Build Coastguard Worker                 (TYPENAME##Slot **)deMemPool_alloc(hash->pool, sizeof(TYPENAME##Slot *) * (size_t)newSlotTableSize);  \
265*35238bceSAndroid Build Coastguard Worker             int oldSlotTableSize = hash->slotTableSize;                                                               \
266*35238bceSAndroid Build Coastguard Worker             int slotNdx;                                                                                              \
267*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
268*35238bceSAndroid Build Coastguard Worker             if (!newSlotTable)                                                                                        \
269*35238bceSAndroid Build Coastguard Worker                 return false;                                                                                         \
270*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
271*35238bceSAndroid Build Coastguard Worker             for (slotNdx = 0; slotNdx < oldSlotTableSize; slotNdx++)                                                  \
272*35238bceSAndroid Build Coastguard Worker                 newSlotTable[slotNdx] = oldSlotTable[slotNdx];                                                        \
273*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
274*35238bceSAndroid Build Coastguard Worker             for (slotNdx = oldSlotTableSize; slotNdx < newSlotTableSize; slotNdx++)                                   \
275*35238bceSAndroid Build Coastguard Worker                 newSlotTable[slotNdx] = DE_NULL;                                                                      \
276*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
277*35238bceSAndroid Build Coastguard Worker             hash->slotTableSize = newSlotTableSize;                                                                   \
278*35238bceSAndroid Build Coastguard Worker             hash->slotTable     = newSlotTable;                                                                       \
279*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
280*35238bceSAndroid Build Coastguard Worker             for (slotNdx = 0; slotNdx < oldSlotTableSize; slotNdx++)                                                  \
281*35238bceSAndroid Build Coastguard Worker             {                                                                                                         \
282*35238bceSAndroid Build Coastguard Worker                 TYPENAME##Slot *slot  = oldSlotTable[slotNdx];                                                        \
283*35238bceSAndroid Build Coastguard Worker                 newSlotTable[slotNdx] = DE_NULL;                                                                      \
284*35238bceSAndroid Build Coastguard Worker                 while (slot)                                                                                          \
285*35238bceSAndroid Build Coastguard Worker                 {                                                                                                     \
286*35238bceSAndroid Build Coastguard Worker                     int elemNdx;                                                                                      \
287*35238bceSAndroid Build Coastguard Worker                     for (elemNdx = 0; elemNdx < slot->numUsed; elemNdx++)                                             \
288*35238bceSAndroid Build Coastguard Worker                     {                                                                                                 \
289*35238bceSAndroid Build Coastguard Worker                         hash->numElements--;                                                                          \
290*35238bceSAndroid Build Coastguard Worker                         if (!TYPENAME##_insert(hash, slot->keys[elemNdx], slot->values[elemNdx]))                     \
291*35238bceSAndroid Build Coastguard Worker                             return false;                                                                             \
292*35238bceSAndroid Build Coastguard Worker                     }                                                                                                 \
293*35238bceSAndroid Build Coastguard Worker                     slot = slot->nextSlot;                                                                            \
294*35238bceSAndroid Build Coastguard Worker                 }                                                                                                     \
295*35238bceSAndroid Build Coastguard Worker             }                                                                                                         \
296*35238bceSAndroid Build Coastguard Worker         }                                                                                                             \
297*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
298*35238bceSAndroid Build Coastguard Worker         return true;                                                                                                  \
299*35238bceSAndroid Build Coastguard Worker     }                                                                                                                 \
300*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
301*35238bceSAndroid Build Coastguard Worker     VALUETYPE *TYPENAME##_find(const TYPENAME *hash, KEYTYPE key)                                                     \
302*35238bceSAndroid Build Coastguard Worker     {                                                                                                                 \
303*35238bceSAndroid Build Coastguard Worker         if (hash->numElements > 0)                                                                                    \
304*35238bceSAndroid Build Coastguard Worker         {                                                                                                             \
305*35238bceSAndroid Build Coastguard Worker             int slotNdx          = (int)(HASHFUNC(key) & (uint32_t)(hash->slotTableSize - 1));                        \
306*35238bceSAndroid Build Coastguard Worker             TYPENAME##Slot *slot = hash->slotTable[slotNdx];                                                          \
307*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(deInBounds32(slotNdx, 0, hash->slotTableSize));                                                 \
308*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
309*35238bceSAndroid Build Coastguard Worker             while (slot)                                                                                              \
310*35238bceSAndroid Build Coastguard Worker             {                                                                                                         \
311*35238bceSAndroid Build Coastguard Worker                 int elemNdx;                                                                                          \
312*35238bceSAndroid Build Coastguard Worker                 for (elemNdx = 0; elemNdx < slot->numUsed; elemNdx++)                                                 \
313*35238bceSAndroid Build Coastguard Worker                 {                                                                                                     \
314*35238bceSAndroid Build Coastguard Worker                     if (CMPFUNC(slot->keys[elemNdx], key))                                                            \
315*35238bceSAndroid Build Coastguard Worker                         return &slot->values[elemNdx];                                                                \
316*35238bceSAndroid Build Coastguard Worker                 }                                                                                                     \
317*35238bceSAndroid Build Coastguard Worker                 slot = slot->nextSlot;                                                                                \
318*35238bceSAndroid Build Coastguard Worker             }                                                                                                         \
319*35238bceSAndroid Build Coastguard Worker         }                                                                                                             \
320*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
321*35238bceSAndroid Build Coastguard Worker         return DE_NULL;                                                                                               \
322*35238bceSAndroid Build Coastguard Worker     }                                                                                                                 \
323*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
324*35238bceSAndroid Build Coastguard Worker     bool TYPENAME##_insert(DE_PTR_TYPE(TYPENAME) hash, KEYTYPE key, VALUETYPE value)                                  \
325*35238bceSAndroid Build Coastguard Worker     {                                                                                                                 \
326*35238bceSAndroid Build Coastguard Worker         int slotNdx;                                                                                                  \
327*35238bceSAndroid Build Coastguard Worker         TYPENAME##Slot *slot;                                                                                         \
328*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
329*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(!TYPENAME##_find(hash, key));                                                                       \
330*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
331*35238bceSAndroid Build Coastguard Worker         if ((hash->numElements + 1) >= hash->slotTableSize * DE_HASH_ELEMENTS_PER_SLOT)                               \
332*35238bceSAndroid Build Coastguard Worker             if (!TYPENAME##_rehash(hash, deMax32(4, 2 * hash->slotTableSize)))                                        \
333*35238bceSAndroid Build Coastguard Worker                 return false;                                                                                         \
334*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
335*35238bceSAndroid Build Coastguard Worker         slotNdx = (int)(HASHFUNC(key) & (uint32_t)(hash->slotTableSize - 1));                                         \
336*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(slotNdx >= 0 && slotNdx < hash->slotTableSize);                                                     \
337*35238bceSAndroid Build Coastguard Worker         slot = hash->slotTable[slotNdx];                                                                              \
338*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
339*35238bceSAndroid Build Coastguard Worker         if (!slot)                                                                                                    \
340*35238bceSAndroid Build Coastguard Worker         {                                                                                                             \
341*35238bceSAndroid Build Coastguard Worker             slot = TYPENAME##_allocSlot(hash);                                                                        \
342*35238bceSAndroid Build Coastguard Worker             if (!slot)                                                                                                \
343*35238bceSAndroid Build Coastguard Worker                 return false;                                                                                         \
344*35238bceSAndroid Build Coastguard Worker             hash->slotTable[slotNdx] = slot;                                                                          \
345*35238bceSAndroid Build Coastguard Worker         }                                                                                                             \
346*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
347*35238bceSAndroid Build Coastguard Worker         for (;;)                                                                                                      \
348*35238bceSAndroid Build Coastguard Worker         {                                                                                                             \
349*35238bceSAndroid Build Coastguard Worker             if (slot->numUsed == DE_HASH_ELEMENTS_PER_SLOT)                                                           \
350*35238bceSAndroid Build Coastguard Worker             {                                                                                                         \
351*35238bceSAndroid Build Coastguard Worker                 if (slot->nextSlot)                                                                                   \
352*35238bceSAndroid Build Coastguard Worker                     slot = slot->nextSlot;                                                                            \
353*35238bceSAndroid Build Coastguard Worker                 else                                                                                                  \
354*35238bceSAndroid Build Coastguard Worker                 {                                                                                                     \
355*35238bceSAndroid Build Coastguard Worker                     TYPENAME##Slot *nextSlot = TYPENAME##_allocSlot(hash);                                            \
356*35238bceSAndroid Build Coastguard Worker                     if (!nextSlot)                                                                                    \
357*35238bceSAndroid Build Coastguard Worker                         return false;                                                                                 \
358*35238bceSAndroid Build Coastguard Worker                     slot->nextSlot = nextSlot;                                                                        \
359*35238bceSAndroid Build Coastguard Worker                     slot           = nextSlot;                                                                        \
360*35238bceSAndroid Build Coastguard Worker                 }                                                                                                     \
361*35238bceSAndroid Build Coastguard Worker             }                                                                                                         \
362*35238bceSAndroid Build Coastguard Worker             else                                                                                                      \
363*35238bceSAndroid Build Coastguard Worker             {                                                                                                         \
364*35238bceSAndroid Build Coastguard Worker                 slot->keys[slot->numUsed]   = key;                                                                    \
365*35238bceSAndroid Build Coastguard Worker                 slot->values[slot->numUsed] = value;                                                                  \
366*35238bceSAndroid Build Coastguard Worker                 slot->numUsed++;                                                                                      \
367*35238bceSAndroid Build Coastguard Worker                 hash->numElements++;                                                                                  \
368*35238bceSAndroid Build Coastguard Worker                 return true;                                                                                          \
369*35238bceSAndroid Build Coastguard Worker             }                                                                                                         \
370*35238bceSAndroid Build Coastguard Worker         }                                                                                                             \
371*35238bceSAndroid Build Coastguard Worker     }                                                                                                                 \
372*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
373*35238bceSAndroid Build Coastguard Worker     void TYPENAME##_delete(DE_PTR_TYPE(TYPENAME) hash, KEYTYPE key)                                                   \
374*35238bceSAndroid Build Coastguard Worker     {                                                                                                                 \
375*35238bceSAndroid Build Coastguard Worker         int slotNdx;                                                                                                  \
376*35238bceSAndroid Build Coastguard Worker         TYPENAME##Slot *slot;                                                                                         \
377*35238bceSAndroid Build Coastguard Worker         TYPENAME##Slot *prevSlot = DE_NULL;                                                                           \
378*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
379*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(hash->numElements > 0);                                                                             \
380*35238bceSAndroid Build Coastguard Worker         slotNdx = (int)(HASHFUNC(key) & (uint32_t)(hash->slotTableSize - 1));                                         \
381*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(slotNdx >= 0 && slotNdx < hash->slotTableSize);                                                     \
382*35238bceSAndroid Build Coastguard Worker         slot = hash->slotTable[slotNdx];                                                                              \
383*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(slot);                                                                                              \
384*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
385*35238bceSAndroid Build Coastguard Worker         for (;;)                                                                                                      \
386*35238bceSAndroid Build Coastguard Worker         {                                                                                                             \
387*35238bceSAndroid Build Coastguard Worker             int elemNdx;                                                                                              \
388*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(slot->numUsed > 0);                                                                             \
389*35238bceSAndroid Build Coastguard Worker             for (elemNdx = 0; elemNdx < slot->numUsed; elemNdx++)                                                     \
390*35238bceSAndroid Build Coastguard Worker             {                                                                                                         \
391*35238bceSAndroid Build Coastguard Worker                 if (CMPFUNC(slot->keys[elemNdx], key))                                                                \
392*35238bceSAndroid Build Coastguard Worker                 {                                                                                                     \
393*35238bceSAndroid Build Coastguard Worker                     TYPENAME##Slot *lastSlot = slot;                                                                  \
394*35238bceSAndroid Build Coastguard Worker                     while (lastSlot->nextSlot)                                                                        \
395*35238bceSAndroid Build Coastguard Worker                     {                                                                                                 \
396*35238bceSAndroid Build Coastguard Worker                         prevSlot = lastSlot;                                                                          \
397*35238bceSAndroid Build Coastguard Worker                         lastSlot = lastSlot->nextSlot;                                                                \
398*35238bceSAndroid Build Coastguard Worker                     }                                                                                                 \
399*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
400*35238bceSAndroid Build Coastguard Worker                     slot->keys[elemNdx]   = lastSlot->keys[lastSlot->numUsed - 1];                                    \
401*35238bceSAndroid Build Coastguard Worker                     slot->values[elemNdx] = lastSlot->values[lastSlot->numUsed - 1];                                  \
402*35238bceSAndroid Build Coastguard Worker                     lastSlot->numUsed--;                                                                              \
403*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
404*35238bceSAndroid Build Coastguard Worker                     if (lastSlot->numUsed == 0)                                                                       \
405*35238bceSAndroid Build Coastguard Worker                     {                                                                                                 \
406*35238bceSAndroid Build Coastguard Worker                         if (prevSlot)                                                                                 \
407*35238bceSAndroid Build Coastguard Worker                             prevSlot->nextSlot = DE_NULL;                                                             \
408*35238bceSAndroid Build Coastguard Worker                         else                                                                                          \
409*35238bceSAndroid Build Coastguard Worker                             hash->slotTable[slotNdx] = DE_NULL;                                                       \
410*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
411*35238bceSAndroid Build Coastguard Worker                         lastSlot->nextSlot = hash->slotFreeList;                                                      \
412*35238bceSAndroid Build Coastguard Worker                         hash->slotFreeList = lastSlot;                                                                \
413*35238bceSAndroid Build Coastguard Worker                     }                                                                                                 \
414*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
415*35238bceSAndroid Build Coastguard Worker                     hash->numElements--;                                                                              \
416*35238bceSAndroid Build Coastguard Worker                     return;                                                                                           \
417*35238bceSAndroid Build Coastguard Worker                 }                                                                                                     \
418*35238bceSAndroid Build Coastguard Worker             }                                                                                                         \
419*35238bceSAndroid Build Coastguard Worker                                                                                                                       \
420*35238bceSAndroid Build Coastguard Worker             prevSlot = slot;                                                                                          \
421*35238bceSAndroid Build Coastguard Worker             slot     = slot->nextSlot;                                                                                \
422*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(slot);                                                                                          \
423*35238bceSAndroid Build Coastguard Worker         }                                                                                                             \
424*35238bceSAndroid Build Coastguard Worker     }                                                                                                                 \
425*35238bceSAndroid Build Coastguard Worker     struct TYPENAME##Unused2_s                                                                                        \
426*35238bceSAndroid Build Coastguard Worker     {                                                                                                                 \
427*35238bceSAndroid Build Coastguard Worker         int unused;                                                                                                   \
428*35238bceSAndroid Build Coastguard Worker     }
429*35238bceSAndroid Build Coastguard Worker 
430*35238bceSAndroid Build Coastguard Worker /* Copy-to-array templates. */
431*35238bceSAndroid Build Coastguard Worker 
432*35238bceSAndroid Build Coastguard Worker #define DE_DECLARE_POOL_HASH_TO_ARRAY(HASHTYPENAME, KEYARRAYTYPENAME, VALUEARRAYTYPENAME)            \
433*35238bceSAndroid Build Coastguard Worker     bool HASHTYPENAME##_copyToArray(const HASHTYPENAME *set, DE_PTR_TYPE(KEYARRAYTYPENAME) keyArray, \
434*35238bceSAndroid Build Coastguard Worker                                     DE_PTR_TYPE(VALUEARRAYTYPENAME) valueArray);                     \
435*35238bceSAndroid Build Coastguard Worker     struct HASHTYPENAME##_##KEYARRAYTYPENAME##_##VALUEARRAYTYPENAME##_declare_unused                 \
436*35238bceSAndroid Build Coastguard Worker     {                                                                                                \
437*35238bceSAndroid Build Coastguard Worker         int unused;                                                                                  \
438*35238bceSAndroid Build Coastguard Worker     }
439*35238bceSAndroid Build Coastguard Worker 
440*35238bceSAndroid Build Coastguard Worker #define DE_IMPLEMENT_POOL_HASH_TO_ARRAY(HASHTYPENAME, KEYARRAYTYPENAME, VALUEARRAYTYPENAME)           \
441*35238bceSAndroid Build Coastguard Worker     bool HASHTYPENAME##_copyToArray(const HASHTYPENAME *hash, DE_PTR_TYPE(KEYARRAYTYPENAME) keyArray, \
442*35238bceSAndroid Build Coastguard Worker                                     DE_PTR_TYPE(VALUEARRAYTYPENAME) valueArray)                       \
443*35238bceSAndroid Build Coastguard Worker     {                                                                                                 \
444*35238bceSAndroid Build Coastguard Worker         int numElements = hash->numElements;                                                          \
445*35238bceSAndroid Build Coastguard Worker         int arrayNdx    = 0;                                                                          \
446*35238bceSAndroid Build Coastguard Worker         int slotNdx;                                                                                  \
447*35238bceSAndroid Build Coastguard Worker                                                                                                       \
448*35238bceSAndroid Build Coastguard Worker         if ((keyArray && !KEYARRAYTYPENAME##_setSize(keyArray, numElements)) ||                       \
449*35238bceSAndroid Build Coastguard Worker             (valueArray && !VALUEARRAYTYPENAME##_setSize(valueArray, numElements)))                   \
450*35238bceSAndroid Build Coastguard Worker             return false;                                                                             \
451*35238bceSAndroid Build Coastguard Worker                                                                                                       \
452*35238bceSAndroid Build Coastguard Worker         for (slotNdx = 0; slotNdx < hash->slotTableSize; slotNdx++)                                   \
453*35238bceSAndroid Build Coastguard Worker         {                                                                                             \
454*35238bceSAndroid Build Coastguard Worker             const HASHTYPENAME##Slot *slot = hash->slotTable[slotNdx];                                \
455*35238bceSAndroid Build Coastguard Worker             while (slot)                                                                              \
456*35238bceSAndroid Build Coastguard Worker             {                                                                                         \
457*35238bceSAndroid Build Coastguard Worker                 int elemNdx;                                                                          \
458*35238bceSAndroid Build Coastguard Worker                 for (elemNdx = 0; elemNdx < slot->numUsed; elemNdx++)                                 \
459*35238bceSAndroid Build Coastguard Worker                 {                                                                                     \
460*35238bceSAndroid Build Coastguard Worker                     if (keyArray)                                                                     \
461*35238bceSAndroid Build Coastguard Worker                         KEYARRAYTYPENAME##_set(keyArray, arrayNdx, slot->keys[elemNdx]);              \
462*35238bceSAndroid Build Coastguard Worker                     if (valueArray)                                                                   \
463*35238bceSAndroid Build Coastguard Worker                         VALUEARRAYTYPENAME##_set(valueArray, arrayNdx, slot->values[elemNdx]);        \
464*35238bceSAndroid Build Coastguard Worker                     arrayNdx++;                                                                       \
465*35238bceSAndroid Build Coastguard Worker                 }                                                                                     \
466*35238bceSAndroid Build Coastguard Worker                 slot = slot->nextSlot;                                                                \
467*35238bceSAndroid Build Coastguard Worker             }                                                                                         \
468*35238bceSAndroid Build Coastguard Worker         }                                                                                             \
469*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(arrayNdx == numElements);                                                           \
470*35238bceSAndroid Build Coastguard Worker         return true;                                                                                  \
471*35238bceSAndroid Build Coastguard Worker     }                                                                                                 \
472*35238bceSAndroid Build Coastguard Worker     struct HASHTYPENAME##_##KEYARRAYTYPENAME##_##VALUEARRAYTYPENAME##_implement_unused                \
473*35238bceSAndroid Build Coastguard Worker     {                                                                                                 \
474*35238bceSAndroid Build Coastguard Worker         int unused;                                                                                   \
475*35238bceSAndroid Build Coastguard Worker     }
476*35238bceSAndroid Build Coastguard Worker 
477*35238bceSAndroid Build Coastguard Worker #endif /* _DEPOOLHASH_H */
478