Skip to content

Commit 67807ee

Browse files
MurmurHash : Added string constructor and fromString function.
1 parent c1f159a commit 67807ee

File tree

5 files changed

+91
-2
lines changed

5 files changed

+91
-2
lines changed

Changes

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
10.4.x.x (relative to 10.4.2.1)
22
========
33

4+
Improvements
5+
------------
6+
7+
- Added string constructor and static `fromString` function to `IECore.MurmurHash`.
8+
49
Build
510
-----
611

include/IECore/MurmurHash.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ class IECORE_API MurmurHash
6161
inline MurmurHash();
6262
inline MurmurHash( const MurmurHash &other );
6363

64+
// Construct directly from string representation
65+
explicit MurmurHash( const std::string &repr );
66+
6467
// Construct directly from known internal values
6568
inline MurmurHash( uint64_t h1, uint64_t h2 );
6669

@@ -84,6 +87,7 @@ class IECORE_API MurmurHash
8487
inline bool operator < ( const MurmurHash &other ) const;
8588

8689
std::string toString() const;
90+
static MurmurHash fromString( const std::string &repr );
8791

8892
// Access internal storage for special cases
8993
inline uint64_t h1() const;

src/IECore/MurmurHash.cpp

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,63 @@
3333
//////////////////////////////////////////////////////////////////////////
3434

3535
#include "IECore/MurmurHash.h"
36+
#include "IECore/Exception.h"
37+
38+
#include <boost/format.hpp>
3639

3740
#include <iomanip>
3841
#include <sstream>
3942

4043
using namespace IECore;
4144

42-
std::string MurmurHash::toString() const
45+
namespace
46+
{
47+
48+
std::string internalToString( uint64_t const h1, uint64_t const h2 )
4349
{
4450
std::stringstream s;
45-
s << std::hex << std::setfill( '0' ) << std::setw( 16 ) << m_h1 << std::setw( 16 ) << m_h2;
51+
s << std::hex << std::setfill( '0' ) << std::setw( 16 ) << h1 << std::setw( 16 ) << h2;
4652
return s.str();
4753
}
4854

55+
void internalFromString( const std::string &repr, uint64_t &h1, uint64_t &h2 )
56+
{
57+
if( repr.length() != static_cast<std::string::size_type>( 32 ) )
58+
{
59+
throw Exception(
60+
boost::str(
61+
boost::format(
62+
"Invalid IECore::MurmurHash string representation \"%s\", must have 32 characters" )
63+
% repr
64+
) );
65+
}
66+
67+
std::stringstream s;
68+
s.str( repr.substr( 0, 16 ) );
69+
s >> std::hex >> h1;
70+
s.clear();
71+
s.str( repr.substr( 16, 16 ) );
72+
s >> std::hex >> h2;
73+
}
74+
75+
} // namespace
76+
77+
MurmurHash::MurmurHash( const std::string &repr )
78+
: m_h1( 0 ), m_h2( 0 )
79+
{
80+
internalFromString( repr, m_h1, m_h2 );
81+
}
82+
83+
std::string MurmurHash::toString() const
84+
{
85+
return internalToString( m_h1, m_h2 );
86+
}
87+
88+
MurmurHash MurmurHash::fromString( const std::string &repr )
89+
{
90+
return MurmurHash( repr );
91+
}
92+
4993
std::ostream &IECore::operator << ( std::ostream &o, const MurmurHash &hash )
5094
{
5195
o << hash.toString();

src/IECorePython/MurmurHashBinding.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ void IECorePython::bindMurmurHash()
128128
class_<MurmurHash>( "MurmurHash" )
129129
.def( init<>() )
130130
.def( init<const MurmurHash &>() )
131+
.def( init<const std::string &>() )
131132
.def( init<uint64_t, uint64_t>() )
132133
.def( "append", (MurmurHash &(MurmurHash::*)( const float & ))&MurmurHash::append, return_self<>() )
133134
.def( "append", (MurmurHash &(MurmurHash::*)( const double & ))&MurmurHash::append, return_self<>() )
@@ -198,6 +199,8 @@ void IECorePython::bindMurmurHash()
198199
.def( "__str__", &MurmurHash::toString )
199200
.def( "__hash__", &hash )
200201
.def( "toString", &MurmurHash::toString )
202+
.def( "fromString", (MurmurHash (*)( const std::string & ))&MurmurHash::fromString )
203+
.staticmethod( "fromString" )
201204
.def( "h1", &MurmurHash::h1 )
202205
.def( "h2", &MurmurHash::h2 )
203206
;

test/IECore/MurmurHashTest.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
import unittest
3636
import imath
37+
import six
3738

3839
import IECore
3940

@@ -45,6 +46,16 @@ def testConstructor( self ) :
4546
self.assertEqual( str( h ), "0" * 32 )
4647
self.assertEqual( h, IECore.MurmurHash() )
4748

49+
def testStringConstructor( self ) :
50+
51+
h = IECore.MurmurHash()
52+
h.append( 1 )
53+
h.append( "hello" )
54+
55+
s = h.toString()
56+
hs = IECore.MurmurHash( s )
57+
self.assertEqual( h, hs )
58+
4859
def testCopyConstructor( self ) :
4960

5061
h = IECore.MurmurHash()
@@ -54,6 +65,28 @@ def testCopyConstructor( self ) :
5465
self.assertEqual( h, IECore.MurmurHash( h ) )
5566
self.assertNotEqual( h, IECore.MurmurHash() )
5667

68+
def testRepr( self ) :
69+
70+
h = IECore.MurmurHash()
71+
h.append( 42 )
72+
h.append( "world" )
73+
h2 = eval( repr( h ) )
74+
75+
self.assertEqual( h, h2 )
76+
77+
def testFromString( self ) :
78+
79+
h = IECore.MurmurHash()
80+
h.append( 1 )
81+
h.append( "hello" )
82+
83+
s = h.toString()
84+
hs = IECore.MurmurHash.fromString( s )
85+
self.assertEqual( h, hs )
86+
87+
with six.assertRaisesRegex( self, Exception, ".*must have 32 characters.*" ) :
88+
IECore.MurmurHash.fromString( "InvalidStringRepresentation" )
89+
5790
def testAppend( self ) :
5891

5992
h = IECore.MurmurHash()

0 commit comments

Comments
 (0)