Merge vk-gl-cts/opengl-es-cts-3.2.3 into vk-gl-cts/opengl-es-cts-3.2.4
[platform/upstream/VK-GL-CTS.git] / framework / delibs / depool / dePoolHashArray.h
1 #ifndef _DEPOOLHASHARRAY_H
2 #define _DEPOOLHASHARRAY_H
3 /*-------------------------------------------------------------------------
4  * drawElements Memory Pool Library
5  * --------------------------------
6  *
7  * Copyright 2014 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Memory pool hash-array class.
24  *//*--------------------------------------------------------------------*/
25
26 #include "deDefs.h"
27 #include "dePoolHash.h"
28 #include "dePoolArray.h"
29
30 DE_BEGIN_EXTERN_C
31
32 void    dePoolHashArray_selfTest                (void);
33
34 DE_END_EXTERN_C
35
36 /*--------------------------------------------------------------------*//*!
37  * \brief Declare a template pool hash-array (array with hash) class interface.
38  * \param TYPENAME                      Type name of the declared hash-array.
39  * \param KEYTYPE                       Type of the key.
40  * \param VALUETYPE                     Type of the value.
41  * \param KEYARRAYTYPE          Type of the key array.
42  * \param VALUEARRAYTYPE        Type of the value array.
43  *
44  * \todo [petri] Description.
45  *
46  * The functions for operating the hash are:
47  * \todo [petri] Figure out how to comment these in Doxygen-style.
48  *
49  * \todo [pyry] HashArray_find() will break if dePoolArray implementation changes.
50  *
51  * \code
52  * HashArray*  HashArray_create            (deMemPool* pool);
53  * int         HashArray_getNumElements    (const HashArray* hashArray);
54  * Value*      HashArray_find              (Hash* hashArray, Key key);
55  * deBool      HashArray_insert            (Hash* hashArray, Key key, Value value);
56  * deBool      HashArray_copyToArray       (Hash* hashArray, KeyArray* keys, ValueArray* values);
57  * \endcode
58 *//*--------------------------------------------------------------------*/
59 #define DE_DECLARE_POOL_HASH_ARRAY(TYPENAME, KEYTYPE, VALUETYPE, KEYARRAYTYPE, VALUEARRAYTYPE)          \
60                                                                                                                                                                                                         \
61 DE_DECLARE_POOL_ARRAY(TYPENAME##Array, VALUETYPE);                                                                                                      \
62 DE_DECLARE_POOL_HASH(TYPENAME##Hash, KEYTYPE, int);                                                                                                     \
63                                                                                                                                                                                                         \
64 typedef struct TYPENAME_s                                                                                                                                                       \
65 {                                                                                                                                                                                                       \
66         TYPENAME##Hash*         hash;                                                                                                                                           \
67         TYPENAME##Array*        array;                                                                                                                                          \
68 } TYPENAME; /* NOLINT(TYPENAME) */                                                                                                                                      \
69                                                                                                                                                                                                         \
70 TYPENAME*               TYPENAME##_create               (deMemPool* pool);                                                                                      \
71 deBool                  TYPENAME##_insert               (DE_PTR_TYPE(TYPENAME) hashArray, KEYTYPE key, VALUETYPE value);        \
72 deBool                  TYPENAME##_copyToArray  (const TYPENAME* hashArray, DE_PTR_TYPE(KEYARRAYTYPE) keys, DE_PTR_TYPE(VALUEARRAYTYPE) values);        \
73                                                                                                                                                                                                         \
74 DE_INLINE int                   TYPENAME##_getNumElements       (const TYPENAME* hashArray)                                     DE_UNUSED_FUNCTION;     \
75 DE_INLINE VALUETYPE*    TYPENAME##_find                         (const TYPENAME* hashArray, KEYTYPE key)        DE_UNUSED_FUNCTION;     \
76 DE_INLINE void                  TYPENAME##_reset                        (DE_PTR_TYPE(TYPENAME) hashArray)                       DE_UNUSED_FUNCTION;     \
77                                                                                                                                                                                                         \
78 DE_INLINE int TYPENAME##_getNumElements (const TYPENAME* hashArray)                                                                     \
79 {                                                                                                                                                                                                       \
80         return TYPENAME##Array_getNumElements(hashArray->array);                                                                                \
81 }                                                                                                                                                                                                       \
82                                                                                                                                                                                                         \
83 DE_INLINE VALUETYPE* TYPENAME##_find (const TYPENAME* hashArray, KEYTYPE key)                                           \
84 {                                                                                                                                                                                                       \
85         int* ndxPtr = TYPENAME##Hash_find(hashArray->hash, key);                                                                                \
86         if (!ndxPtr)                                                                                                                                                                    \
87                 return DE_NULL;                                                                                                                                                         \
88         else                                                                                                                                                                                    \
89         {                                                                                                                                                                                               \
90                 int ndx = *ndxPtr;                                                                                                                                                      \
91                 DE_ASSERT(ndx >= 0 && ndx < hashArray->array->numElements);                                                                     \
92                 {                                                                                                                                                                                       \
93                         int pageNdx     = (ndx >> DE_ARRAY_ELEMENTS_PER_PAGE_LOG2);                                                                     \
94                         int subNdx      = ndx & ((1 << DE_ARRAY_ELEMENTS_PER_PAGE_LOG2) - 1);                                           \
95                         return &((VALUETYPE*)hashArray->array->pageTable[pageNdx])[subNdx];                                             \
96                 }                                                                                                                                                                                       \
97         }                                                                                                                                                                                               \
98 }                                                                                                                                                                                                       \
99                                                                                                                                                                                                         \
100 DE_INLINE void TYPENAME##_reset (DE_PTR_TYPE(TYPENAME) hashArray)                                                                       \
101 {                                                                                                                                                                                                       \
102         TYPENAME##Hash_reset(hashArray->hash);                                                                                                                  \
103         TYPENAME##Array_reset(hashArray->array);                                                                                                                \
104 }                                                                                                                                                                                                       \
105                                                                                                                                                                                                         \
106 struct TYPENAME##Dummy_s { int dummy; }
107
108 /*--------------------------------------------------------------------*//*!
109  * \brief Implement a template pool hash-array class.
110  * \param TYPENAME                      Type name of the declared hash.
111  * \param KEYTYPE                       Type of the key.
112  * \param VALUETYPE                     Type of the value.
113  * \param KEYARRAYTYPE          Type of the key array.
114  * \param VALUEARRAYTYPE        Type of the value array.
115  * \param HASHFUNC                      Function used for hashing the key.
116  * \param CMPFUNC                       Function used for exact matching of the keys.
117  *
118  * This macro has implements the hash declared with DE_DECLARE_POOL_HASH.
119  * Usually this macro should be used from a .c file, since the macro expands
120  * into multiple functions. The TYPENAME, KEYTYPE, and VALUETYPE parameters
121  * must match those of the declare macro.
122 *//*--------------------------------------------------------------------*/
123 #define DE_IMPLEMENT_POOL_HASH_ARRAY(TYPENAME, KEYTYPE, VALUETYPE, KEYARRAYTYPE, VALUEARRAYTYPE, KEYHASHFUNC, KEYCMPFUNC)                       \
124                                                                                                                                                                                                         \
125 DE_IMPLEMENT_POOL_HASH(TYPENAME##Hash, KEYTYPE, int, KEYHASHFUNC, KEYCMPFUNC);                                          \
126                                                                                                                                                                                                         \
127 TYPENAME* TYPENAME##_create (deMemPool* pool)                                                                                                           \
128 {                                                                                                                                                                                                       \
129         DE_PTR_TYPE(TYPENAME) hashArray = DE_POOL_NEW(pool, TYPENAME);                                                                  \
130         if (!hashArray) return DE_NULL;                                                                                                                                 \
131         if ((hashArray->hash = TYPENAME##Hash_create(pool)) == DE_NULL)                                                                 \
132                 return DE_NULL;                                                                                                                                                         \
133         if ((hashArray->array = TYPENAME##Array_create(pool)) == DE_NULL)                                                               \
134                 return DE_NULL;                                                                                                                                                         \
135         return hashArray;                                                                                                                                                               \
136 }                                                                                                                                                                                                       \
137                                                                                                                                                                                                         \
138 deBool TYPENAME##_insert (DE_PTR_TYPE(TYPENAME) hashArray, KEYTYPE key, VALUETYPE value)                        \
139 {                                                                                                                                                                                                       \
140         int numElements = TYPENAME##Array_getNumElements(hashArray->array);                                                             \
141         DE_ASSERT(TYPENAME##Hash_getNumElements(hashArray->hash) == numElements);                                               \
142         DE_ASSERT(!TYPENAME##Hash_find(hashArray->hash, key));                                                                                  \
143         if (!TYPENAME##Array_setSize(hashArray->array, numElements+1) ||                                                                \
144                 !TYPENAME##Hash_insert(hashArray->hash, key, numElements))                                                                      \
145                 return DE_FALSE;                                                                                                                                                        \
146         TYPENAME##Array_set(hashArray->array, numElements, value);                                                                              \
147         return DE_TRUE;                                                                                                                                                                 \
148 }                                                                                                                                                                                                       \
149                                                                                                                                                                                                         \
150 deBool TYPENAME##_copyToArray (const TYPENAME* hashArray, DE_PTR_TYPE(KEYARRAYTYPE) keys, DE_PTR_TYPE(VALUEARRAYTYPE) values)           \
151 {                                                                                                                                                                                                       \
152         int                                     numElements     = TYPENAME##Array_getNumElements(hashArray->array);                             \
153         TYPENAME##Hash*         hash            = hashArray->hash;                                                                                              \
154         TYPENAME##HashIter      iter;                                                                                                                                           \
155         DE_ASSERT(TYPENAME##Hash_getNumElements(hashArray->hash) == numElements);                                               \
156         if ((keys && !KEYARRAYTYPE##_setSize(keys, numElements)) ||                                                                             \
157                 (values && !VALUEARRAYTYPE##_setSize(values, numElements)))                                                                     \
158                 return DE_FALSE;                                                                                                                                                        \
159         for (TYPENAME##HashIter_init(hash, &iter); TYPENAME##HashIter_hasItem(&iter); TYPENAME##HashIter_next(&iter))   \
160         {                                                                                                                                                                                               \
161                 KEYTYPE key     = TYPENAME##HashIter_getKey(&iter);                                                                                             \
162                 int             ndx     = TYPENAME##HashIter_getValue(&iter);                                                                                   \
163                 if (keys) KEYARRAYTYPE##_set(keys, ndx, key);                                                                                           \
164                 if (values) VALUEARRAYTYPE##_set(values, ndx, TYPENAME##Array_get(hashArray->array, ndx));      \
165         }                                                                                                                                                                                               \
166         return DE_TRUE;                                                                                                                                                                 \
167 }                                                                                                                                                                                                       \
168                                                                                                                                                                                                         \
169 struct TYPENAME##Dummy2_s { int dummy; }
170
171 #endif /* _DEPOOLHASHARRAY_H */