murmurhash3 0.1.6-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/ext/murmurhash3/native.jar +0 -0
- data/lib/murmurhash3.rb +16 -0
- data/lib/murmurhash3/aliaser.rb +30 -0
- data/lib/murmurhash3/native_murmur.rb +11 -0
- data/lib/murmurhash3/native_ruby.rb +15 -0
- data/lib/murmurhash3/pure_ruby.rb +165 -0
- data/lib/murmurhash3/version.rb +3 -0
- data/test/test_murmur.rb +76 -0
- metadata +68 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 578e3995fcfc3de1c098772bce9b840038b40882
|
4
|
+
data.tar.gz: e2a0f60ad759f5ea17c2f07d8fbe1f59216d5ba9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5d8c798fd34c700c0063be818bd6c22256ec0872cfe387a08baefe2f31423ef4b4b660f59b38e66684bfc14cd547b5875587443439506fe918aea024da90a7ab
|
7
|
+
data.tar.gz: 808d8410457d263d7863b9c1d7234e2f7678804e21fed16919a375a21d04f2ea6c9d7827612fe94425fe0d8a8b0fb5aaeccd95e570f3b159d15e1e3c75d0eaf9
|
Binary file
|
data/lib/murmurhash3.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "murmurhash3/version"
|
2
|
+
|
3
|
+
module MurmurHash3
|
4
|
+
begin
|
5
|
+
require 'murmurhash3/native_murmur'
|
6
|
+
V32 = Native32
|
7
|
+
V128 = Native128
|
8
|
+
rescue LoadError
|
9
|
+
require 'murmurhash3/pure_ruby'
|
10
|
+
if RUBY_ENGINE == 'ruby'
|
11
|
+
$stderr.puts "Attention: used pure ruby version of MurmurHash3"
|
12
|
+
end
|
13
|
+
V32 = PureRuby32
|
14
|
+
V128 = PureRuby128
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module MurmurHash3
|
2
|
+
module Alias32
|
3
|
+
def self.included(base)
|
4
|
+
base.send(:extend, base)
|
5
|
+
class << base
|
6
|
+
alias fmix murmur3_32_fmix
|
7
|
+
alias str_hash murmur3_32_str_hash
|
8
|
+
alias str_digest murmur3_32_str_digest
|
9
|
+
alias str_hexdigest murmur3_32_str_hexdigest
|
10
|
+
alias str_base64digest murmur3_32_str_base64digest
|
11
|
+
alias int32_hash murmur3_32_int32_hash
|
12
|
+
alias int64_hash murmur3_32_int64_hash
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
module Alias128
|
17
|
+
def self.included(base)
|
18
|
+
base.send(:extend, base)
|
19
|
+
class << base
|
20
|
+
alias fmix murmur3_128_fmix
|
21
|
+
alias str_hash murmur3_128_str_hash
|
22
|
+
alias str_digest murmur3_128_str_digest
|
23
|
+
alias str_hexdigest murmur3_128_str_hexdigest
|
24
|
+
alias str_base64digest murmur3_128_str_base64digest
|
25
|
+
alias int32_hash murmur3_128_int32_hash
|
26
|
+
alias int64_hash murmur3_128_int64_hash
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'murmurhash3/aliaser'
|
2
|
+
if RUBY_ENGINE == 'jruby'
|
3
|
+
require 'murmurhash3/native'
|
4
|
+
else
|
5
|
+
require 'murmurhash3/native'
|
6
|
+
end
|
7
|
+
|
8
|
+
module MurmurHash3
|
9
|
+
module Native32
|
10
|
+
include MurmurHash3::Alias32
|
11
|
+
end
|
12
|
+
#module Native128
|
13
|
+
# include MurmurHash3::Alias128
|
14
|
+
#end
|
15
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
require 'murmurhash3/aliaser'
|
2
|
+
module MurmurHash3
|
3
|
+
module PureRuby32
|
4
|
+
MASK32 = 0xffffffff
|
5
|
+
def murmur3_32_rotl(x, r)
|
6
|
+
((x << r) | (x >> (32 - r))) & MASK32
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
def murmur3_32_fmix(h)
|
11
|
+
h &= MASK32
|
12
|
+
h ^= h >> 16
|
13
|
+
h = (h * 0x85ebca6b) & MASK32
|
14
|
+
h ^= h >> 13
|
15
|
+
h = (h * 0xc2b2ae35) & MASK32
|
16
|
+
h ^ (h >> 16)
|
17
|
+
end
|
18
|
+
|
19
|
+
def murmur3_32__mmix(k1)
|
20
|
+
k1 = (k1 * 0xcc9e2d51) & MASK32
|
21
|
+
k1 = murmur3_32_rotl(k1, 15)
|
22
|
+
(k1 * 0x1b873593) & MASK32
|
23
|
+
end
|
24
|
+
|
25
|
+
def murmur3_32_str_hash(str, seed=0)
|
26
|
+
h1 = seed
|
27
|
+
numbers = str.unpack('V*C*')
|
28
|
+
tailn = str.bytesize % 4
|
29
|
+
tail = numbers.slice!(numbers.size - tailn, tailn)
|
30
|
+
for k1 in numbers
|
31
|
+
h1 ^= murmur3_32__mmix(k1)
|
32
|
+
h1 = murmur3_32_rotl(h1, 13)
|
33
|
+
h1 = (h1*5 + 0xe6546b64) & MASK32
|
34
|
+
end
|
35
|
+
|
36
|
+
unless tail.empty?
|
37
|
+
k1 = 0
|
38
|
+
tail.reverse_each do |c1|
|
39
|
+
k1 = (k1 << 8) | c1
|
40
|
+
end
|
41
|
+
h1 ^= murmur3_32__mmix(k1)
|
42
|
+
end
|
43
|
+
|
44
|
+
h1 ^= str.bytesize
|
45
|
+
murmur3_32_fmix(h1)
|
46
|
+
end
|
47
|
+
|
48
|
+
def murmur3_32_int32_hash(i, seed=0)
|
49
|
+
str_hash([i].pack("V"), seed)
|
50
|
+
end
|
51
|
+
|
52
|
+
def murmur3_32_int64_hash(i, seed=0)
|
53
|
+
str_hash([i].pack("Q<"), seed)
|
54
|
+
end
|
55
|
+
|
56
|
+
def murmur3_32_str_digest(str, seed=0)
|
57
|
+
[str_hash(str, seed)].pack("V")
|
58
|
+
end
|
59
|
+
|
60
|
+
def murmur3_32_str_hexdigest(str, seed=0)
|
61
|
+
[str_hash(str, seed)].pack("V").unpack("H*")[0]
|
62
|
+
end
|
63
|
+
|
64
|
+
def murmur3_32_str_base64digest(str, seed=0)
|
65
|
+
[[str_hash(str, seed)].pack("V")].pack("m").chomp!
|
66
|
+
end
|
67
|
+
include MurmurHash3::Alias32
|
68
|
+
end
|
69
|
+
|
70
|
+
module PureRuby128
|
71
|
+
MASK64 = 0xffff_ffff_ffff_ffff
|
72
|
+
|
73
|
+
def murmur3_128_rotl(x, r)
|
74
|
+
((x << r) | (x >> (64 - r))) & MASK64
|
75
|
+
end
|
76
|
+
|
77
|
+
def murmur3_128_fmix(h)
|
78
|
+
h &= MASK64
|
79
|
+
h ^= h >> 33
|
80
|
+
h = (h * 0xff51afd7_ed558ccd) & MASK64
|
81
|
+
h ^= h >> 33
|
82
|
+
h = (h * 0xc4ceb9fe_1a85ec53) & MASK64
|
83
|
+
h ^ (h >> 33)
|
84
|
+
end
|
85
|
+
|
86
|
+
C1_128 = 0x87c37b91_114253d5
|
87
|
+
C2_128 = 0x4cf5ad43_2745937f
|
88
|
+
def murmur3_128__mmix1(k1)
|
89
|
+
k1 = (k1 * C1_128) & MASK64
|
90
|
+
k1 = murmur3_128_rotl(k1, 31)
|
91
|
+
(k1 * C2_128) & MASK64
|
92
|
+
end
|
93
|
+
|
94
|
+
def murmur3_128__mmix2(k2)
|
95
|
+
k2 = (k2 * C2_128) & MASK64
|
96
|
+
k2 = murmur3_128_rotl(k2, 33)
|
97
|
+
(k2 * C1_128) & MASK64
|
98
|
+
end
|
99
|
+
|
100
|
+
def murmur3_128_str_hash(str, seed=0)
|
101
|
+
h1 = h2 = seed
|
102
|
+
fast_part = ((str.bytesize / 16) * 16)
|
103
|
+
numbers = str.byteslice(0, fast_part).unpack('Q<*')
|
104
|
+
tail = str.byteslice(fast_part, str.bytesize - fast_part).unpack('C*')
|
105
|
+
|
106
|
+
numbers.each_slice(2) do |k1, k2|
|
107
|
+
h1 ^= murmur3_128__mmix1(k1)
|
108
|
+
h1 = murmur3_128_rotl(h1, 27)
|
109
|
+
h1 = (h1 + h2) & MASK64
|
110
|
+
h1 = (h1*5 + 0x52dce729) & MASK64
|
111
|
+
h2 ^= murmur3_128__mmix2(k2)
|
112
|
+
h2 = murmur3_128_rotl(h2, 31)
|
113
|
+
h2 = (h1 + h2) & MASK64
|
114
|
+
h2 = (h2*5 + 0x38495ab5) & MASK64
|
115
|
+
end
|
116
|
+
|
117
|
+
unless tail.empty?
|
118
|
+
if tail.size > 8
|
119
|
+
k2 = 0
|
120
|
+
tail[8,8].reverse_each do |c2|
|
121
|
+
k2 = (k2 << 8) | c2
|
122
|
+
end
|
123
|
+
h2 ^= murmur3_128__mmix2(k2)
|
124
|
+
end
|
125
|
+
k1 = 0
|
126
|
+
tail[0,8].reverse_each do |c1|
|
127
|
+
k1 = (k1 << 8) | c1
|
128
|
+
end
|
129
|
+
h1 ^= murmur3_128__mmix1(k1)
|
130
|
+
end
|
131
|
+
|
132
|
+
h1 ^= str.bytesize
|
133
|
+
h2 ^= str.bytesize
|
134
|
+
h1 = (h1 + h2) & MASK64
|
135
|
+
h2 = (h1 + h2) & MASK64
|
136
|
+
h1 = murmur3_128_fmix(h1)
|
137
|
+
h2 = murmur3_128_fmix(h2)
|
138
|
+
|
139
|
+
h1 = (h1 + h2) & MASK64
|
140
|
+
h2 = (h1 + h2) & MASK64
|
141
|
+
[h1 & 0xffffffff, h1 >> 32, h2 & 0xffffffff, h2 >> 32]
|
142
|
+
end
|
143
|
+
|
144
|
+
def murmur3_128_int32_hash(i, seed=0)
|
145
|
+
str_hash([i].pack("V"), seed)
|
146
|
+
end
|
147
|
+
|
148
|
+
def murmur3_128_int64_hash(i, seed=0)
|
149
|
+
str_hash([i].pack("Q<"), seed)
|
150
|
+
end
|
151
|
+
|
152
|
+
def murmur3_128_str_digest(str, seed=0)
|
153
|
+
str_hash(str, seed).pack("V4")
|
154
|
+
end
|
155
|
+
|
156
|
+
def murmur3_128_str_hexdigest(str, seed=0)
|
157
|
+
str_hash(str, seed).pack("V4").unpack("H*")[0]
|
158
|
+
end
|
159
|
+
|
160
|
+
def murmur3_128_str_base64digest(str, seed=0)
|
161
|
+
[str_hash(str, seed).pack("V4")].pack('m').chomp!
|
162
|
+
end
|
163
|
+
include MurmurHash3::Alias128
|
164
|
+
end
|
165
|
+
end
|
data/test/test_murmur.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'minitest/spec'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
|
4
|
+
shared_examples_128 = proc do
|
5
|
+
it 'should make correct hash for string' do
|
6
|
+
murmur.str_hash('asdfqwer', 0).must_equal [0xd6d7d367, 0xcb41f064, 0x8973cd72, 0xc345e72e]
|
7
|
+
murmur.str_hash('asdfqwerzxcvyui', 0).must_equal [0x007b2172f, 0x64ecae1b, 0x1813b5a5, 0x9c674ee6]
|
8
|
+
murmur.str_hash('asdfqwerzxcvyuio', 0).must_equal [0xf508df57, 0xbb38f3fd, 0xf48c9d98, 0xb65c36cd]
|
9
|
+
murmur.str_hash('asdfqwerzxcvyuio!', 0).must_equal [0x8a011755, 0xb13d463f, 0x8386d32a, 0x0df8884c]
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should make correct hash for 32bit integer' do
|
13
|
+
murmur.int32_hash(1717859169).must_equal [0x20b48108, 0x10369ceb, 0x3ad523cc, 0xdacb587f]
|
14
|
+
murmur.int32_hash(1717859169).must_equal murmur.str_hash('asdf')
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should make correct hash for 64bit integer' do
|
18
|
+
murmur.int64_hash(0x12345678).must_equal murmur.str_hash("\x78\x56\x34\x12\x00\x00\x00\x00")
|
19
|
+
murmur.int64_hash(0x1234567812345678).must_equal murmur.str_hash("\x78\x56\x34\x12\x78\x56\x34\x12")
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should make correct fmix for 64bit integer' do
|
23
|
+
murmur.fmix(1717859169).must_equal 0xbefb9076a3712207
|
24
|
+
murmur.fmix(12345678912345678).must_equal 0x197ef59146f5221c
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
shared_examples_32 = proc do
|
29
|
+
it 'should make correct hash for string' do
|
30
|
+
murmur.str_hash('asdfqwer', 0).must_equal 0xa46b5209
|
31
|
+
murmur.str_hash('asdfqwerty', 0).must_equal 0xa3cfe04b
|
32
|
+
murmur.str_hash('asd', 0).must_equal 0x14570c6f
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should make correct hash for 32bit integer' do
|
36
|
+
murmur.int32_hash(1717859169).must_equal 0x1b20e026
|
37
|
+
murmur.int32_hash(1717859169).must_equal murmur.str_hash('asdf')
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should make correct hash for 64bit integer' do
|
41
|
+
murmur.int64_hash(0x12345678).must_equal murmur.str_hash("\x78\x56\x34\x12\x00\x00\x00\x00")
|
42
|
+
murmur.int64_hash(0x1234567812345678).must_equal murmur.str_hash("\x78\x56\x34\x12\x78\x56\x34\x12")
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should make correct fmix for 32bit integer' do
|
46
|
+
murmur.fmix(1717859169).must_equal 0x17561734
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
require 'murmurhash3/pure_ruby'
|
51
|
+
describe "Pure ruby 32" do
|
52
|
+
let(:murmur) { MurmurHash3::PureRuby32 }
|
53
|
+
class_exec &shared_examples_32
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "Pure ruby 128" do
|
57
|
+
let(:murmur) { MurmurHash3::PureRuby128 }
|
58
|
+
class_exec &shared_examples_128
|
59
|
+
end
|
60
|
+
|
61
|
+
begin
|
62
|
+
require 'murmurhash3/native_murmur'
|
63
|
+
|
64
|
+
describe "Native 32" do
|
65
|
+
let(:murmur) { MurmurHash3::Native32 }
|
66
|
+
class_exec &shared_examples_32
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "Native 128" do
|
70
|
+
let(:murmur) { MurmurHash3::Native128 }
|
71
|
+
class_exec &shared_examples_128
|
72
|
+
end
|
73
|
+
|
74
|
+
rescue LoadError => e
|
75
|
+
puts "Could not load native extension: #{e}"
|
76
|
+
end
|
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: murmurhash3
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.6
|
5
|
+
platform: java
|
6
|
+
authors:
|
7
|
+
- Sokolov Yura 'funny-falcon'
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-12-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake-compiler
|
15
|
+
version_requirements: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.9'
|
20
|
+
requirement: !ruby/object:Gem::Requirement
|
21
|
+
requirements:
|
22
|
+
- - ~>
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: '0.9'
|
25
|
+
prerelease: false
|
26
|
+
type: :development
|
27
|
+
description: implementation of murmur3 hashing function
|
28
|
+
email:
|
29
|
+
- funny.falcon@gmail.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- lib/murmurhash3.rb
|
35
|
+
- lib/murmurhash3/aliaser.rb
|
36
|
+
- lib/murmurhash3/native_murmur.rb
|
37
|
+
- lib/murmurhash3/native_ruby.rb
|
38
|
+
- lib/murmurhash3/pure_ruby.rb
|
39
|
+
- lib/murmurhash3/version.rb
|
40
|
+
- test/test_murmur.rb
|
41
|
+
- ext/murmurhash3/native.jar
|
42
|
+
homepage: https://github.com/funny-falcon/murmurhash3-ruby
|
43
|
+
licenses:
|
44
|
+
- MIT
|
45
|
+
metadata: {}
|
46
|
+
post_install_message:
|
47
|
+
rdoc_options: []
|
48
|
+
require_paths:
|
49
|
+
- lib
|
50
|
+
- ext
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 1.9.1
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
requirements: []
|
62
|
+
rubyforge_project:
|
63
|
+
rubygems_version: 2.1.9
|
64
|
+
signing_key:
|
65
|
+
specification_version: 4
|
66
|
+
summary: implements mumur3 hashing function
|
67
|
+
test_files:
|
68
|
+
- test/test_murmur.rb
|