Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Side by Side Diff: base/hash_tables.h

Issue 10911330: Add methods for hashing pairs of integer values. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix windows compile Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/base.gyp ('k') | base/hash_tables_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 5
6 // 6 //
7 // Deal with the differences between Microsoft and GNU implemenations 7 // Deal with the differences between Microsoft and GNU implemenations
8 // of hash_map. Allows all platforms to use |base::hash_map| and 8 // of hash_map. Allows all platforms to use |base::hash_map| and
9 // |base::hash_set|. 9 // |base::hash_set|.
10 // eg: 10 // eg:
(...skipping 13 matching lines...) Expand all
24 #include "build/build_config.h" 24 #include "build/build_config.h"
25 25
26 #include "base/string16.h" 26 #include "base/string16.h"
27 27
28 #if defined(COMPILER_MSVC) 28 #if defined(COMPILER_MSVC)
29 #include <hash_map> 29 #include <hash_map>
30 #include <hash_set> 30 #include <hash_set>
31 31
32 #define BASE_HASH_NAMESPACE stdext 32 #define BASE_HASH_NAMESPACE stdext
33 33
34 template <typename Key>
35 struct hash : public BASE_HASH_NAMESPACE::hash_compare<Key> {
36 };
37
34 #elif defined(COMPILER_GCC) 38 #elif defined(COMPILER_GCC)
35 #if defined(OS_ANDROID) 39 #if defined(OS_ANDROID)
36 #define BASE_HASH_NAMESPACE std 40 #define BASE_HASH_NAMESPACE std
37 #else 41 #else
38 #define BASE_HASH_NAMESPACE __gnu_cxx 42 #define BASE_HASH_NAMESPACE __gnu_cxx
39 #endif 43 #endif
40 44
41 // This is a hack to disable the gcc 4.4 warning about hash_map and hash_set 45 // This is a hack to disable the gcc 4.4 warning about hash_map and hash_set
42 // being deprecated. We can get rid of this when we upgrade to VS2008 and we 46 // being deprecated. We can get rid of this when we upgrade to VS2008 and we
43 // can use <tr1/unordered_map> and <tr1/unordered_set>. 47 // can use <tr1/unordered_map> and <tr1/unordered_set>.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 result = (result * 131) + *i; \ 102 result = (result * 131) + *i; \
99 return result; \ 103 return result; \
100 } \ 104 } \
101 } 105 }
102 106
103 DEFINE_STRING_HASH(std::string); 107 DEFINE_STRING_HASH(std::string);
104 DEFINE_STRING_HASH(string16); 108 DEFINE_STRING_HASH(string16);
105 109
106 #undef DEFINE_STRING_HASH 110 #undef DEFINE_STRING_HASH
107 111
112 // Implement hashing for pairs of at-most 32 bit integer values.
113 // We use randomly-generated 32-bit and 64-bit values to produce a hash code.
114 // If the hash code is 64-bit then we can be very efficient to produce a
115 // universal hash function. When size_t is 64 bits, the algorithm, as described
116 // in Section 4 of "UMAC: Fast and Secure Message Authentication" by Black,
117 // Halevi, Krawczyk, Krovetz, and Rogaway, is:
118 //
119 // h64(x32, y32) = ((x32 + rand32) % 2^32)((y32 + rand32) % 2^32) % 2^64
jar (doing other things) 2012/09/17 22:01:13 a) It appears that the second modulus operator (mo
120 //
121 // When size_t is 32 bits, we turn the 64-bit hash code above back into
122 // 32 bits by using multiply-add hashing. This algorithm, as described in
123 // Theorem 6 of "Efficient Strongly Universal and Optimally Universal Hashing"
124 // by Woelfel, is:
125 //
126 // h32(x32, y32) = (h64(x32, y32) * randOdd64 + rand32 * 2^32) % 2^64 / 2^32
jar (doing other things) 2012/09/17 22:01:13 Here, the addition of rand32 * 2^32 is useless, fo
127
128 #define DEFINE_32BIT_PAIR_HASH(type1, type2) \
129 template<> \
130 struct hash<std::pair<type1, type2> > { \
131 std::size_t operator()(std::pair<type1, type2> value) const { \
132 uint32 shortRandom1 = 698340900U; \
133 uint32 shortRandom2 = 2638093458U; \
134 \
135 uint32 sum1 = value.first + shortRandom1; \
136 uint32 sum2 = value.second + shortRandom2; \
137 uint64 hash64 = static_cast<uint64>(sum1) * sum2; \
138 \
139 if (sizeof(std::size_t) >= sizeof(uint64)) \
140 return static_cast<std::size_t>(hash64); \
141 \
142 uint64 longRandom1 = 885644242649267641LL; \
143 uint64 longRandom2 = 1614045628LL << 32; \
144 \
145 hash64 = hash64 * longRandom1 + longRandom2; \
146 std::size_t highBits = static_cast<std::size_t>( \
147 hash64 >> (sizeof(uint64) - sizeof(std::size_t))); \
148 return highBits; \
149 } \
150 \
151 size_t operator()(const std::pair<type1, type2>& a, \
152 const std::pair<type1, type2>& b) const { \
153 return a < b; \
154 } \
155 }; \
156
157 DEFINE_32BIT_PAIR_HASH(short, short);
158 DEFINE_32BIT_PAIR_HASH(short, unsigned short);
159 DEFINE_32BIT_PAIR_HASH(short, int);
160 DEFINE_32BIT_PAIR_HASH(short, unsigned);
161 DEFINE_32BIT_PAIR_HASH(unsigned short, short);
162 DEFINE_32BIT_PAIR_HASH(unsigned short, unsigned short);
163 DEFINE_32BIT_PAIR_HASH(unsigned short, int);
164 DEFINE_32BIT_PAIR_HASH(unsigned short, unsigned);
165 DEFINE_32BIT_PAIR_HASH(int, short);
166 DEFINE_32BIT_PAIR_HASH(int, unsigned short);
167 DEFINE_32BIT_PAIR_HASH(int, int);
168 DEFINE_32BIT_PAIR_HASH(int, unsigned);
169 DEFINE_32BIT_PAIR_HASH(unsigned, short);
170 DEFINE_32BIT_PAIR_HASH(unsigned, unsigned short);
171 DEFINE_32BIT_PAIR_HASH(unsigned, int);
172 DEFINE_32BIT_PAIR_HASH(unsigned, unsigned);
173
174 #undef DEFINE_32BIT_PAIR_HASH
175
176 // Implement hashing for pairs of up-to 64-bit integer values.
177 // We use the above algorithms for 32-bit integers, but treat each 64-bit
178 // value as 2 32-bit values.
179
180 #define DEFINE_64BIT_PAIR_HASH(type1, type2) \
181 template<> \
182 struct hash<std::pair<type1, type2> > { \
183 std::size_t operator()(std::pair<type1, type2> value) const { \
184 uint32 shortRandom1 = 673537332U; \
185 uint32 shortRandom2 = 2309950629U; \
186 uint32 shortRandom3 = 29379286U; \
187 uint32 shortRandom4 = 2611985739U; \
188 \
189 uint64 value1 = value.first; \
190 uint64 value2 = value.second; \
191 uint32 value1a = static_cast<uint32>(value1 & 0xffffffff); \
192 uint32 value1b = static_cast<uint32>((value1 >> 32) & 0xffffffff); \
193 uint32 value2a = static_cast<uint32>(value2 & 0xffffffff); \
194 uint32 value2b = static_cast<uint32>((value2 >> 32) & 0xffffffff); \
195 \
196 uint32 sum1 = value1a + shortRandom1; \
197 uint32 sum2 = value1b + shortRandom2; \
198 uint32 sum3 = value2a + shortRandom3; \
199 uint32 sum4 = value2b + shortRandom4; \
200 uint64 hash64 = static_cast<uint64>(sum1) * sum2 + \
201 static_cast<uint64>(sum3) * sum4; \
202 \
203 if (sizeof(std::size_t) >= sizeof(uint64)) \
204 return static_cast<std::size_t>(hash64); \
205 \
206 uint64 longRandom1 = 629146275505555501LL; \
207 uint64 longRandom2 = 45557137LL << 32; \
208 \
209 hash64 = hash64 * longRandom1 + longRandom2; \
210 std::size_t highBits = static_cast<std::size_t>( \
211 hash64 >> (sizeof(uint64) - sizeof(std::size_t))); \
212 return highBits; \
213 } \
214 size_t operator()(const std::pair<type1, type2>& a, \
215 const std::pair<type1, type2>& b) const { \
216 return a < b; \
217 } \
218 };
219
220 DEFINE_64BIT_PAIR_HASH(short, int64);
221 DEFINE_64BIT_PAIR_HASH(short, uint64);
222 DEFINE_64BIT_PAIR_HASH(unsigned short, int64);
223 DEFINE_64BIT_PAIR_HASH(unsigned short, uint64);
224 DEFINE_64BIT_PAIR_HASH(int, int64);
225 DEFINE_64BIT_PAIR_HASH(int, uint64);
226 DEFINE_64BIT_PAIR_HASH(unsigned, int64);
227 DEFINE_64BIT_PAIR_HASH(unsigned, uint64);
228 DEFINE_64BIT_PAIR_HASH(int64, short);
229 DEFINE_64BIT_PAIR_HASH(int64, unsigned short);
230 DEFINE_64BIT_PAIR_HASH(int64, int);
231 DEFINE_64BIT_PAIR_HASH(int64, unsigned);
232 DEFINE_64BIT_PAIR_HASH(int64, int64);
233 DEFINE_64BIT_PAIR_HASH(int64, uint64);
234 DEFINE_64BIT_PAIR_HASH(uint64, short);
235 DEFINE_64BIT_PAIR_HASH(uint64, unsigned short);
236 DEFINE_64BIT_PAIR_HASH(uint64, int);
237 DEFINE_64BIT_PAIR_HASH(uint64, unsigned);
238 DEFINE_64BIT_PAIR_HASH(uint64, int64);
239 DEFINE_64BIT_PAIR_HASH(uint64, uint64);
240
241 #undef DEFINE_64BIT_PAIR_HASH
242
108 } // namespace BASE_HASH_NAMESPACE 243 } // namespace BASE_HASH_NAMESPACE
109 244
110 #else // COMPILER 245 #else // COMPILER
111 #error define BASE_HASH_NAMESPACE for your compiler 246 #error define BASE_HASH_NAMESPACE for your compiler
112 #endif // COMPILER 247 #endif // COMPILER
113 248
114 namespace base { 249 namespace base {
115 using BASE_HASH_NAMESPACE::hash_map; 250 using BASE_HASH_NAMESPACE::hash_map;
116 using BASE_HASH_NAMESPACE::hash_set; 251 using BASE_HASH_NAMESPACE::hash_set;
117 } 252 }
118 253
119 #endif // BASE_HASH_TABLES_H_ 254 #endif // BASE_HASH_TABLES_H_
OLDNEW
« no previous file with comments | « base/base.gyp ('k') | base/hash_tables_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698