digest-murmurhash 0.2.3 → 0.3.0

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.
@@ -0,0 +1,13 @@
1
+ #ifndef MURMURHASH_ALIGNED2_INCLUDED
2
+ # define MURMURHASH_ALIGNED2_INCLUDED
3
+
4
+ #include "murmurhash.h"
5
+
6
+ VALUE murmur_aligned2_finish(VALUE self);
7
+ VALUE murmur_aligned2_to_i(VALUE self);
8
+ VALUE murmur_aligned2_s_digest(int argc, VALUE *argv, VALUE klass);
9
+ VALUE murmur_aligned2_s_hexdigest(int argc, VALUE *argv, VALUE klass);
10
+ VALUE murmur_aligned2_s_rawdigest(int argc, VALUE *argv, VALUE klass);
11
+
12
+ #endif /* ifndef MURMURHASH_ALIGNED2_INCLUDED */
13
+
@@ -0,0 +1,87 @@
1
+ /*
2
+ * MurmurHashNeutral2 (C) Austin Appleby
3
+ */
4
+
5
+ #include "murmurhash_neutral2.h"
6
+
7
+ uint32_t
8
+ murmur_hash_process_neutral2(const char * key, uint32_t len, uint32_t seed)
9
+ {
10
+ const uint32_t m = 0x5bd1e995;
11
+ const int r = 24;
12
+
13
+ uint32_t h = seed ^ len;
14
+
15
+ const unsigned char * data = (const unsigned char *)key;
16
+
17
+ while(len >= 4) {
18
+ uint32_t k;
19
+
20
+ k = data[0];
21
+ k |= data[1] << 8;
22
+ k |= data[2] << 16;
23
+ k |= data[3] << 24;
24
+
25
+ k *= m;
26
+ k ^= k >> r;
27
+ k *= m;
28
+
29
+ h *= m;
30
+ h ^= k;
31
+
32
+ data += 4;
33
+ len -= 4;
34
+ }
35
+
36
+ switch(len) {
37
+ case 3: h ^= data[2] << 16;
38
+ case 2: h ^= data[1] << 8;
39
+ case 1: h ^= data[0];
40
+ h *= m;
41
+ };
42
+
43
+ h ^= h >> 13;
44
+ h *= m;
45
+ h ^= h >> 15;
46
+
47
+ return h;
48
+ }
49
+
50
+ VALUE
51
+ murmur_neutral2_finish(VALUE self)
52
+ {
53
+ uint8_t digest[4];
54
+ uint32_t h;
55
+
56
+ h = _murmur_finish32(self, murmur_hash_process_neutral2);
57
+ ASSINE_BY_ENDIAN_32(digest, h);
58
+ return rb_str_new((const char*) digest, 4);
59
+ }
60
+
61
+ VALUE
62
+ murmur_neutral2_to_i(VALUE self)
63
+ {
64
+ return ULL2NUM(_murmur_finish32(self, murmur_hash_process_neutral2));
65
+ }
66
+
67
+ VALUE
68
+ murmur_neutral2_s_digest(int argc, VALUE *argv, VALUE klass)
69
+ {
70
+ uint8_t digest[4];
71
+ uint64_t h;
72
+ h = _murmur_s_digest32(argc, argv, klass, murmur_hash_process_neutral2);
73
+ ASSINE_BY_ENDIAN_32(digest, h);
74
+ return rb_str_new((const char*) digest, 4);
75
+ }
76
+
77
+ VALUE
78
+ murmur_neutral2_s_hexdigest(int argc, VALUE *argv, VALUE klass)
79
+ {
80
+ return hexencode_str_new(murmur_neutral2_s_digest(argc, argv, klass));
81
+ }
82
+
83
+ VALUE
84
+ murmur_neutral2_s_rawdigest(int argc, VALUE *argv, VALUE klass)
85
+ {
86
+ return ULL2NUM(_murmur_s_digest32(argc, argv, klass, murmur_hash_process_neutral2));
87
+ }
@@ -0,0 +1,13 @@
1
+ #ifndef MURMURHASH_NEUTRAL2_INCLUDED
2
+ # define MURMURHASH_NEUTRAL2_INCLUDED
3
+
4
+ #include "murmurhash.h"
5
+
6
+ VALUE murmur_neutral2_finish(VALUE self);
7
+ VALUE murmur_neutral2_to_i(VALUE self);
8
+ VALUE murmur_neutral2_s_digest(int argc, VALUE *argv, VALUE klass);
9
+ VALUE murmur_neutral2_s_hexdigest(int argc, VALUE *argv, VALUE klass);
10
+ VALUE murmur_neutral2_s_rawdigest(int argc, VALUE *argv, VALUE klass);
11
+
12
+ #endif /* ifndef MURMURHASH_NEUTRAL2_INCLUDED */
13
+
@@ -1,5 +1,5 @@
1
1
  module Digest
2
2
  class MurmurHash
3
- VERSION = "0.2.3"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
@@ -7,18 +7,13 @@ require 'digest/stringbuffer'
7
7
  require 'digest/murmurhash'
8
8
  require 'benchmark'
9
9
 
10
- class Prime37 < Digest::StringBuffer
11
- def initialize
12
- @prime = 37
13
- end
14
-
15
- def finish
16
- result = 0
17
- buffer.unpack("C*").each do |c|
18
- result += (c * @prime)
19
- end
20
- [result & 0xffffffff].pack("N")
21
- end
10
+ @rands = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".split(//)
11
+ def rand_str length
12
+ rand = "";
13
+ length.times {
14
+ rand << @rands.sample
15
+ }
16
+ rand
22
17
  end
23
18
 
24
19
  class Integer
@@ -27,12 +22,12 @@ class Integer
27
22
  end
28
23
  end
29
24
 
30
- def murmur_hash str
25
+ def murmur_hash str, seed
31
26
  data = str.dup.unpack("C*")
32
27
  m = 0x5bd1e995
33
28
  r = 16
34
29
  length = str.bytesize
35
- h = (length * m).to_32
30
+ h = (seed ^ (length * m).to_32).to_32
36
31
 
37
32
  while 4 <= length
38
33
  d = data.shift(4).pack("C*").unpack("I")[0]
@@ -62,34 +57,29 @@ def murmur_hash str
62
57
  h
63
58
  end
64
59
 
65
- @rands = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".split(//)
66
- def rand_str
67
- rand = "";
68
- 20.times {
69
- rand << @rands[rand(62)]
70
- }
71
- rand
72
- end
73
-
74
60
  n = 100000
75
61
  times_enum = n.times
76
62
 
77
63
  a = Array.new(n, 0)
78
64
  n.times do |i|
79
- a[i] = rand_str
65
+ a[i] = rand_str 20
80
66
  end
81
-
67
+ seed = rand(2**32)
68
+ seed_str32 = [seed].pack("L")
69
+ seed_str64 = [seed].pack("Q")
82
70
  c = Struct.new "Cases",
83
71
  :name,
84
72
  :func
85
73
  cases = [
86
- c.new("pureRuby", proc{|x| murmur_hash x }),
87
- c.new("Prime37", proc{|x| Prime37.digest x }),
88
- c.new("MurmurHash1", proc{|x| Digest::MurmurHash1.rawdigest x }),
89
- c.new("MurmurHash2", proc{|x| Digest::MurmurHash2.rawdigest x }),
90
- c.new("MurmurHash2A", proc{|x| Digest::MurmurHash2A.rawdigest x }),
74
+ c.new("pureRuby", proc{|x| murmur_hash x, seed }),
75
+ c.new("MurmurHash1", proc{|x| Digest::MurmurHash1.rawdigest x, seed_str32 }),
76
+ c.new("MurmurHash2", proc{|x| Digest::MurmurHash2.rawdigest x, seed_str32 }),
77
+ c.new("MurmurHash2A", proc{|x| Digest::MurmurHash2A.rawdigest x, seed_str32 }),
78
+ c.new("MurmurHash64A", proc{|x| Digest::MurmurHash64A.rawdigest x, seed_str64 }),
79
+ c.new("MurmurHash64B", proc{|x| Digest::MurmurHash64B.rawdigest x, seed_str64 }),
80
+ c.new("MurmurHashNeutral2", proc{|x| Digest::MurmurHashNeutral2.rawdigest x, seed_str32 }),
81
+ c.new("MurmurHashAligned2", proc{|x| Digest::MurmurHashAligned2.rawdigest x, seed_str32 }),
91
82
  ]
92
-
93
83
  reals = {}
94
84
  confrict = {}
95
85
  confricts = {}
@@ -1,48 +1,68 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "Digest::MurmurHash1 and 2" do
4
- let :all do
5
- [MurmurHash1, MurmurHash2, MurmurHash2A]
3
+ describe Digest::MurmurHash do
4
+ it "seed" do
5
+ all.each do |c|
6
+ m = c.new
7
+ expect(c::DEFAULT_SEED == m.seed).to be true
8
+ end
6
9
  end
7
10
 
8
- it "initialize" do
9
- expect(MurmurHash1.new).to be_a_kind_of(Digest::StringBuffer)
10
- expect(MurmurHash2.new).to be_a_kind_of(Digest::StringBuffer)
11
- expect(MurmurHash2A.new).to be_a_kind_of(Digest::StringBuffer)
11
+ it "seed=" do
12
+ all.each do |c|
13
+ m = c.new
14
+ m.update "murmurhash"
15
+ before_digest = m.hexdigest
16
+ m.seed = (c::DEFAULT_SEED.length == 4) ? seed32 : seed64
17
+ expect(c::DEFAULT_SEED != m.seed).to be true
18
+ expect(before_digest != m.hexdigest).to be true
19
+ end
12
20
  end
13
21
 
14
- it "digest" do
15
- expect(MurmurHash1.digest("a" * 1024)).to eq("\xa1\x52\x2e\x5f".force_encoding("ASCII-8BIT"))
16
- expect(MurmurHash2.digest("a" * 1024)).to eq("\xd0\x0c\x31\x2f".force_encoding("ASCII-8BIT"))
17
- expect(MurmurHash2A.digest("a" * 1024)).to eq("\xd5\x2d\xb1\x67".force_encoding("ASCII-8BIT"))
22
+ it "initialize" do
23
+ all.each do |c|
24
+ expect(c.new).to be_a_kind_of(Digest::StringBuffer)
25
+ end
18
26
  end
19
27
 
20
- it "hexdigest" do
21
- expect(MurmurHash1.hexdigest("a" * 1024)).to eq("a1522e5f")
22
- expect(MurmurHash2.hexdigest("a" * 1024)).to eq("d00c312f")
23
- expect(MurmurHash2A.hexdigest("a" * 1024)).to eq("d52db167")
28
+ it "digest and hexdigest" do
29
+ all.each do |c|
30
+ [:digest, :hexdigest].each do |method|
31
+ str = "a" * 1024
32
+ d = c.send(method, str)
33
+ d2 = c.send(method, str, (c::DEFAULT_SEED.length == 4) ? seed32 : seed64)
34
+ expect(d).to be_a_kind_of(String)
35
+ expect(d2).to be_a_kind_of(String)
36
+ expect(d.length).to be > 0
37
+ expect(d2.length).to be > 0
38
+ expect(d != d2).to be true
39
+ end
40
+ end
24
41
  end
25
42
 
26
43
  it "rawdigest" do
27
- expect(MurmurHash1.rawdigest("a" * 1024)).to eq(0xa1522e5f)
28
- expect(MurmurHash2.rawdigest("a" * 1024)).to eq(0xd00c312f)
29
- expect(MurmurHash2A.rawdigest("a" * 1024)).to eq(0xd52db167)
44
+ all.each do |c|
45
+ str = "a" * 1024
46
+ d = c.rawdigest str
47
+ d2 = c.rawdigest str, (c::DEFAULT_SEED.length == 4) ? seed32 : seed64
48
+ expect(d).to be_a_kind_of(Integer)
49
+ expect(d2).to be_a_kind_of(Integer)
50
+ expect(d).to be > 0
51
+ expect(d2).to be > 0
52
+ expect(d != d2).to be true
53
+ end
30
54
  end
31
55
 
32
- it "update and reset and hexdigest" do
33
- {
34
- MurmurHash1 => "c709abd5",
35
- MurmurHash2 => "33f67c7e",
36
- MurmurHash2A => "df25554b",
37
- }.each do |c, should|
56
+ it "update and reset and hexdigest(32bit)" do
57
+ all.each do |c|
38
58
  murmur = c.new
39
59
  murmur.update("m").update("u").update("r")
40
60
  murmur << "m" << "u" << "r"
41
61
  murmur << "hash"
42
- expect(murmur.hexdigest).to eq(should);
43
- expect(murmur.hexdigest).to eq(should);
44
- expect(murmur.hexdigest!).to eq(should);
45
- expect(murmur.hexdigest).to eq("00000000");
62
+ hex = murmur.hexdigest
63
+ expect(murmur.hexdigest! == hex).to be true
64
+ reset_str = "0" * ((c::DEFAULT_SEED.length == 4) ? 8 : 16)
65
+ expect(murmur.hexdigest).to eq(reset_str)
46
66
  end
47
67
  end
48
68
 
@@ -69,14 +89,14 @@ describe "Digest::MurmurHash1 and 2" do
69
89
  end
70
90
 
71
91
  it "length" do
72
- expect(MurmurHash1.new.length).to eq(4);
73
- expect(MurmurHash2.new.length).to eq(4);
74
- expect(MurmurHash2A.new.length).to eq(4);
92
+ all.each do |c|
93
+ expect(c.new.length == c::DEFAULT_SEED.length).to be true
94
+ end
75
95
  end
76
96
 
77
97
  it "to_i" do
78
- expect(MurmurHash1.new.update("murmurhash").to_i).to eq(0xc709abd5);
79
- expect(MurmurHash2.new.update("murmurhash").to_i).to eq(0x33f67c7e);
80
- expect(MurmurHash2A.new.update("murmurhash").to_i).to eq(0xdf25554b);
98
+ all.each do |c|
99
+ expect(c.new.update("murmurhash").to_i).to be_a_kind_of(Integer)
100
+ end
81
101
  end
82
102
  end
@@ -1,10 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe MurmurHash do
4
- let :all do
5
- [MurmurHash1, MurmurHash2, MurmurHash2A]
6
- end
7
-
8
4
  it "update nil" do
9
5
  all.each do |c|
10
6
  murmur = c.new
@@ -17,4 +13,23 @@ describe MurmurHash do
17
13
  expect{ c.rawdigest }.to raise_error(ArgumentError)
18
14
  end
19
15
  end
16
+
17
+ it "seed digest" do
18
+ all.each do |c|
19
+ expect{ c.digest "", ""}.to raise_error(ArgumentError)
20
+ expect{ c.digest "", "\x00" }.to raise_error(ArgumentError)
21
+ seed = (c::DEFAULT_SEED.bytesize == 4) ? seed32 : seed64
22
+ expect{ c.digest "", seed }.to_not raise_error
23
+ end
24
+ end
25
+
26
+ it "seed instance" do
27
+ all.each do |c|
28
+ murmur = c.new
29
+ expect{ murmur.seed = "" }.to raise_error(ArgumentError)
30
+ expect{ murmur.seed = "\x00" }.to raise_error(ArgumentError)
31
+ seed = (c::DEFAULT_SEED.bytesize == 4) ? seed32 : seed64
32
+ expect{ murmur.seed = seed }.to_not raise_error
33
+ end
34
+ end
20
35
  end
@@ -2,16 +2,13 @@ require 'spec_helper'
2
2
 
3
3
  describe MurmurHash do
4
4
  it "gc safe" do
5
- {
6
- MurmurHash1 => "c709abd5",
7
- MurmurHash2 => "33f67c7e",
8
- MurmurHash2A => "df25554b",
9
- }.each do |c, should|
5
+ all.each do |c|
10
6
  murmur = c.new
7
+ init = murmur.to_s
11
8
  GC.start
12
9
  murmur.update("murmur")
13
10
  GC.start
14
- expect(murmur.update("hash").to_s).to eq(should);
11
+ expect(murmur.update("hash").to_s != init).to be true
15
12
  end
16
13
  end
17
14
  end
@@ -1,2 +1,23 @@
1
1
  require 'digest/murmurhash'
2
2
  include Digest
3
+
4
+ def all
5
+ [
6
+ MurmurHash1,
7
+ MurmurHash2,
8
+ MurmurHash2A,
9
+ MurmurHash64A,
10
+ MurmurHash64B,
11
+ MurmurHashNeutral2,
12
+ MurmurHashAligned2
13
+ ]
14
+ end
15
+
16
+ def seed32
17
+ (0..4).to_a.pack("C4")
18
+ end
19
+
20
+ def seed64
21
+ (0..8).to_a.pack("C8")
22
+ end
23
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: digest-murmurhash
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ksss
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-25 00:00:00.000000000 Z
11
+ date: 2014-01-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: digest-stringbuffer
@@ -72,15 +72,15 @@ dependencies:
72
72
  requirements:
73
73
  - - ~>
74
74
  - !ruby/object:Gem::Version
75
- version: 0.9.2
75
+ version: 0.8.3
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - ~>
81
81
  - !ruby/object:Gem::Version
82
- version: 0.9.2
83
- description: Digest::MurmurHash1 is a class of use algorithm MurmurHash1(32-bit) desiged
82
+ version: 0.8.3
83
+ description: Digest::MurmurHash is class collections of use algorithm MurmurHash desiged
84
84
  by Austin Appleby.
85
85
  email: co000ri@gmail.com
86
86
  executables: []
@@ -96,7 +96,7 @@ files:
96
96
  - Rakefile
97
97
  - digest-murmurhash.gemspec
98
98
  - ext/digest/murmurhash/extconf.rb
99
- - ext/digest/murmurhash/init.c
99
+ - ext/digest/murmurhash/murmurhash.c
100
100
  - ext/digest/murmurhash/murmurhash.h
101
101
  - ext/digest/murmurhash/murmurhash1.c
102
102
  - ext/digest/murmurhash/murmurhash1.h
@@ -104,6 +104,14 @@ files:
104
104
  - ext/digest/murmurhash/murmurhash2.h
105
105
  - ext/digest/murmurhash/murmurhash2a.c
106
106
  - ext/digest/murmurhash/murmurhash2a.h
107
+ - ext/digest/murmurhash/murmurhash64a.c
108
+ - ext/digest/murmurhash/murmurhash64a.h
109
+ - ext/digest/murmurhash/murmurhash64b.c
110
+ - ext/digest/murmurhash/murmurhash64b.h
111
+ - ext/digest/murmurhash/murmurhash_aligned2.c
112
+ - ext/digest/murmurhash/murmurhash_aligned2.h
113
+ - ext/digest/murmurhash/murmurhash_neutral2.c
114
+ - ext/digest/murmurhash/murmurhash_neutral2.h
107
115
  - lib/digest/murmurhash.rb
108
116
  - lib/digest/murmurhash/version.rb
109
117
  - spec/bench.rb
@@ -134,7 +142,7 @@ rubyforge_project:
134
142
  rubygems_version: 2.1.11
135
143
  signing_key:
136
144
  specification_version: 4
137
- summary: Digest::MurmurHash1 is a class of use algorithm MurmurHash1(32-bit) desiged
145
+ summary: Digest::MurmurHash is class collections of use algorithm MurmurHash desiged
138
146
  by Austin Appleby.
139
147
  test_files:
140
148
  - spec/bench.rb