src/corelib/tools/qhash.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
child 7 f7bc934e204c
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
   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 );
   260         while (n--) {
   271         while (n--) {
   261             Node *cur = *bucket++;
   272             Node *cur = *bucket++;
   262             while (cur != this_e) {
   273             while (cur != this_e) {
   263                 Node *next = cur->next;
   274                 Node *next = cur->next;
   264                 node_delete(cur);
   275                 node_delete(cur);
       
   276                 freeNode(cur);
   265                 cur = next;
   277                 cur = next;
   266             }
   278             }
   267         }
   279         }
   268     }
   280     }
   269     delete [] buckets;
   281     delete [] buckets;