Qt 4.8
Classes | Public Functions | Static Public Functions | Public Variables | Static Public Variables | List of all members
QHashData Struct Reference

#include <qhash.h>

Classes

struct  Node
 

Public Functions

void * allocateNode ()
 
void * allocateNode (int nodeAlign)
 
void destroyAndFree ()
 
QHashDatadetach_helper (void(*node_duplicate)(Node *, void *), int nodeSize)
 
QHashDatadetach_helper2 (void(*node_duplicate)(Node *, void *), void(*node_delete)(Node *), int nodeSize, int nodeAlign)
 
NodefirstNode ()
 
void free_helper (void(*node_delete)(Node *))
 
void freeNode (void *node)
 
void hasShrunk ()
 
void mightGrow ()
 
void rehash (int hint)
 
bool willGrow ()
 

Static Public Functions

static NodenextNode (Node *node)
 
static NodepreviousNode (Node *node)
 

Public Variables

Node ** buckets
 
NodefakeNext
 
int nodeSize
 
short numBits
 
int numBuckets
 
QBasicAtomicInt ref
 
uint reserved: 30
 
uint sharable: 1
 
int size
 
uint strictAlignment: 1
 
short userNumBits
 

Static Public Variables

static QHashData shared_null
 

Detailed Description

Definition at line 112 of file qhash.h.

Functions

◆ allocateNode() [1/2]

void * QHashData::allocateNode ( )

Definition at line 172 of file qhash.cpp.

Referenced by detach_helper2().

173 {
174  return allocateNode(0);
175 }
void * allocateNode()
Definition: qhash.cpp:172

◆ allocateNode() [2/2]

void * QHashData::allocateNode ( int  nodeAlign)

Definition at line 177 of file qhash.cpp.

178 {
179  void *ptr = strictAlignment ? qMallocAligned(nodeSize, nodeAlign) : qMalloc(nodeSize);
180  Q_CHECK_PTR(ptr);
181  return ptr;
182 }
Q_CORE_EXPORT void * qMallocAligned(size_t size, size_t alignment)
Definition: qmalloc.cpp:68
Q_CORE_EXPORT void * qMalloc(size_t size)
Definition: qmalloc.cpp:53
const T * ptr(const T &t)
#define Q_CHECK_PTR(p)
Definition: qglobal.h:1853
uint strictAlignment
Definition: qhash.h:128
int nodeSize
Definition: qhash.h:123

◆ destroyAndFree()

void QHashData::destroyAndFree ( )

Definition at line 395 of file qhash.cpp.

396 {
397  free_helper(0);
398 }
void free_helper(void(*node_delete)(Node *))
Definition: qhash.cpp:264

◆ detach_helper()

QHashData * QHashData::detach_helper ( void(*)(Node *, void *)  node_duplicate,
int  nodeSize 
)

Definition at line 192 of file qhash.cpp.

193 {
194  return detach_helper2( node_duplicate, 0, nodeSize, 0 );
195 }
QHashData * detach_helper2(void(*node_duplicate)(Node *, void *), void(*node_delete)(Node *), int nodeSize, int nodeAlign)
Definition: qhash.cpp:197
int nodeSize
Definition: qhash.h:123

◆ detach_helper2()

QHashData * QHashData::detach_helper2 ( void(*)(Node *, void *)  node_duplicate,
void(*)(Node *)  node_delete,
int  nodeSize,
int  nodeAlign 
)

Definition at line 197 of file qhash.cpp.

Referenced by detach_helper().

201 {
202  union {
203  QHashData *d;
204  Node *e;
205  };
206  d = new QHashData;
207  d->fakeNext = 0;
208  d->buckets = 0;
209  d->ref = 1;
210  d->size = size;
211  d->nodeSize = nodeSize;
212  d->userNumBits = userNumBits;
213  d->numBits = numBits;
214  d->numBuckets = numBuckets;
215  d->sharable = true;
216  d->strictAlignment = nodeAlign > 8;
217  d->reserved = 0;
218 
219  if (numBuckets) {
220  QT_TRY {
221  d->buckets = new Node *[numBuckets];
222  } QT_CATCH(...) {
223  // restore a consistent state for d
224  d->numBuckets = 0;
225  // roll back
226  d->free_helper(node_delete);
227  QT_RETHROW;
228  }
229 
230  Node *this_e = reinterpret_cast<Node *>(this);
231  for (int i = 0; i < numBuckets; ++i) {
232  Node **nextNode = &d->buckets[i];
233  Node *oldNode = buckets[i];
234  while (oldNode != this_e) {
235  QT_TRY {
236  Node *dup = static_cast<Node *>(allocateNode(nodeAlign));
237 
238  QT_TRY {
239  node_duplicate(oldNode, dup);
240  } QT_CATCH(...) {
241  freeNode( dup );
242  QT_RETHROW;
243  }
244 
245  dup->h = oldNode->h;
246  *nextNode = dup;
247  nextNode = &dup->next;
248  oldNode = oldNode->next;
249  } QT_CATCH(...) {
250  // restore a consistent state for d
251  *nextNode = e;
252  d->numBuckets = i+1;
253  // roll back
254  d->free_helper(node_delete);
255  QT_RETHROW;
256  }
257  }
258  *nextNode = e;
259  }
260  }
261  return d;
262 }
double d
Definition: qnumeric_p.h:62
void * allocateNode()
Definition: qhash.cpp:172
int size
Definition: qhash.h:122
short numBits
Definition: qhash.h:125
static Node * nextNode(Node *node)
Definition: qhash.cpp:285
int numBuckets
Definition: qhash.h:126
Node ** buckets
Definition: qhash.h:120
#define QT_RETHROW
Definition: qglobal.h:1539
short userNumBits
Definition: qhash.h:124
#define QT_CATCH(A)
Definition: qglobal.h:1537
void freeNode(void *node)
Definition: qhash.cpp:184
#define QT_TRY
Definition: qglobal.h:1536
int nodeSize
Definition: qhash.h:123

◆ firstNode()

QHashData::Node * QHashData::firstNode ( )
inline

Definition at line 181 of file qhash.h.

Referenced by rehash().

182 {
183  Node *e = reinterpret_cast<Node *>(this);
184  Node **bucket = buckets;
185  int n = numBuckets;
186  while (n--) {
187  if (*bucket != e)
188  return *bucket;
189  ++bucket;
190  }
191  return e;
192 }
int numBuckets
Definition: qhash.h:126
Node ** buckets
Definition: qhash.h:120

◆ free_helper()

void QHashData::free_helper ( void(*)(Node *)  node_delete)

Definition at line 264 of file qhash.cpp.

Referenced by destroyAndFree(), and QHash< QExplicitlySharedDataPointer, QHash >::freeData().

265 {
266  if (node_delete) {
267  Node *this_e = reinterpret_cast<Node *>(this);
268  Node **bucket = reinterpret_cast<Node **>(this->buckets);
269 
270  int n = numBuckets;
271  while (n--) {
272  Node *cur = *bucket++;
273  while (cur != this_e) {
274  Node *next = cur->next;
275  node_delete(cur);
276  freeNode(cur);
277  cur = next;
278  }
279  }
280  }
281  delete [] buckets;
282  delete this;
283 }
int numBuckets
Definition: qhash.h:126
Node ** buckets
Definition: qhash.h:120
void freeNode(void *node)
Definition: qhash.cpp:184

◆ freeNode()

void QHashData::freeNode ( void *  node)

Definition at line 184 of file qhash.cpp.

Referenced by detach_helper2(), and free_helper().

185 {
186  if (strictAlignment)
187  qFreeAligned(node);
188  else
189  qFree(node);
190 }
Q_CORE_EXPORT void qFree(void *ptr)
Definition: qmalloc.cpp:58
uint strictAlignment
Definition: qhash.h:128
Q_CORE_EXPORT void qFreeAligned(void *ptr)
Definition: qmalloc.cpp:118

◆ hasShrunk()

void QHashData::hasShrunk ( )
inline

Definition at line 170 of file qhash.h.

171 {
172  if (size <= (numBuckets >> 3) && numBits > userNumBits) {
173  QT_TRY {
174  rehash(qMax(int(numBits) - 2, int(userNumBits)));
175  } QT_CATCH(const std::bad_alloc &) {
176  // ignore bad allocs - shrinking shouldn't throw. rehash is exception safe.
177  }
178  }
179 }
int size
Definition: qhash.h:122
short numBits
Definition: qhash.h:125
void rehash(int hint)
Definition: qhash.cpp:349
int numBuckets
Definition: qhash.h:126
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
short userNumBits
Definition: qhash.h:124
#define QT_CATCH(A)
Definition: qglobal.h:1537
#define QT_TRY
Definition: qglobal.h:1536

◆ mightGrow()

void QHashData::mightGrow ( )
inline

Definition at line 154 of file qhash.h.

155 {
156  if (size >= numBuckets)
157  rehash(numBits + 1);
158 }
int size
Definition: qhash.h:122
short numBits
Definition: qhash.h:125
void rehash(int hint)
Definition: qhash.cpp:349
int numBuckets
Definition: qhash.h:126

◆ nextNode()

QHashData::Node * QHashData::nextNode ( Node node)
static

Definition at line 285 of file qhash.cpp.

Referenced by detach_helper2(), QHash< Key, T >::iterator::operator++(), and QHash< Key, T >::const_iterator::operator++().

286 {
287  union {
288  Node *next;
289  Node *e;
290  QHashData *d;
291  };
292  next = node->next;
293  Q_ASSERT_X(next, "QHash", "Iterating beyond end()");
294  if (next->next)
295  return next;
296 
297  int start = (node->h % d->numBuckets) + 1;
298  Node **bucket = d->buckets + start;
299  int n = d->numBuckets - start;
300  while (n--) {
301  if (*bucket != e)
302  return *bucket;
303  ++bucket;
304  }
305  return e;
306 }
double d
Definition: qnumeric_p.h:62
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837

◆ previousNode()

QHashData::Node * QHashData::previousNode ( Node node)
static

Definition at line 308 of file qhash.cpp.

Referenced by QHash< Key, T >::iterator::operator--(), and QHash< Key, T >::const_iterator::operator--().

309 {
310  union {
311  Node *e;
312  QHashData *d;
313  };
314 
315  e = node;
316  while (e->next)
317  e = e->next;
318 
319  int start;
320  if (node == e)
321  start = d->numBuckets - 1;
322  else
323  start = node->h % d->numBuckets;
324 
325  Node *sentinel = node;
326  Node **bucket = d->buckets + start;
327  while (start >= 0) {
328  if (*bucket != sentinel) {
329  Node *prev = *bucket;
330  while (prev->next != sentinel)
331  prev = prev->next;
332  return prev;
333  }
334 
335  sentinel = e;
336  --bucket;
337  --start;
338  }
339  Q_ASSERT_X(start >= 0, "QHash", "Iterating backward beyond begin()");
340  return e;
341 }
double d
Definition: qnumeric_p.h:62
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837

◆ rehash()

void QHashData::rehash ( int  hint)

Definition at line 349 of file qhash.cpp.

350 {
351  if (hint < 0) {
352  hint = countBits(-hint);
353  if (hint < MinNumBits)
354  hint = MinNumBits;
355  userNumBits = hint;
356  while (primeForNumBits(hint) < (size >> 1))
357  ++hint;
358  } else if (hint < MinNumBits) {
359  hint = MinNumBits;
360  }
361 
362  if (numBits != hint) {
363  Node *e = reinterpret_cast<Node *>(this);
364  Node **oldBuckets = buckets;
365  int oldNumBuckets = numBuckets;
366 
367  int nb = primeForNumBits(hint);
368  buckets = new Node *[nb];
369  numBits = hint;
370  numBuckets = nb;
371  for (int i = 0; i < numBuckets; ++i)
372  buckets[i] = e;
373 
374  for (int i = 0; i < oldNumBuckets; ++i) {
375  Node *firstNode = oldBuckets[i];
376  while (firstNode != e) {
377  uint h = firstNode->h;
378  Node *lastNode = firstNode;
379  while (lastNode->next != e && lastNode->next->h == h)
380  lastNode = lastNode->next;
381 
382  Node *afterLastNode = lastNode->next;
383  Node **beforeFirstNode = &buckets[h % numBuckets];
384  while (*beforeFirstNode != e)
385  beforeFirstNode = &(*beforeFirstNode)->next;
386  lastNode->next = *beforeFirstNode;
387  *beforeFirstNode = firstNode;
388  firstNode = afterLastNode;
389  }
390  }
391  delete [] oldBuckets;
392  }
393 }
Node * firstNode()
Definition: qhash.h:181
int size
Definition: qhash.h:122
short numBits
Definition: qhash.h:125
int numBuckets
Definition: qhash.h:126
Node ** buckets
Definition: qhash.h:120
static int countBits(int hint)
Definition: qhash.cpp:144
short userNumBits
Definition: qhash.h:124
unsigned int uint
Definition: qglobal.h:996
const int MinNumBits
Definition: qhash.cpp:166
static int primeForNumBits(int numBits)
Definition: qhash.cpp:135

◆ willGrow()

bool QHashData::willGrow ( )
inline

Definition at line 160 of file qhash.h.

161 {
162  if (size >= numBuckets) {
163  rehash(numBits + 1);
164  return true;
165  } else {
166  return false;
167  }
168 }
int size
Definition: qhash.h:122
short numBits
Definition: qhash.h:125
void rehash(int hint)
Definition: qhash.cpp:349
int numBuckets
Definition: qhash.h:126

Properties

◆ buckets

Node** QHashData::buckets

Definition at line 120 of file qhash.h.

Referenced by destroyAndFree(), detach_helper2(), free_helper(), and rehash().

◆ fakeNext

Node* QHashData::fakeNext

Definition at line 119 of file qhash.h.

Referenced by destroyAndFree().

◆ nodeSize

int QHashData::nodeSize

Definition at line 123 of file qhash.h.

Referenced by allocateNode(), destroyAndFree(), and detach_helper2().

◆ numBits

short QHashData::numBits

Definition at line 125 of file qhash.h.

Referenced by destroyAndFree(), detach_helper2(), and rehash().

◆ numBuckets

int QHashData::numBuckets

Definition at line 126 of file qhash.h.

Referenced by destroyAndFree(), detach_helper2(), free_helper(), and rehash().

◆ ref

QBasicAtomicInt QHashData::ref

◆ reserved

uint QHashData::reserved

Definition at line 129 of file qhash.h.

◆ sharable

uint QHashData::sharable

Definition at line 127 of file qhash.h.

◆ shared_null

QHashData QHashData::shared_null
static
Initial value:
= {
0, 0, Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, MinNumBits, 0, 0, true, false, 0
}

Definition at line 151 of file qhash.h.

Referenced by QSqlDatabase::isValid().

◆ size

int QHashData::size

Definition at line 122 of file qhash.h.

Referenced by destroyAndFree(), detach_helper2(), and rehash().

◆ strictAlignment

uint QHashData::strictAlignment

Definition at line 128 of file qhash.h.

Referenced by allocateNode(), and freeNode().

◆ userNumBits

short QHashData::userNumBits

Definition at line 124 of file qhash.h.

Referenced by destroyAndFree(), detach_helper2(), and rehash().


The documentation for this struct was generated from the following files: