Skip to content

Commit fd7a1f9

Browse files
MurmurHash : Add std::hash specialization, for use in std::unordered_map
1 parent e786d7b commit fd7a1f9

File tree

4 files changed

+154
-0
lines changed

4 files changed

+154
-0
lines changed

include/IECore/MurmurHash.inl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,4 +461,13 @@ inline void murmurHashAppend( MurmurHash &h, const T *data, size_t numElements )
461461

462462
} // namespace IECore
463463

464+
template <>
465+
struct std::hash<IECore::MurmurHash>
466+
{
467+
std::size_t operator()( const IECore::MurmurHash& h ) const
468+
{
469+
return h.h1() ^ h.h2();
470+
}
471+
};
472+
464473
#endif // IECORE_MURMURHASH_INL

test/IECore/IECoreTest.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ IECORE_POP_DEFAULT_VISIBILITY
6969
#include "CompoundDataTest.h"
7070
#include "CompoundObjectTest.h"
7171
#include "ComputationCacheTest.h"
72+
#include "MurmurHashTest.h"
7273

7374
using namespace boost::unit_test;
7475

@@ -102,6 +103,7 @@ bool init()
102103
addCompoundDataTest(test);
103104
addCompoundObjectTest(test);
104105
addComputationCacheTest(test);
106+
addMurmurHashTest(test);
105107
}
106108
catch (std::exception &ex)
107109
{

test/IECore/MurmurHashTest.cpp

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
//////////////////////////////////////////////////////////////////////////
2+
//
3+
// Copyright (c) 2023, Image Engine Design Inc. All rights reserved.
4+
//
5+
// Redistribution and use in source and binary forms, with or without
6+
// modification, are permitted provided that the following conditions are
7+
// met:
8+
//
9+
// * Redistributions of source code must retain the above copyright
10+
// notice, this list of conditions and the following disclaimer.
11+
//
12+
// * Redistributions in binary form must reproduce the above copyright
13+
// notice, this list of conditions and the following disclaimer in the
14+
// documentation and/or other materials provided with the distribution.
15+
//
16+
// * Neither the name of Image Engine Design nor the names of any
17+
// other contributors to this software may be used to endorse or
18+
// promote products derived from this software without specific prior
19+
// written permission.
20+
//
21+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22+
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23+
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24+
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
25+
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26+
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27+
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28+
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29+
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30+
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31+
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32+
//
33+
//////////////////////////////////////////////////////////////////////////
34+
35+
#include "MurmurHashTest.h"
36+
37+
#include "IECore/MurmurHash.h"
38+
39+
#include <unordered_set>
40+
41+
using namespace boost;
42+
using namespace boost::unit_test;
43+
44+
namespace IECore
45+
{
46+
47+
struct MurmurHashTest
48+
{
49+
50+
void testUnorderedSet()
51+
{
52+
std::unordered_set< IECore::MurmurHash > set;
53+
for( size_t i = 0; i < 1000000; i++ )
54+
{
55+
IECore::MurmurHash h;
56+
h.append( i );
57+
set.insert( h );
58+
}
59+
60+
BOOST_CHECK( set.size() == 1000000 );
61+
62+
size_t maxBucketOccupancy = 0;
63+
for( size_t i = 0; i < set.bucket_count(); i++ )
64+
{
65+
maxBucketOccupancy = std::max( maxBucketOccupancy, set.bucket_size( i ) );
66+
}
67+
68+
// If our hash function is good, then there shouldn't be any bucket that gets way too
69+
// many elements in it - currently, I'm seeing a max occupancy of 8.
70+
BOOST_CHECK( maxBucketOccupancy < 16 );
71+
}
72+
};
73+
74+
75+
struct MurmurHashTestSuite : public boost::unit_test::test_suite
76+
{
77+
78+
MurmurHashTestSuite() : boost::unit_test::test_suite( "MurmurHashTestSuite" )
79+
{
80+
boost::shared_ptr<MurmurHashTest> instance( new MurmurHashTest() );
81+
82+
add( BOOST_CLASS_TEST_CASE( &MurmurHashTest::testUnorderedSet, instance ) );
83+
}
84+
};
85+
86+
void addMurmurHashTest(boost::unit_test::test_suite* test)
87+
{
88+
test->add( new MurmurHashTestSuite( ) );
89+
}
90+
91+
} // namespace IECore

test/IECore/MurmurHashTest.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//////////////////////////////////////////////////////////////////////////
2+
//
3+
// Copyright (c) 2023, Image Engine Design Inc. All rights reserved.
4+
//
5+
// Redistribution and use in source and binary forms, with or without
6+
// modification, are permitted provided that the following conditions are
7+
// met:
8+
//
9+
// * Redistributions of source code must retain the above copyright
10+
// notice, this list of conditions and the following disclaimer.
11+
//
12+
// * Redistributions in binary form must reproduce the above copyright
13+
// notice, this list of conditions and the following disclaimer in the
14+
// documentation and/or other materials provided with the distribution.
15+
//
16+
// * Neither the name of Image Engine Design nor the names of any
17+
// other contributors to this software may be used to endorse or
18+
// promote products derived from this software without specific prior
19+
// written permission.
20+
//
21+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22+
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23+
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24+
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
25+
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26+
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27+
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28+
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29+
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30+
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31+
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32+
//
33+
//////////////////////////////////////////////////////////////////////////
34+
35+
#ifndef IECORE_MURMURHASHTEST_H
36+
#define IECORE_MURMURHASHTEST_H
37+
38+
#include "IECore/Export.h"
39+
40+
IECORE_PUSH_DEFAULT_VISIBILITY
41+
#include "boost/test/unit_test.hpp"
42+
IECORE_POP_DEFAULT_VISIBILITY
43+
44+
namespace IECore
45+
{
46+
47+
void addMurmurHashTest( boost::unit_test::test_suite *test );
48+
49+
}
50+
51+
#endif // IECORE_MURMURHASHTEST_H
52+

0 commit comments

Comments
 (0)