Kinetica   C#   API  Version 7.2.3.1
MurMurHash3.cs
Go to the documentation of this file.
1 /*
2 This code is public domain.
3 
4 The MurmurHash3 algorithm was created by Austin Appleby and put into the public domain. See http://code.google.com/p/smhasher/
5 */
6 
7 using System;
8 
9 
10 namespace kinetica;
11 
22  public static class MurMurHash3
23  {
25  public class LongPair
26  {
27  public long val1 { get; set; }
28  public long val2 { get; set; }
29  }
30 
31 
32  private static ulong fmix64( UInt64 k )
33  {
34  k ^= k >> 33;
35  k *= 0xff51afd7ed558ccdL;
36  k ^= k >> 33;
37  k *= 0xc4ceb9fe1a85ec53L;
38  k ^= k >> 33;
39  return k;
40  } // end fmix64
41 
42 
49  private static ulong RotateLeft( this ulong original, int bits )
50  {
51  return ( original << bits ) | ( original >> ( 64 - bits ) );
52  }
53 
54 
55 
56 
58  public static void murmurhash3_x64_128( byte[] key, uint offset, uint len, int seed, out LongPair output )
59  {
60  // The original algorithm does have a 32 bit unsigned seed.
61  // We have to mask to match the behavior of the unsigned types and prevent sign extension.
62  ulong h1 = (ulong) (seed & 0x00000000FFFFFFFFL);
63  ulong h2 = (ulong) (seed & 0x00000000FFFFFFFFL);
64 
65  const ulong c1 = 0x87c37b91114253d5L;
66  const ulong c2 = 0x4cf5ad432745937fL;
67 
68  uint roundedEnd = offset + (len & 0xFFFFFFF0); // round down to 16 byte block
69 
70  // Process the body in 16 byte blocks
71  for ( int i = (int)offset; i < roundedEnd; i += 16 )
72  {
73  ulong key1 = BitConverter.ToUInt64( key, i );
74  ulong key2 = BitConverter.ToUInt64( key, (i + 8) );
75 
76  key1 *= c1; key1 = key1.RotateLeft( 31 ); key1 *= c2; h1 ^= key1;
77  h1 = h1.RotateLeft( 27 ); h1 += h2; h1 = h1 * 5 + 0x52dce729;
78  key2 *= c2; key2 = key2.RotateLeft( 33 ); key2 *= c1; h2 ^= key2;
79  h2 = h2.RotateLeft( 31 ); h2 += h1; h2 = h2 * 5 + 0x38495ab5;
80  }
81 
82  // Process the remaining bytes, if any
83  ulong k1 = 0;
84  ulong k2 = 0;
85 
86  switch ( len & 15 )
87  {
88  case 15:
89  k2 = ( ulong ) ( key[roundedEnd + 14] & 0xffL ) << 48;
90  goto case 14; // fall through
91  case 14:
92  k2 |= ( ulong ) ( key[roundedEnd + 13] & 0xffL ) << 40;
93  goto case 13; // fall through
94  case 13:
95  k2 |= ( ulong ) ( key[roundedEnd + 12] & 0xffL ) << 32;
96  goto case 12; // fall through
97  case 12:
98  k2 |= ( ulong ) ( key[roundedEnd + 11] & 0xffL ) << 24;
99  goto case 11; // fall through
100  case 11:
101  k2 |= ( ulong ) ( key[roundedEnd + 10] & 0xffL ) << 16;
102  goto case 10; // fall through
103  case 10:
104  k2 |= ( ulong ) ( key[roundedEnd + 9] & 0xffL ) << 8;
105  goto case 9; // fall through
106  case 9:
107  k2 |= ( ulong ) ( key[roundedEnd + 8] & 0xffL );
108  k2 *= c2; k2 = k2.RotateLeft( 33 ); k2 *= c1; h2 ^= k2;
109  //break;
110  goto case 8; // fall through
111 
112  case 8:
113  k1 = ( ( ulong ) key[roundedEnd + 7] ) << 56;
114  goto case 7; // fall through
115  case 7:
116  k1 |= ( ulong ) ( key[roundedEnd + 6] & 0xffL ) << 48;
117  goto case 6; // fall through
118  case 6:
119  k1 |= ( ulong ) ( key[roundedEnd + 5] & 0xffL ) << 40;
120  goto case 5; // fall through
121  case 5:
122  k1 |= ( ulong ) ( key[roundedEnd + 4] & 0xffL ) << 32;
123  goto case 4; // fall through
124  case 4:
125  k1 |= ( ulong ) ( key[roundedEnd + 3] & 0xffL ) << 24;
126  goto case 3; // fall through
127  case 3:
128  k1 |= ( ulong ) ( key[roundedEnd + 2] & 0xffL ) << 16;
129  goto case 2; // fall through
130  case 2:
131  k1 |= ( ulong ) ( key[roundedEnd + 1] & 0xffL ) << 8;
132  goto case 1; // fall through
133  case 1:
134  k1 |= ( ulong ) ( key[roundedEnd] & 0xffL );
135  k1 *= c1; k1 = k1.RotateLeft( 31 ); k1 *= c2; h1 ^= k1;
136  break;
137  }
138 
139  //----------
140  // Finalize the values
141 
142  h1 ^= len;
143  h2 ^= len;
144 
145  h1 += h2;
146  h2 += h1;
147 
148  h1 = fmix64( h1 );
149  h2 = fmix64( h2 );
150 
151  h1 += h2;
152  h2 += h1;
153 
154  // Save the values in the output
155  output = new LongPair();
156  output.val1 = (long) h1;
157  output.val2 = (long) h2;
158  } // end murmurhash3_x64_128
159 
160  } // end class MurMurHash3
static void murmurhash3_x64_128(byte[] key, uint offset, uint len, int seed, out LongPair output)
Returns the MurmurHash3_x64_128 hash, placing the result in output
Definition: MurMurHash3.cs:58
128 bits of state
Definition: MurMurHash3.cs:25