source: trunk/src/corelib/tools/qhash.cpp@ 595

Last change on this file since 595 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 52.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtCore module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qhash.h"
43
44#ifdef truncate
45#undef truncate
46#endif
47
48#include <qbitarray.h>
49#include <qstring.h>
50#include <stdlib.h>
51#ifdef QT_QHASH_DEBUG
52#include <qstring.h>
53#endif
54
55QT_BEGIN_NAMESPACE
56
57/*
58 These functions are based on Peter J. Weinberger's hash function
59 (from the Dragon Book). The constant 24 in the original function
60 was replaced with 23 to produce fewer collisions on input such as
61 "a", "aa", "aaa", "aaaa", ...
62*/
63
64static uint hash(const uchar *p, int n)
65{
66 uint h = 0;
67 uint g;
68
69 while (n--) {
70 h = (h << 4) + *p++;
71 if ((g = (h & 0xf0000000)) != 0)
72 h ^= g >> 23;
73 h &= ~g;
74 }
75 return h;
76}
77
78static uint hash(const QChar *p, int n)
79{
80 uint h = 0;
81 uint g;
82
83 while (n--) {
84 h = (h << 4) + (*p++).unicode();
85 if ((g = (h & 0xf0000000)) != 0)
86 h ^= g >> 23;
87 h &= ~g;
88 }
89 return h;
90}
91
92uint qHash(const QByteArray &key)
93{
94 return hash(reinterpret_cast<const uchar *>(key.constData()), key.size());
95}
96
97uint qHash(const QString &key)
98{
99 return hash(key.unicode(), key.size());
100}
101
102uint qHash(const QStringRef &key)
103{
104 return hash(key.unicode(), key.size());
105}
106
107uint qHash(const QBitArray &bitArray)
108{
109 int m = bitArray.d.size() - 1;
110 uint result = hash(reinterpret_cast<const uchar *>(bitArray.d.constData()), qMax(0, m));
111
112 // deal with the last 0 to 7 bits manually, because we can't trust that
113 // the padding is initialized to 0 in bitArray.d
114 int n = bitArray.size();
115 if (n & 0x7)
116 result = ((result << 4) + bitArray.d.at(m)) & ((1 << n) - 1);
117 return result;
118}
119
120/*
121 The prime_deltas array is a table of selected prime values, even
122 though it doesn't look like one. The primes we are using are 1,
123 2, 5, 11, 17, 37, 67, 131, 257, ..., i.e. primes in the immediate
124 surrounding of a power of two.
125
126 The primeForNumBits() function returns the prime associated to a
127 power of two. For example, primeForNumBits(8) returns 257.
128*/
129
130static const uchar prime_deltas[] = {
131 0, 0, 1, 3, 1, 5, 3, 3, 1, 9, 7, 5, 3, 9, 25, 3,
132 1, 21, 3, 21, 7, 15, 9, 5, 3, 29, 15, 0, 0, 0, 0, 0
133};
134
135static inline int primeForNumBits(int numBits)
136{
137 return (1 << numBits) + prime_deltas[numBits];
138}
139
140/*