164 example, if MinNumBits is 4, it has 17 buckets. |
164 example, if MinNumBits is 4, it has 17 buckets. |
165 */ |
165 */ |
166 const int MinNumBits = 4; |
166 const int MinNumBits = 4; |
167 |
167 |
168 QHashData QHashData::shared_null = { |
168 QHashData QHashData::shared_null = { |
169 0, 0, Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, MinNumBits, 0, 0, true |
169 0, 0, Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, MinNumBits, 0, 0, true, false, 0 |
170 }; |
170 }; |
171 |
171 |
172 void *QHashData::allocateNode() |
172 void *QHashData::allocateNode() |
173 { |
173 { |
174 void *ptr = qMalloc(nodeSize); |
174 return allocateNode(0); |
|
175 } |
|
176 |
|
177 void *QHashData::allocateNode(int nodeAlign) |
|
178 { |
|
179 void *ptr = strictAlignment ? qMallocAligned(nodeSize, nodeAlign) : qMalloc(nodeSize); |
175 Q_CHECK_PTR(ptr); |
180 Q_CHECK_PTR(ptr); |
176 return ptr; |
181 return ptr; |
177 } |
182 } |
178 |
183 |
179 void QHashData::freeNode(void *node) |
184 void QHashData::freeNode(void *node) |
180 { |
185 { |
181 qFree(node); |
186 if (strictAlignment) |
|
187 qFreeAligned(node); |
|
188 else |
|
189 qFree(node); |
182 } |
190 } |
183 |
191 |
184 QHashData *QHashData::detach_helper(void (*node_duplicate)(Node *, void *), int nodeSize) |
192 QHashData *QHashData::detach_helper(void (*node_duplicate)(Node *, void *), int nodeSize) |
185 { |
193 { |
186 return detach_helper( node_duplicate, 0, nodeSize ); |
194 return detach_helper2( node_duplicate, 0, nodeSize, 0 ); |
187 } |
195 } |
188 |
196 |
189 QHashData *QHashData::detach_helper(void (*node_duplicate)(Node *, void *), |
197 QHashData *QHashData::detach_helper2(void (*node_duplicate)(Node *, void *), |
190 void (*node_delete)(Node *), |
198 void (*node_delete)(Node *), |
191 int nodeSize) |
199 int nodeSize, |
|
200 int nodeAlign) |
192 { |
201 { |
193 union { |
202 union { |
194 QHashData *d; |
203 QHashData *d; |
195 Node *e; |
204 Node *e; |
196 }; |
205 }; |
202 d->nodeSize = nodeSize; |
211 d->nodeSize = nodeSize; |
203 d->userNumBits = userNumBits; |
212 d->userNumBits = userNumBits; |
204 d->numBits = numBits; |
213 d->numBits = numBits; |
205 d->numBuckets = numBuckets; |
214 d->numBuckets = numBuckets; |
206 d->sharable = true; |
215 d->sharable = true; |
|
216 d->strictAlignment = nodeAlign > 8; |
|
217 d->reserved = 0; |
207 |
218 |
208 if (numBuckets) { |
219 if (numBuckets) { |
209 QT_TRY { |
220 QT_TRY { |
210 d->buckets = new Node *[numBuckets]; |
221 d->buckets = new Node *[numBuckets]; |
211 } QT_CATCH(...) { |
222 } QT_CATCH(...) { |
220 for (int i = 0; i < numBuckets; ++i) { |
231 for (int i = 0; i < numBuckets; ++i) { |
221 Node **nextNode = &d->buckets[i]; |
232 Node **nextNode = &d->buckets[i]; |
222 Node *oldNode = buckets[i]; |
233 Node *oldNode = buckets[i]; |
223 while (oldNode != this_e) { |
234 while (oldNode != this_e) { |
224 QT_TRY { |
235 QT_TRY { |
225 Node *dup = static_cast<Node *>(allocateNode()); |
236 Node *dup = static_cast<Node *>(allocateNode(nodeAlign)); |
226 |
237 |
227 QT_TRY { |
238 QT_TRY { |
228 node_duplicate(oldNode, dup); |
239 node_duplicate(oldNode, dup); |
229 } QT_CATCH(...) { |
240 } QT_CATCH(...) { |
230 freeNode( dup ); |
241 freeNode( dup ); |