1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/chromium/base/containers/hash_tables.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,264 @@ 1.4 +// Copyright (c) 2011 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 +// 1.8 + 1.9 +// 1.10 +// Deal with the differences between Microsoft and GNU implemenations 1.11 +// of hash_map. Allows all platforms to use |base::hash_map| and 1.12 +// |base::hash_set|. 1.13 +// eg: 1.14 +// base::hash_map<int> my_map; 1.15 +// base::hash_set<int> my_set; 1.16 +// 1.17 +// NOTE: It is an explicit non-goal of this class to provide a generic hash 1.18 +// function for pointers. If you want to hash a pointers to a particular class, 1.19 +// please define the template specialization elsewhere (for example, in its 1.20 +// header file) and keep it specific to just pointers to that class. This is 1.21 +// because identity hashes are not desirable for all types that might show up 1.22 +// in containers as pointers. 1.23 + 1.24 +#ifndef BASE_CONTAINERS_HASH_TABLES_H_ 1.25 +#define BASE_CONTAINERS_HASH_TABLES_H_ 1.26 + 1.27 +#include <utility> 1.28 + 1.29 +#include "base/basictypes.h" 1.30 +#include "base/strings/string16.h" 1.31 +#include "build/build_config.h" 1.32 + 1.33 +#if defined(COMPILER_MSVC) 1.34 +#include <hash_map> 1.35 +#include <hash_set> 1.36 + 1.37 +#define BASE_HASH_NAMESPACE stdext 1.38 + 1.39 +#elif defined(COMPILER_GCC) 1.40 +#if defined(OS_ANDROID) 1.41 +#define BASE_HASH_NAMESPACE std 1.42 +#else 1.43 +#define BASE_HASH_NAMESPACE __gnu_cxx 1.44 +#endif 1.45 + 1.46 +// This is a hack to disable the gcc 4.4 warning about hash_map and hash_set 1.47 +// being deprecated. We can get rid of this when we upgrade to VS2008 and we 1.48 +// can use <tr1/unordered_map> and <tr1/unordered_set>. 1.49 +#ifdef __DEPRECATED 1.50 +#define CHROME_OLD__DEPRECATED __DEPRECATED 1.51 +#undef __DEPRECATED 1.52 +#endif 1.53 + 1.54 +#if defined(OS_ANDROID) 1.55 +#include <hash_map> 1.56 +#include <hash_set> 1.57 +#else 1.58 +#include <ext/hash_map> 1.59 +#include <ext/hash_set> 1.60 +#endif 1.61 + 1.62 +#include <string> 1.63 + 1.64 +#ifdef CHROME_OLD__DEPRECATED 1.65 +#define __DEPRECATED CHROME_OLD__DEPRECATED 1.66 +#undef CHROME_OLD__DEPRECATED 1.67 +#endif 1.68 + 1.69 +namespace BASE_HASH_NAMESPACE { 1.70 + 1.71 +#if !defined(OS_ANDROID) 1.72 +// The GNU C++ library provides identity hash functions for many integral types, 1.73 +// but not for |long long|. This hash function will truncate if |size_t| is 1.74 +// narrower than |long long|. This is probably good enough for what we will 1.75 +// use it for. 1.76 + 1.77 +#define DEFINE_TRIVIAL_HASH(integral_type) \ 1.78 + template<> \ 1.79 + struct hash<integral_type> { \ 1.80 + std::size_t operator()(integral_type value) const { \ 1.81 + return static_cast<std::size_t>(value); \ 1.82 + } \ 1.83 + } 1.84 + 1.85 +DEFINE_TRIVIAL_HASH(long long); 1.86 +DEFINE_TRIVIAL_HASH(unsigned long long); 1.87 + 1.88 +#undef DEFINE_TRIVIAL_HASH 1.89 +#endif // !defined(OS_ANDROID) 1.90 + 1.91 +// Implement string hash functions so that strings of various flavors can 1.92 +// be used as keys in STL maps and sets. The hash algorithm comes from the 1.93 +// GNU C++ library, in <tr1/functional>. It is duplicated here because GCC 1.94 +// versions prior to 4.3.2 are unable to compile <tr1/functional> when RTTI 1.95 +// is disabled, as it is in our build. 1.96 + 1.97 +#define DEFINE_STRING_HASH(string_type) \ 1.98 + template<> \ 1.99 + struct hash<string_type> { \ 1.100 + std::size_t operator()(const string_type& s) const { \ 1.101 + std::size_t result = 0; \ 1.102 + for (string_type::const_iterator i = s.begin(); i != s.end(); ++i) \ 1.103 + result = (result * 131) + *i; \ 1.104 + return result; \ 1.105 + } \ 1.106 + } 1.107 + 1.108 +DEFINE_STRING_HASH(std::string); 1.109 +DEFINE_STRING_HASH(string16); 1.110 + 1.111 +#undef DEFINE_STRING_HASH 1.112 + 1.113 +} // namespace BASE_HASH_NAMESPACE 1.114 + 1.115 +#else // COMPILER 1.116 +#error define BASE_HASH_NAMESPACE for your compiler 1.117 +#endif // COMPILER 1.118 + 1.119 +namespace base { 1.120 +using BASE_HASH_NAMESPACE::hash_map; 1.121 +using BASE_HASH_NAMESPACE::hash_multimap; 1.122 +using BASE_HASH_NAMESPACE::hash_multiset; 1.123 +using BASE_HASH_NAMESPACE::hash_set; 1.124 + 1.125 +// Implement hashing for pairs of at-most 32 bit integer values. 1.126 +// When size_t is 32 bits, we turn the 64-bit hash code into 32 bits by using 1.127 +// multiply-add hashing. This algorithm, as described in 1.128 +// Theorem 4.3.3 of the thesis "Über die Komplexität der Multiplikation in 1.129 +// eingeschränkten Branchingprogrammmodellen" by Woelfel, is: 1.130 +// 1.131 +// h32(x32, y32) = (h64(x32, y32) * rand_odd64 + rand16 * 2^16) % 2^64 / 2^32 1.132 +// 1.133 +// Contact danakj@chromium.org for any questions. 1.134 +inline std::size_t HashInts32(uint32 value1, uint32 value2) { 1.135 + uint64 value1_64 = value1; 1.136 + uint64 hash64 = (value1_64 << 32) | value2; 1.137 + 1.138 + if (sizeof(std::size_t) >= sizeof(uint64)) 1.139 + return static_cast<std::size_t>(hash64); 1.140 + 1.141 + uint64 odd_random = 481046412LL << 32 | 1025306955LL; 1.142 + uint32 shift_random = 10121U << 16; 1.143 + 1.144 + hash64 = hash64 * odd_random + shift_random; 1.145 + std::size_t high_bits = static_cast<std::size_t>( 1.146 + hash64 >> (sizeof(uint64) - sizeof(std::size_t))); 1.147 + return high_bits; 1.148 +} 1.149 + 1.150 +// Implement hashing for pairs of up-to 64-bit integer values. 1.151 +// We use the compound integer hash method to produce a 64-bit hash code, by 1.152 +// breaking the two 64-bit inputs into 4 32-bit values: 1.153 +// http://opendatastructures.org/versions/edition-0.1d/ods-java/node33.html#SECTION00832000000000000000 1.154 +// Then we reduce our result to 32 bits if required, similar to above. 1.155 +inline std::size_t HashInts64(uint64 value1, uint64 value2) { 1.156 + uint32 short_random1 = 842304669U; 1.157 + uint32 short_random2 = 619063811U; 1.158 + uint32 short_random3 = 937041849U; 1.159 + uint32 short_random4 = 3309708029U; 1.160 + 1.161 + uint32 value1a = static_cast<uint32>(value1 & 0xffffffff); 1.162 + uint32 value1b = static_cast<uint32>((value1 >> 32) & 0xffffffff); 1.163 + uint32 value2a = static_cast<uint32>(value2 & 0xffffffff); 1.164 + uint32 value2b = static_cast<uint32>((value2 >> 32) & 0xffffffff); 1.165 + 1.166 + uint64 product1 = static_cast<uint64>(value1a) * short_random1; 1.167 + uint64 product2 = static_cast<uint64>(value1b) * short_random2; 1.168 + uint64 product3 = static_cast<uint64>(value2a) * short_random3; 1.169 + uint64 product4 = static_cast<uint64>(value2b) * short_random4; 1.170 + 1.171 + uint64 hash64 = product1 + product2 + product3 + product4; 1.172 + 1.173 + if (sizeof(std::size_t) >= sizeof(uint64)) 1.174 + return static_cast<std::size_t>(hash64); 1.175 + 1.176 + uint64 odd_random = 1578233944LL << 32 | 194370989LL; 1.177 + uint32 shift_random = 20591U << 16; 1.178 + 1.179 + hash64 = hash64 * odd_random + shift_random; 1.180 + std::size_t high_bits = static_cast<std::size_t>( 1.181 + hash64 >> (sizeof(uint64) - sizeof(std::size_t))); 1.182 + return high_bits; 1.183 +} 1.184 + 1.185 +#define DEFINE_32BIT_PAIR_HASH(Type1, Type2) \ 1.186 +inline std::size_t HashPair(Type1 value1, Type2 value2) { \ 1.187 + return HashInts32(value1, value2); \ 1.188 +} 1.189 + 1.190 +DEFINE_32BIT_PAIR_HASH(int16, int16); 1.191 +DEFINE_32BIT_PAIR_HASH(int16, uint16); 1.192 +DEFINE_32BIT_PAIR_HASH(int16, int32); 1.193 +DEFINE_32BIT_PAIR_HASH(int16, uint32); 1.194 +DEFINE_32BIT_PAIR_HASH(uint16, int16); 1.195 +DEFINE_32BIT_PAIR_HASH(uint16, uint16); 1.196 +DEFINE_32BIT_PAIR_HASH(uint16, int32); 1.197 +DEFINE_32BIT_PAIR_HASH(uint16, uint32); 1.198 +DEFINE_32BIT_PAIR_HASH(int32, int16); 1.199 +DEFINE_32BIT_PAIR_HASH(int32, uint16); 1.200 +DEFINE_32BIT_PAIR_HASH(int32, int32); 1.201 +DEFINE_32BIT_PAIR_HASH(int32, uint32); 1.202 +DEFINE_32BIT_PAIR_HASH(uint32, int16); 1.203 +DEFINE_32BIT_PAIR_HASH(uint32, uint16); 1.204 +DEFINE_32BIT_PAIR_HASH(uint32, int32); 1.205 +DEFINE_32BIT_PAIR_HASH(uint32, uint32); 1.206 + 1.207 +#undef DEFINE_32BIT_PAIR_HASH 1.208 + 1.209 +#define DEFINE_64BIT_PAIR_HASH(Type1, Type2) \ 1.210 +inline std::size_t HashPair(Type1 value1, Type2 value2) { \ 1.211 + return HashInts64(value1, value2); \ 1.212 +} 1.213 + 1.214 +DEFINE_64BIT_PAIR_HASH(int16, int64); 1.215 +DEFINE_64BIT_PAIR_HASH(int16, uint64); 1.216 +DEFINE_64BIT_PAIR_HASH(uint16, int64); 1.217 +DEFINE_64BIT_PAIR_HASH(uint16, uint64); 1.218 +DEFINE_64BIT_PAIR_HASH(int32, int64); 1.219 +DEFINE_64BIT_PAIR_HASH(int32, uint64); 1.220 +DEFINE_64BIT_PAIR_HASH(uint32, int64); 1.221 +DEFINE_64BIT_PAIR_HASH(uint32, uint64); 1.222 +DEFINE_64BIT_PAIR_HASH(int64, int16); 1.223 +DEFINE_64BIT_PAIR_HASH(int64, uint16); 1.224 +DEFINE_64BIT_PAIR_HASH(int64, int32); 1.225 +DEFINE_64BIT_PAIR_HASH(int64, uint32); 1.226 +DEFINE_64BIT_PAIR_HASH(int64, int64); 1.227 +DEFINE_64BIT_PAIR_HASH(int64, uint64); 1.228 +DEFINE_64BIT_PAIR_HASH(uint64, int16); 1.229 +DEFINE_64BIT_PAIR_HASH(uint64, uint16); 1.230 +DEFINE_64BIT_PAIR_HASH(uint64, int32); 1.231 +DEFINE_64BIT_PAIR_HASH(uint64, uint32); 1.232 +DEFINE_64BIT_PAIR_HASH(uint64, int64); 1.233 +DEFINE_64BIT_PAIR_HASH(uint64, uint64); 1.234 + 1.235 +#undef DEFINE_64BIT_PAIR_HASH 1.236 +} // namespace base 1.237 + 1.238 +namespace BASE_HASH_NAMESPACE { 1.239 + 1.240 +// Implement methods for hashing a pair of integers, so they can be used as 1.241 +// keys in STL containers. 1.242 + 1.243 +#if defined(COMPILER_MSVC) 1.244 + 1.245 +template<typename Type1, typename Type2> 1.246 +inline std::size_t hash_value(const std::pair<Type1, Type2>& value) { 1.247 + return base::HashPair(value.first, value.second); 1.248 +} 1.249 + 1.250 +#elif defined(COMPILER_GCC) 1.251 +template<typename Type1, typename Type2> 1.252 +struct hash<std::pair<Type1, Type2> > { 1.253 + std::size_t operator()(std::pair<Type1, Type2> value) const { 1.254 + return base::HashPair(value.first, value.second); 1.255 + } 1.256 +}; 1.257 + 1.258 +#else 1.259 +#error define hash<std::pair<Type1, Type2> > for your compiler 1.260 +#endif // COMPILER 1.261 + 1.262 +} 1.263 + 1.264 +#undef DEFINE_PAIR_HASH_FUNCTION_START 1.265 +#undef DEFINE_PAIR_HASH_FUNCTION_END 1.266 + 1.267 +#endif // BASE_CONTAINERS_HASH_TABLES_H_