Added hash() overloads for uint32, uint64, and std::pair as well as some more

unit tests.
This commit is contained in:
Davis King 2012-11-27 21:28:00 -05:00
parent d01eee951b
commit 5e75471a84
3 changed files with 151 additions and 0 deletions

View File

@ -83,6 +83,57 @@ namespace dlib
return hash(std::vector<std::pair<T,U> >(item.begin(), item.end()), seed);
}
// ----------------------------------------------------------------------------------------
inline uint32 hash (
uint32 val,
uint32 seed = 0
)
{
return murmur_hash3_2(val,seed);
}
// ----------------------------------------------------------------------------------------
inline uint32 hash (
uint64 val,
uint32 seed = 0
)
{
return static_cast<uint32>(murmur_hash3_128bit_3(val,seed,0).first);
}
// ----------------------------------------------------------------------------------------
inline uint32 hash (
const std::pair<uint64,uint64>& item,
uint32 seed = 0
)
{
return static_cast<uint32>(murmur_hash3_128bit_3(item.first,item.second,seed).first);
}
// ----------------------------------------------------------------------------------------
inline uint32 hash (
const std::pair<uint32,uint32>& item,
uint32 seed = 0
)
{
return murmur_hash3_3(item.first,item.second,seed);
}
// ----------------------------------------------------------------------------------------
template <typename T, typename U>
uint32 hash (
const std::pair<T,U>& item,
uint32 seed = 0
)
{
return hash(item.first, seed) ^ hash(item.second, seed+1);
}
// ----------------------------------------------------------------------------------------
}

View File

@ -121,6 +121,56 @@ namespace dlib
std::vector and then work from there.
!*/
// ----------------------------------------------------------------------------------------
inline uint32 hash (
uint32 item,
uint32 seed = 0
);
/*!
ensures
- returns a 32bit hash of the data stored in item.
- Each value of seed results in a different hash function being used.
(e.g. hash(item,0) should generally not be equal to hash(item,1))
- uses the murmur_hash3_2() routine to compute the actual hash.
- This routine will always give the same hash value when presented
with the same input.
!*/
// ----------------------------------------------------------------------------------------
inline uint32 hash (
uint64 item,
uint32 seed = 0
);
/*!
ensures
- returns a 32bit hash of the data stored in item.
- Each value of seed results in a different hash function being used.
(e.g. hash(item,0) should generally not be equal to hash(item,1))
- uses the murmur_hash3_128bit_3() routine to compute the actual hash.
- This routine will always give the same hash value when presented
with the same input.
!*/
// ----------------------------------------------------------------------------------------
template <typename T, typename U>
uint32 hash (
const std::pair<T,U>& item,
uint32 seed = 0
);
/*!
ensures
- returns a 32bit hash of the data stored in item.
- Each value of seed results in a different hash function being used.
(e.g. hash(item,0) should generally not be equal to hash(item,1))
- if (calling hash() on items of type T and U is always guaranteed to give the
same hash values when presented with the same input) then
- This routine will always give the same hash value when presented
with the same input.
!*/
// ----------------------------------------------------------------------------------------
}

View File

@ -183,6 +183,28 @@ namespace
}
}
void test_murmur_hash_64_3()
{
byte_orderer bo;
dlib::rand rnd;
for (int i = 0; i < 100; ++i)
{
uint32 buf[2] = {rnd.get_random_32bit_number(),
rnd.get_random_32bit_number()};
const uint32 seed = rnd.get_random_32bit_number();
bo.host_to_little(buf);
uint32 temp1, temp2;
// Make sure the 2 integer version of murmur hash does the same thing
// as the memory block version.
temp1 = murmur_hash3(&buf, sizeof(buf), seed);
temp2 = murmur_hash3_3(buf[0], buf[1], seed);
DLIB_TEST(temp1 == temp2);
}
}
class test_hash : public tester
{
public:
@ -236,6 +258,33 @@ namespace
dlog << LINFO << "hash(mat): "<< dlib::hash(mat);
dlog << LINFO << "hash(mat2): "<< dlib::hash(mat2);
uint32 ui1 = 123485393;
uint64 ui2 = ui1;
ui2 *= ui2;
ui2 *= ui2;
dlog << LINFO << "hash(ui1): "<< dlib::hash(ui1);
dlog << LINFO << "hash(ui2): "<< dlib::hash(ui2);
dlog << LINFO << "hash(make_pair(ui2,ui1)): "<< dlib::hash(make_pair(ui2,ui1));
dlog << LINFO << "hash(make_pair(ui2,ui2)): "<< dlib::hash(make_pair(ui2,ui2));
dlog << LINFO << "hash(make_pair(ui1,ui1)): "<< dlib::hash(make_pair(ui1,ui1));
dlog << LINFO << "hash(ui1,3): "<< dlib::hash(ui1,3);
dlog << LINFO << "hash(ui2,3): "<< dlib::hash(ui2,3);
dlog << LINFO << "hash(make_pair(ui2,ui1),3): "<< dlib::hash(make_pair(ui2,ui1),3);
dlog << LINFO << "hash(make_pair(ui2,ui2),3): "<< dlib::hash(make_pair(ui2,ui2),3);
dlog << LINFO << "hash(make_pair(ui1,ui1),3): "<< dlib::hash(make_pair(ui1,ui1),3);
DLIB_TEST(dlib::hash(ui1) == 0x63e272e4);
DLIB_TEST(dlib::hash(ui2) == 0xaf55561a);
DLIB_TEST(dlib::hash(make_pair(ui2,ui1)) == 0x52685376);
DLIB_TEST(dlib::hash(make_pair(ui2,ui2)) == 0xd25d6929);
DLIB_TEST(dlib::hash(make_pair(ui1,ui1)) == 0xeea3b63e);
DLIB_TEST(dlib::hash(ui1,3) == 0x95d1c4c0);
DLIB_TEST(dlib::hash(ui2,3) == 0x6ada728d);
DLIB_TEST(dlib::hash(make_pair(ui2,ui1),3) == 0x2f72a0ff);
DLIB_TEST(dlib::hash(make_pair(ui2,ui2),3) == 0xac1407f0);
DLIB_TEST(dlib::hash(make_pair(ui1,ui1),3) == 0x39ad637a);
DLIB_TEST(dlib::hash(str1) == 0x3ffe6bf6);
DLIB_TEST(dlib::hash(v) == 0xf1af2ca6);
DLIB_TEST(dlib::hash(v2) == 0x63852afc);
@ -262,6 +311,7 @@ namespace
test_murmur_hash_128_4();
test_murmur_hash_128_3();
test_murmur_hash_64_2();
test_murmur_hash_64_3();
}
} a;