2013-06-11 14:48:50 +00:00
|
|
|
// Copyright 2010-2013 Google
|
2010-09-15 12:42:33 +00:00
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
|
//
|
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
//
|
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
2011-05-17 20:38:55 +00:00
|
|
|
#ifndef OR_TOOLS_BASE_HASH_H_
|
|
|
|
|
#define OR_TOOLS_BASE_HASH_H_
|
2010-09-15 12:42:33 +00:00
|
|
|
|
2011-05-17 20:38:55 +00:00
|
|
|
// Hash maps and hash sets are compiler dependant.
|
2010-09-15 12:42:33 +00:00
|
|
|
#ifdef __GNUC__
|
|
|
|
|
#include <ext/hash_map>
|
|
|
|
|
#include <ext/hash_set>
|
|
|
|
|
namespace operations_research {
|
2013-01-09 11:09:38 +00:00
|
|
|
using namespace __gnu_cxx; // NOLINT
|
2010-09-15 12:42:33 +00:00
|
|
|
} // namespace operations_research
|
|
|
|
|
#else
|
2011-06-23 08:47:37 +00:00
|
|
|
#include <hash_map>
|
2011-06-24 13:54:41 +00:00
|
|
|
#include <hash_set>
|
2010-09-15 12:42:33 +00:00
|
|
|
#endif
|
2011-05-17 20:38:55 +00:00
|
|
|
#include <string>
|
|
|
|
|
#include <utility>
|
2010-09-15 12:42:33 +00:00
|
|
|
|
|
|
|
|
#include "base/basictypes.h"
|
|
|
|
|
|
|
|
|
|
namespace operations_research {
|
2013-01-09 11:09:38 +00:00
|
|
|
// 32 bit version.
|
|
|
|
|
static inline void mix(uint32& a, uint32& b, uint32& c) { // NOLINT
|
|
|
|
|
a -= b; a -= c; a ^= (c >> 13);
|
|
|
|
|
b -= c; b -= a; b ^= (a << 8);
|
|
|
|
|
c -= a; c -= b; c ^= (b >> 13);
|
|
|
|
|
a -= b; a -= c; a ^= (c >> 12);
|
|
|
|
|
b -= c; b -= a; b ^= (a << 16);
|
|
|
|
|
c -= a; c -= b; c ^= (b >> 5);
|
|
|
|
|
a -= b; a -= c; a ^= (c >> 3);
|
|
|
|
|
b -= c; b -= a; b ^= (a << 10);
|
|
|
|
|
c -= a; c -= b; c ^= (b >> 15);
|
2010-09-15 12:42:33 +00:00
|
|
|
}
|
|
|
|
|
|
2013-01-09 11:09:38 +00:00
|
|
|
// 64 bit version.
|
|
|
|
|
static inline void mix(uint64& a, uint64& b, uint64& c) { // NOLINT
|
|
|
|
|
a -= b; a -= c; a ^= (c >> 43);
|
|
|
|
|
b -= c; b -= a; b ^= (a << 9);
|
|
|
|
|
c -= a; c -= b; c ^= (b >> 8);
|
|
|
|
|
a -= b; a -= c; a ^= (c >> 38);
|
|
|
|
|
b -= c; b -= a; b ^= (a << 23);
|
|
|
|
|
c -= a; c -= b; c ^= (b >> 5);
|
|
|
|
|
a -= b; a -= c; a ^= (c >> 35);
|
|
|
|
|
b -= c; b -= a; b ^= (a << 49);
|
|
|
|
|
c -= a; c -= b; c ^= (b >> 11);
|
|
|
|
|
a -= b; a -= c; a ^= (c >> 12);
|
|
|
|
|
b -= c; b -= a; b ^= (a << 18);
|
|
|
|
|
c -= a; c -= b; c ^= (b >> 22);
|
2010-09-15 12:42:33 +00:00
|
|
|
}
|
|
|
|
|
} // namespace operations_research
|
2011-05-17 20:38:55 +00:00
|
|
|
#if !defined(SWIG)
|
|
|
|
|
#if !defined(_MSC_VER)
|
2010-09-15 12:42:33 +00:00
|
|
|
namespace __gnu_cxx {
|
|
|
|
|
template<class T> struct hash<T*> {
|
|
|
|
|
size_t operator()(T *x) const { return reinterpret_cast<size_t>(x); }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<> struct hash<int64> {
|
|
|
|
|
size_t operator()(int64 x) const { return static_cast<size_t>(x); }
|
|
|
|
|
};
|
|
|
|
|
|
2010-11-02 18:59:07 +00:00
|
|
|
template<> struct hash<std::string> {
|
|
|
|
|
size_t operator()(const std::string& x) const {
|
|
|
|
|
size_t hash = 0;
|
|
|
|
|
int c;
|
|
|
|
|
const char* s = x.c_str();
|
2013-06-18 09:43:51 +00:00
|
|
|
while ((c = *s++)) { // Extra () to remove a warning on windows.
|
2010-11-02 18:59:07 +00:00
|
|
|
hash = ((hash << 5) + hash) ^ c;
|
|
|
|
|
}
|
|
|
|
|
return hash;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2010-09-15 12:42:33 +00:00
|
|
|
inline uint32 Hash32NumWithSeed(uint32 num, uint32 c) {
|
|
|
|
|
uint32 b = 0x9e3779b9UL; // the golden ratio; an arbitrary value
|
|
|
|
|
operations_research::mix(num, b, c);
|
|
|
|
|
return c;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline uint64 Hash64NumWithSeed(uint64 num, uint64 c) {
|
|
|
|
|
uint64 b = GG_ULONGLONG(0xe08c1d668b756f82); // more of the golden ratio
|
|
|
|
|
operations_research::mix(num, b, c);
|
|
|
|
|
return c;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class First, class Second>
|
|
|
|
|
struct hash<std::pair<First, Second> > {
|
|
|
|
|
size_t operator()(const std::pair<First, Second>& p) const {
|
|
|
|
|
size_t h1 = hash<First>()(p.first);
|
|
|
|
|
size_t h2 = hash<Second>()(p.second);
|
|
|
|
|
// The decision below is at compile time
|
2013-01-09 11:09:38 +00:00
|
|
|
return (sizeof(h1) <= sizeof(uint32)) ? // NOLINT
|
2010-09-15 12:42:33 +00:00
|
|
|
Hash32NumWithSeed(h1, h2)
|
|
|
|
|
: Hash64NumWithSeed(h1, h2);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
} // namespace __gnu_cxx
|
2011-05-17 20:38:55 +00:00
|
|
|
#else // !defined(_MSC_VER)
|
|
|
|
|
// The following class defines a hash function for pair<int64, int64>.
|
2011-06-23 08:47:37 +00:00
|
|
|
class PairInt64Hasher : public stdext::hash_compare <std::pair<int64, int64> > {
|
2011-05-17 20:38:55 +00:00
|
|
|
public:
|
2011-06-23 08:47:37 +00:00
|
|
|
size_t operator() (const std::pair<int64, int64>& a) const {
|
2011-05-17 20:38:55 +00:00
|
|
|
uint64 x = a.first;
|
|
|
|
|
uint64 y = GG_ULONGLONG(0xe08c1d668b756f82);
|
|
|
|
|
uint64 z = a.second;
|
2011-06-23 08:47:37 +00:00
|
|
|
operations_research::mix(x, y, z);
|
2011-05-17 20:38:55 +00:00
|
|
|
return z;
|
|
|
|
|
}
|
2011-06-23 08:47:37 +00:00
|
|
|
bool operator() (const std::pair<int64, int64>& a1,
|
|
|
|
|
const std::pair<int64, int64>& a2) const {
|
2011-05-17 20:38:55 +00:00
|
|
|
return a1.first < a2.first ||
|
|
|
|
|
(a1.first == a2.first && a1.second < a2.second);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2011-06-23 08:47:37 +00:00
|
|
|
class PairIntHasher : public stdext::hash_compare <std::pair<int, int> > {
|
2011-05-17 20:38:55 +00:00
|
|
|
public:
|
2011-06-23 08:47:37 +00:00
|
|
|
size_t operator() (const std::pair<int, int>& a) const {
|
2011-05-17 20:38:55 +00:00
|
|
|
uint32 x = a.first;
|
|
|
|
|
uint32 y = 0x9e3779b9UL;
|
|
|
|
|
uint32 z = a.second;
|
2011-06-23 08:47:37 +00:00
|
|
|
operations_research::mix(x, y, z);
|
2011-05-17 20:38:55 +00:00
|
|
|
return z;
|
|
|
|
|
}
|
2011-06-23 08:47:37 +00:00
|
|
|
bool operator() (const std::pair<int, int>& a1,
|
2011-06-28 09:23:44 +00:00
|
|
|
const std::pair<int, int>& a2) const {
|
2011-05-17 20:38:55 +00:00
|
|
|
return a1.first < a2.first ||
|
|
|
|
|
(a1.first == a2.first && a1.second < a2.second);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
#endif // defined(_MSC_VER)
|
|
|
|
|
#endif // defined(SWIG)
|
2010-09-15 12:42:33 +00:00
|
|
|
|
|
|
|
|
#if !defined(SWIG)
|
2011-05-17 20:38:55 +00:00
|
|
|
# if defined(__GNUC__)
|
2010-09-15 12:42:33 +00:00
|
|
|
using __gnu_cxx::hash;
|
|
|
|
|
using __gnu_cxx::hash_set;
|
2011-05-17 20:38:55 +00:00
|
|
|
# elif defined(_MSC_VER)
|
2010-09-15 12:42:33 +00:00
|
|
|
using std::hash;
|
|
|
|
|
using stdext::hash_map;
|
|
|
|
|
using stdext::hash_set;
|
2011-05-17 20:38:55 +00:00
|
|
|
# else
|
2010-09-15 12:42:33 +00:00
|
|
|
using std::hash;
|
|
|
|
|
using std::hash_map;
|
|
|
|
|
using std::hash_set;
|
2011-05-17 20:38:55 +00:00
|
|
|
# endif
|
2010-09-15 12:42:33 +00:00
|
|
|
#endif
|
2011-05-17 20:38:55 +00:00
|
|
|
|
|
|
|
|
#endif // OR_TOOLS_BASE_HASH_H_
|