digest-murmurhash 0.0.1 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6eb394fa67dc2adc52961e3d8de2faeef0826f68
4
- data.tar.gz: 1ee189aa44955238877fcfd5978ae13fe2007185
3
+ metadata.gz: 5f158d21ca468ee7cccb9c39ba6fc57660850edd
4
+ data.tar.gz: 82730d511f8136b2ff960c0d2d99a62c9a78c339
5
5
  SHA512:
6
- metadata.gz: 438420bdde5f3cbd0082274133c1dcdf61970a427d06592be020b93120cc8b9dcf8b87f21b93647aef26bbd9b59b65ad072fbaa8984b5886a7e20b6dd06d9c1c
7
- data.tar.gz: 06d713bb5248de042c7539f99258b4d642bc4d941145ccf07a4cd08e8d62eb4e96c14031b8eb44eb516cb9a234dcccc23906158afad8ef40f76b9295818809eb
6
+ metadata.gz: 4494bc8ee54eb5bc525c9c8d5a8f275c299b73350fd0f6fcb638e7272fb546cab8d5bd5867cab5f388845ddc2eeec11302c8d982ea1e0e5bb33cc2b50b127d28
7
+ data.tar.gz: 20cc99086cc26e5ba616a9d179aa11121f88704a8effb6a417dd3cc58032b8c0fb89a21818c1bf790bfd7dde3b94a0477cd67d74d0fe860c882e339ddfd3c1b8
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![Build Status](https://travis-ci.org/ksss/digest-murmurhash.png?branch=master)](https://travis-ci.org/ksss/digest-murmurhash)
4
4
 
5
- Digest::MurmurHash is a class use algorithm of MurmurHash(MurmurHash1 32-bit) desiged by Austin Appleby.
5
+ Digest::MurmurHash is a class of use algorithm MurmurHash(MurmurHash1 32-bit) desiged by Austin Appleby.
6
6
 
7
7
  Digest::MurmurHash compliance Digest API of Ruby.
8
8
 
@@ -16,7 +16,7 @@ You can use same interface built in Digest::XXX classes.
16
16
  require 'digest/murmurhash'
17
17
 
18
18
  p Digest::MurmurHash.hexdigest('murmurhash') #=> 'c709abd5'
19
- p Digest::MurmurHash.file("./LICENSE.txt") #=> '712e9641'
19
+ p Digest::MurmurHash.file("./LICENSE.txt").hexdigest #=> '712e9641'
20
20
  ```
21
21
 
22
22
  ## Class tree
@@ -6,11 +6,11 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "digest-murmurhash"
8
8
  # FIXME replace Digest::MurmurHash::VERSION but raise NameError
9
- spec.version = "0.0.1"
9
+ spec.version = "0.1.0"
10
10
  spec.author = "ksss"
11
11
  spec.email = "co000ri@gmail.com"
12
- spec.description = %q{The MurmurHash.}
13
- spec.summary = %q{The MurmurHash create by Austin Appleby.}
12
+ spec.description = %q{Digest::MurmurHash is a class of use algorithm MurmurHash(MurmurHash1 32-bit) desiged by Austin Appleby.}
13
+ spec.summary = %q{Digest::MurmurHash is a class of use algorithm MurmurHash(MurmurHash1 32-bit) desiged by Austin Appleby.}
14
14
  spec.homepage = ""
15
15
  spec.license = "MIT"
16
16
 
@@ -12,7 +12,9 @@
12
12
  ID id_concat;
13
13
 
14
14
  typedef struct {
15
- VALUE data;
15
+ char* data;
16
+ char* p;
17
+ size_t memsize;
16
18
  } murmur_t;
17
19
 
18
20
  #define MURMURHASH(self, name) \
@@ -25,19 +27,20 @@ typedef struct {
25
27
  static void
26
28
  murmur_init(murmur_t* ptr)
27
29
  {
28
- ptr->data = rb_str_new("", 0);
30
+ ptr->data = (char*) malloc(sizeof(char) * 64);
31
+ ptr->p = ptr->data;
32
+ ptr->memsize = 64;
29
33
  }
30
34
 
31
35
  static void
32
36
  murmur_mark(murmur_t* ptr)
33
37
  {
34
- rb_gc_mark(ptr->data);
35
38
  }
36
39
 
37
40
  static void
38
41
  murmur_free(murmur_t* ptr)
39
42
  {
40
- xfree(ptr);
43
+ free(ptr->data);
41
44
  }
42
45
 
43
46
  static VALUE
@@ -49,50 +52,72 @@ murmur_alloc(VALUE self)
49
52
  }
50
53
 
51
54
  static VALUE
52
- murmur_initialize_copy(VALUE self, VALUE obj)
55
+ murmur_initialize_copy(VALUE copy, VALUE origin)
53
56
  {
54
- if (self == obj) return self;
57
+ murmur_t *ptr_copy, *ptr_origin;
58
+ size_t data_len;
55
59
 
56
- MURMURHASH(self, pctx1);
57
- MURMURHASH(obj, pctx2);
60
+ if (copy == origin) return copy;
58
61
 
59
- rb_check_frozen(self);
62
+ rb_check_frozen(copy);
60
63
 
61
- memcpy(pctx1, pctx2, sizeof(murmur_t));
64
+ Data_Get_Struct(copy, murmur_t, ptr_copy);
65
+ Data_Get_Struct(origin, murmur_t, ptr_origin);
62
66
 
63
- return self;
67
+ data_len = ptr_origin->p - ptr_origin->data;
68
+ ptr_copy->data = (char*) malloc(sizeof(char) * ptr_origin->memsize);
69
+ memcpy(ptr_copy->data, ptr_origin->data, data_len);
70
+ ptr_copy->p = ptr_copy->data + data_len;
71
+ ptr_copy->memsize = ptr_origin->memsize;
72
+
73
+ return copy;
64
74
  }
65
75
 
66
76
  static VALUE
67
77
  murmur_reset(VALUE self)
68
78
  {
69
79
  MURMURHASH(self, ptr);
70
- murmur_init(ptr);
80
+ ptr->p = ptr->data;
71
81
  return self;
72
82
  }
73
83
 
74
84
  static VALUE
75
85
  murmur_update(VALUE self, VALUE str)
76
86
  {
87
+ size_t data_len, str_len, require, newsize;
88
+ const char* str_p;
77
89
  MURMURHASH(self, ptr);
90
+
78
91
  StringValue(str);
79
- rb_funcall(ptr->data, id_concat, 1, str);
92
+ str_p = RSTRING_PTR(str);
93
+ str_len = RSTRING_LEN(str);
94
+ data_len = (ptr->p - ptr->data);
95
+ require = data_len + str_len;
96
+ if (ptr->memsize < require) {
97
+ newsize = ptr->memsize;
98
+ while (newsize < require) {
99
+ newsize *= 2;
100
+ }
101
+ ptr->data = realloc(ptr->data, sizeof(char) * newsize);
102
+ ptr->p = ptr->data + data_len;
103
+ ptr->memsize = newsize;
104
+ }
105
+ memcpy(ptr->p, str_p, str_len);
106
+ ptr->p += str_len;
107
+
80
108
  return self;
81
109
  }
82
110
 
83
- static VALUE
84
- murmur_finish(VALUE self)
111
+ static uint32_t
112
+ murmur_hash_process(murmur_t* ptr)
85
113
  {
86
114
  const uint32_t m = 0x5bd1e995;
87
115
  const uint8_t r = 16;
88
116
  uint32_t length, h;
89
117
  const char* p;
90
- uint8_t digest[MURMURHASH_DIGEST_LENGTH];
91
-
92
- MURMURHASH(self, ptr);
93
118
 
94
- p = RSTRING_PTR(ptr->data);
95
- length = RSTRING_LEN(ptr->data);
119
+ p = ptr->data;
120
+ length = ptr->p - ptr->data;
96
121
  h = length * m;
97
122
 
98
123
  while (4 <= length) {
@@ -119,6 +144,18 @@ murmur_finish(VALUE self)
119
144
  h *= m;
120
145
  h ^= h >> 17;
121
146
 
147
+ return h;
148
+ }
149
+
150
+ static VALUE
151
+ murmur_finish(VALUE self)
152
+ {
153
+ uint32_t h;
154
+ uint8_t digest[MURMURHASH_DIGEST_LENGTH];
155
+ MURMURHASH(self, ptr);
156
+
157
+ h = murmur_hash_process(ptr);
158
+
122
159
  digest[0] = (h >> 24);
123
160
  digest[1] = (h >> 16);
124
161
  digest[2] = (h >> 8);
@@ -139,6 +176,13 @@ murmur_block_length(VALUE self)
139
176
  return INT2NUM(MURMURHASH_BLOCK_LENGTH);
140
177
  }
141
178
 
179
+ static VALUE
180
+ murmur_to_i(VALUE self)
181
+ {
182
+ MURMURHASH(self, ptr);
183
+ return UINT2NUM(murmur_hash_process(ptr));
184
+ }
185
+
142
186
  void
143
187
  Init_murmurhash()
144
188
  {
@@ -160,4 +204,6 @@ Init_murmurhash()
160
204
  rb_define_private_method(cDigest_MurmurHash, "finish", murmur_finish, 0);
161
205
  rb_define_method(cDigest_MurmurHash, "digest_length", murmur_digest_length, 0);
162
206
  rb_define_method(cDigest_MurmurHash, "block_length", murmur_block_length, 0);
207
+
208
+ rb_define_method(cDigest_MurmurHash, "to_i", murmur_to_i, 0);
163
209
  }
@@ -1,5 +1,5 @@
1
1
  module Digest
2
2
  class MurmurHash
3
- VERSION = "0.0.1"
3
+ VERSION = "0.1.0"
4
4
  end
5
5
  end
data/spec/bench.rb ADDED
@@ -0,0 +1,73 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ lib = File.expand_path('../../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ require 'digest/murmurhash'
7
+ require 'benchmark'
8
+
9
+ class Integer
10
+ def to_32
11
+ self & 0xffffffff
12
+ end
13
+ end
14
+
15
+ def murmur_hash str
16
+ data = str.dup.unpack("C*")
17
+ m = 0x5bd1e995
18
+ r = 16
19
+ length = str.bytesize
20
+ h = (length * m).to_32
21
+
22
+ while 4 <= length
23
+ d = data.shift(4).pack("C*").unpack("I")[0]
24
+ h = (h + d).to_32
25
+ h = (h * m).to_32
26
+ h ^= h >> r
27
+ length -= 4
28
+ end
29
+
30
+ if 2 < length
31
+ h = (h + (data[2] << 16).to_32).to_32
32
+ end
33
+ if 1 < length
34
+ h = (h + (data[1] << 8).to_32).to_32
35
+ end
36
+ if 0 < length
37
+ h = (h + data[0]).to_32
38
+ h = (h * m).to_32
39
+ h ^= h >> r
40
+ end
41
+
42
+ h = (h * m).to_32
43
+ h ^= h >> 10
44
+ h = (h * m).to_32
45
+ h ^= h >> 17
46
+
47
+ h.to_32
48
+ end
49
+
50
+ def rand_str
51
+ rand = "";
52
+ File.open("/dev/urandom").read(20).each_byte{|x| rand << sprintf("%02x",x)}
53
+ rand
54
+ end
55
+
56
+ s = rand_str
57
+ p [murmur_hash(s)].pack("N")
58
+ p Digest::MurmurHash.digest(s)
59
+
60
+ Benchmark.bm do |x|
61
+ n = 10000
62
+ a = []
63
+ n.times { |i|
64
+ a[i] = rand_str
65
+ }
66
+
67
+ x.report {n.times{ |i|
68
+ [murmur_hash(a[i])].pack("N")
69
+ }}
70
+ x.report {n.times{ |i|
71
+ Digest::MurmurHash.digest(a[i])
72
+ }}
73
+ end
data/spec/digest_spec.rb CHANGED
@@ -53,4 +53,8 @@ describe Digest::MurmurHash do
53
53
  # Therefore `block_length` return chunk size for calculate MurmurHash (equal 4)
54
54
  expect(murmur.block_length).to eq(4);
55
55
  end
56
+
57
+ it "to_i" do
58
+ expect(murmur.update("murmurhash").to_i).to eq(0xc709abd5);
59
+ end
56
60
  end
data/spec/mem_spec.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require 'spec_helper'
2
+
1
3
  describe Digest::MurmurHash do
2
4
  it "gc safe" do
3
5
  murmur = Digest::MurmurHash.new
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.0.1
4
+ version: 0.1.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-01 00:00:00.000000000 Z
11
+ date: 2013-12-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,7 +66,8 @@ dependencies:
66
66
  - - ~>
67
67
  - !ruby/object:Gem::Version
68
68
  version: 0.8.3
69
- description: The MurmurHash.
69
+ description: Digest::MurmurHash is a class of use algorithm MurmurHash(MurmurHash1
70
+ 32-bit) desiged by Austin Appleby.
70
71
  email: co000ri@gmail.com
71
72
  executables: []
72
73
  extensions:
@@ -83,6 +84,7 @@ files:
83
84
  - ext/digest/murmurhash/extconf.rb
84
85
  - ext/digest/murmurhash/murmurhash.c
85
86
  - lib/digest/murmurhash/version.rb
87
+ - spec/bench.rb
86
88
  - spec/digest_spec.rb
87
89
  - spec/mem_spec.rb
88
90
  - spec/spec_helper.rb
@@ -109,8 +111,10 @@ rubyforge_project:
109
111
  rubygems_version: 2.1.6
110
112
  signing_key:
111
113
  specification_version: 4
112
- summary: The MurmurHash create by Austin Appleby.
114
+ summary: Digest::MurmurHash is a class of use algorithm MurmurHash(MurmurHash1 32-bit)
115
+ desiged by Austin Appleby.
113
116
  test_files:
117
+ - spec/bench.rb
114
118
  - spec/digest_spec.rb
115
119
  - spec/mem_spec.rb
116
120
  - spec/spec_helper.rb