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

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: compiles at last 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 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 DEFINE_STRING_HASH(string16); 104 DEFINE_STRING_HASH(string16);
105 105
106 #undef DEFINE_STRING_HASH 106 #undef DEFINE_STRING_HASH
107 107
108 } // namespace BASE_HASH_NAMESPACE 108 } // namespace BASE_HASH_NAMESPACE
109 109
110 #else // COMPILER 110 #else // COMPILER
111 #error define BASE_HASH_NAMESPACE for your compiler 111 #error define BASE_HASH_NAMESPACE for your compiler
112 #endif // COMPILER 112 #endif // COMPILER
113 113
114 #if defined(COMPILER_MSVC)
115
116 #define DEFINE_PAIR_HASH_FUNCTION_START(type1, type2) \
117 template<> \
118 inline std::size_t hash_value<std::pair<type1, type2> >( \
119 const std::pair<type1, type2>& value)
120
121 #define DEFINE_PAIR_HASH_FUNCTION_END()
122
123 #elif defined(COMPILER_GCC)
124
125 #define DEFINE_PAIR_HASH_FUNCTION_START(type1, type2) \
126 template<> \
127 struct hash<std::pair<type1, type2> > { \
128 std::size_t operator()(std::pair<type1, type2> value) const
129
130 #define DEFINE_PAIR_HASH_FUNCTION_END() \
131 };
132
133 #else
134 #error define DEFINE_PAIR_HASH_FUNCTION_START for your compiler
135 #endif // COMPILER
136
137 namespace BASE_HASH_NAMESPACE {
138
139 // Implement hashing for pairs of at-most 32 bit integer values.
140 // When size_t is 32 bits, we turn the 64-bit hash code into 32 bits by using
141 // multiply-add hashing. This algorithm, as described in
142 // Theorem 4.3.3 of the thesis "Über die Komplexität der Multiplikation in
143 // eingeschränkten Branchingprogrammmodellen" by Woelfel, is:
144 //
145 // h32(x32, y32) = (h64(x32, y32) * randOdd64 + rand16 * 2^16) % 2^64 / 2^32
146
147 #define DEFINE_32BIT_PAIR_HASH(type1, type2) \
148 DEFINE_PAIR_HASH_FUNCTION_START(type1, type2) { \
149 uint64 first = value.first; \
150 uint32 second = value.second; \
151 uint64 hash64 = (first << 32) | second; \
152 \
153 if (sizeof(std::size_t) >= sizeof(uint64)) \
154 return static_cast<std::size_t>(hash64); \
155 \
156 uint64 oddRandom = 885644242649267641LL; \
jar (doing other things) 2012/09/24 20:52:21 FWIW: This is a strange odd number: about 2^56, he
157 uint32 shiftRandom = 10141U << 16; \
158 \
159 hash64 = hash64 * oddRandom + shiftRandom; \
160 std::size_t highBits = static_cast<std::size_t>( \
161 hash64 >> (sizeof(uint64) - sizeof(std::size_t))); \
162 return highBits; \
163 } \
164 DEFINE_PAIR_HASH_FUNCTION_END();
165
166 DEFINE_32BIT_PAIR_HASH(short, short);
167 DEFINE_32BIT_PAIR_HASH(short, unsigned short);
168 DEFINE_32BIT_PAIR_HASH(short, int);
169 DEFINE_32BIT_PAIR_HASH(short, unsigned);
170 DEFINE_32BIT_PAIR_HASH(unsigned short, short);
171 DEFINE_32BIT_PAIR_HASH(unsigned short, unsigned short);
172 DEFINE_32BIT_PAIR_HASH(unsigned short, int);
173 DEFINE_32BIT_PAIR_HASH(unsigned short, unsigned);
174 DEFINE_32BIT_PAIR_HASH(int, short);
175 DEFINE_32BIT_PAIR_HASH(int, unsigned short);
176 DEFINE_32BIT_PAIR_HASH(int, int);
177 DEFINE_32BIT_PAIR_HASH(int, unsigned);
178 DEFINE_32BIT_PAIR_HASH(unsigned, short);
179 DEFINE_32BIT_PAIR_HASH(unsigned, unsigned short);
180 DEFINE_32BIT_PAIR_HASH(unsigned, int);
181 DEFINE_32BIT_PAIR_HASH(unsigned, unsigned);
182
183 #undef DEFINE_32BIT_PAIR_HASH
184
185 // Implement hashing for pairs of up-to 64-bit integer values.
186 // We use the compound integer hash method to produce a 64-bit hash code, by
187 // breaking the two 64-bit inputs into 4 32-bit values:
188 // http://opendatastructures.org/versions/edition-0.1d/ods-java/node33.html#SECT ION00832000000000000000
189 // Then we reduce our result to 32 bits if required, similar to above.
190
191 #define DEFINE_64BIT_PAIR_HASH(type1, type2) \
192 DEFINE_PAIR_HASH_FUNCTION_START(type1, type2) { \
193 uint32 shortRandom1 = 673537332U; \
194 uint32 shortRandom2 = 2309950629U; \
195 uint32 shortRandom3 = 29379286U; \
jar (doing other things) 2012/09/24 20:52:21 This was a strange choice for a random odd number.
danakj 2012/09/24 21:09:03 All the random numbers were generated using random
196 uint32 shortRandom4 = 2611985739U; \
197 \
198 uint64 value1 = value.first; \
199 uint64 value2 = value.second; \
200 uint32 value1a = static_cast<uint32>(value1 & 0xffffffff); \
201 uint32 value1b = static_cast<uint32>((value1 >> 32) & 0xffffffff); \
202 uint32 value2a = static_cast<uint32>(value2 & 0xffffffff); \
203 uint32 value2b = static_cast<uint32>((value2 >> 32) & 0xffffffff); \
204 \
205 uint64 product1 = static_cast<uint64>(value1a) * shortRandom1; \
206 uint64 product2 = static_cast<uint64>(value1b) * shortRandom2; \
207 uint64 product3 = static_cast<uint64>(value2a) * shortRandom3; \
208 uint64 product4 = static_cast<uint64>(value2b) * shortRandom4; \
209 \
210 uint64 hash64 = product1 + product2 + product3 + product4; \
211 \
212 if (sizeof(std::size_t) >= sizeof(uint64)) \
213 return static_cast<std::size_t>(hash64); \
214 \
215 uint64 oddRandom = 629146275505555501LL; \
216 uint32 shiftRandom = 25582U << 16; \
217 \
218 hash64 = hash64 * oddRandom + shiftRandom; \
219 std::size_t highBits = static_cast<std::size_t>( \
220 hash64 >> (sizeof(uint64) - sizeof(std::size_t))); \
221 return highBits; \
222 } \
223 DEFINE_PAIR_HASH_FUNCTION_END();
224
225 DEFINE_64BIT_PAIR_HASH(short, int64);
226 DEFINE_64BIT_PAIR_HASH(short, uint64);
227 DEFINE_64BIT_PAIR_HASH(unsigned short, int64);
228 DEFINE_64BIT_PAIR_HASH(unsigned short, uint64);
229 DEFINE_64BIT_PAIR_HASH(int, int64);
230 DEFINE_64BIT_PAIR_HASH(int, uint64);
231 DEFINE_64BIT_PAIR_HASH(unsigned, int64);
232 DEFINE_64BIT_PAIR_HASH(unsigned, uint64);
233 DEFINE_64BIT_PAIR_HASH(int64, short);
234 DEFINE_64BIT_PAIR_HASH(int64, unsigned short);
235 DEFINE_64BIT_PAIR_HASH(int64, int);
236 DEFINE_64BIT_PAIR_HASH(int64, unsigned);
237 DEFINE_64BIT_PAIR_HASH(int64, int64);
238 DEFINE_64BIT_PAIR_HASH(int64, uint64);
239 DEFINE_64BIT_PAIR_HASH(uint64, short);
240 DEFINE_64BIT_PAIR_HASH(uint64, unsigned short);
241 DEFINE_64BIT_PAIR_HASH(uint64, int);
242 DEFINE_64BIT_PAIR_HASH(uint64, unsigned);
243 DEFINE_64BIT_PAIR_HASH(uint64, int64);
244 DEFINE_64BIT_PAIR_HASH(uint64, uint64);
245
246 #undef DEFINE_64BIT_PAIR_HASH
247 }
248
249 #undef DEFINE_PAIR_HASH_FUNCTION_START
250 #undef DEFINE_PAIR_HASH_FUNCTION_END
251
114 namespace base { 252 namespace base {
115 using BASE_HASH_NAMESPACE::hash_map; 253 using BASE_HASH_NAMESPACE::hash_map;
116 using BASE_HASH_NAMESPACE::hash_set; 254 using BASE_HASH_NAMESPACE::hash_set;
117 } 255 }
118 256
119 #endif // BASE_HASH_TABLES_H_ 257 #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