2 * Copyright (C) 2005, 2006, 2008, 2010 Apple Inc. All rights reserved.
3 * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
21 #ifndef WTF_StringHasher_h
22 #define WTF_StringHasher_h
24 #include <wtf/unicode/Unicode.h>
28 // Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's
29 static const unsigned stringHashingStartValue
= 0x9e3779b9U
;
31 // Paul Hsieh's SuperFastHash
32 // http://www.azillionmonkeys.com/qed/hash.html
33 // char* data is interpreted as latin-encoded (zero extended to 16 bits).
37 : m_hash(stringHashingStartValue
)
38 , m_hasPendingCharacter(false)
39 , m_pendingCharacter(0)
43 inline void addCharacters(UChar a
, UChar b
)
45 ASSERT(!m_hasPendingCharacter
);
46 addCharactersToHash(a
, b
);
49 inline void addCharacter(UChar ch
)
51 if (m_hasPendingCharacter
) {
52 addCharactersToHash(m_pendingCharacter
, ch
);
53 m_hasPendingCharacter
= false;
57 m_pendingCharacter
= ch
;
58 m_hasPendingCharacter
= true;
61 inline unsigned hash() const
63 unsigned result
= m_hash
;
66 if (m_hasPendingCharacter
) {
67 result
+= m_pendingCharacter
;
68 result
^= result
<< 11;
69 result
+= result
>> 17;
72 // Force "avalanching" of final 31 bits.
73 result
^= result
<< 3;
74 result
+= result
>> 5;
75 result
^= result
<< 2;
76 result
+= result
>> 15;
77 result
^= result
<< 10;
79 // First bit is used in UStringImpl for m_isIdentifier.
82 // This avoids ever returning a hash code of 0, since that is used to
83 // signal "hash not computed yet", using a value that is likely to be
84 // effectively the same as 0 when the low bits are masked.
91 template<typename T
, UChar
Converter(T
)> static inline unsigned computeHash(const T
* data
, unsigned length
)
94 bool rem
= length
& 1;
98 hasher
.addCharacters(Converter(data
[0]), Converter(data
[1]));
103 hasher
.addCharacter(Converter(*data
));
105 return hasher
.hash();
108 template<typename T
, UChar
Converter(T
)> static inline unsigned computeHash(const T
* data
)
113 UChar b0
= Converter(*data
++);
116 UChar b1
= Converter(*data
++);
118 hasher
.addCharacter(b0
);
122 hasher
.addCharacters(b0
, b1
);
125 return hasher
.hash();
128 template<typename T
> static inline unsigned computeHash(const T
* data
, unsigned length
)
130 return computeHash
<T
, defaultCoverter
>(data
, length
);
133 template<typename T
> static inline unsigned computeHash(const T
* data
)
135 return computeHash
<T
, defaultCoverter
>(data
);
138 template<size_t length
> static inline unsigned hashMemory(const void* data
)
140 COMPILE_ASSERT(!(length
% 4), length_must_be_a_multible_of_four
);
141 return computeHash
<UChar
>(static_cast<const UChar
*>(data
), length
/ sizeof(UChar
));
144 static inline unsigned hashMemory(const void* data
, unsigned size
)
147 return computeHash
<UChar
>(static_cast<const UChar
*>(data
), size
/ sizeof(UChar
));
151 static inline UChar
defaultCoverter(UChar ch
)
156 static inline UChar
defaultCoverter(char ch
)
158 return static_cast<unsigned char>(ch
);
161 inline void addCharactersToHash(UChar a
, UChar b
)
164 unsigned tmp
= (b
<< 11) ^ m_hash
;
165 m_hash
= (m_hash
<< 16) ^ tmp
;
166 m_hash
+= m_hash
>> 11;
170 bool m_hasPendingCharacter
;
171 UChar m_pendingCharacter
;
176 using WTF::StringHasher
;
178 #endif // WTF_StringHasher_h