cityhash 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ *.so
2
+ *.bundle
3
+ .bundle
4
+ Gemfile.lock
5
+ pkg/*
6
+ tmp/*
7
+ vendor/bundle
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
data/Gemfile CHANGED
@@ -1,10 +1,7 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem "ffi"
3
+ gemspec
4
4
 
5
- group :development do
6
- gem "shoulda", ">= 0"
7
- gem "bundler", "~> 1.0.0"
8
- gem "jeweler", "~> 1.5.2"
9
- gem "rcov", ">= 0"
10
- end
5
+ gem 'rake'
6
+ gem 'rake-compiler'
7
+ gem 'minitest', '~> 2.11.0'
data/README.md CHANGED
@@ -1,27 +1,29 @@
1
- ### cityhash
1
+ ### cityhash [![TravisCI](https://secure.travis-ci.org/nashby/cityhash.png?branch=master)](http://travis-ci.org/nashby/cityhash)
2
2
 
3
3
  Ruby wrapper for google's cityhash.
4
4
 
5
5
  ### Install
6
-
6
+
7
7
  gem install cityhash
8
8
 
9
9
  ### Usage
10
10
 
11
- require 'cityhash'
12
-
13
- text = "test"
14
- seed1 = 12345
15
- seed2 = 54321
16
-
17
- CityHash.hash64(text) # => 17703940110308125106
18
- CityHash.hash64(text, seed1) # => 14900027982776226655
19
- CityHash.hash64(text, seed1, seed2) # => 11136353178704814373
20
- CityHash.hash128(text) # => 130554790001792308794529643941127319555
21
- CityHash.hash128(text, seed1) # => 1238187875708097619810923284135194760226
22
-
11
+ ```ruby
12
+ require 'cityhash'
13
+
14
+ text = "test"
15
+ seed1 = 12345
16
+ seed2 = 54321
17
+
18
+ CityHash.hash64(text) # => 17703940110308125106
19
+ CityHash.hash64(text, seed1) # => 14900027982776226655
20
+ CityHash.hash64(text, seed1, seed2) # => 11136353178704814373
21
+ CityHash.hash128(text) # => 1800071687761605184910580728449884026697
22
+ CityHash.hash128(text, seed1) # => 6087407617808651818174120599816915369
23
+ ```
24
+
23
25
  ### Contributing to cityhash
24
-
26
+
25
27
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
26
28
  * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
27
29
  * Fork the project
@@ -34,10 +36,13 @@ Ruby wrapper for google's cityhash.
34
36
 
35
37
  #### [Contributors](http://github.com/nashby/cityhash/contributors)
36
38
  - [Johannes Holzfuß](http://github.com/DataWraith)
39
+ - [Quin Hoxie](https://github.com/qhoxie)
40
+ - [David Dai](https://github.com/newtonapple)
41
+ - [Sergey Nartimov](https://github.com/lest)
37
42
 
38
43
  [Vasiliy Ermolovich](http://github.com/nashby/)<br/>
39
44
 
40
45
  ### Copyright
41
46
 
42
- Copyright (c) 2011 nashby. See LICENSE.txt for
47
+ Copyright (c) 2012 Vasiliy Ermolovich. See LICENSE.txt for
43
48
  further details.
data/Rakefile CHANGED
@@ -1,54 +1,20 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- begin
4
- Bundler.setup(:default, :development)
5
- rescue Bundler::BundlerError => e
6
- $stderr.puts e.message
7
- $stderr.puts "Run `bundle install` to install missing gems"
8
- exit e.status_code
9
- end
10
- require 'rake'
11
-
12
- $LOAD_PATH.unshift('lib')
13
-
14
- require 'jeweler'
15
- require 'cityhash/version'
16
- Jeweler::Tasks.new do |gem|
17
- # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
18
- gem.name = "cityhash"
19
- gem.homepage = "http://github.com/nashby/cityhash"
20
- gem.license = "MIT"
21
- gem.version = CityHash::Version::STRING
22
- gem.summary = "ffi wrapper for google's cityhash"
23
- gem.description = "ffi wrapper for google's cityhash"
24
- gem.email = "younash@gmail.com"
25
- gem.authors = ["nashby"]
26
- gem.add_runtime_dependency 'ffi'
27
- end
28
- Jeweler::RubygemsDotOrgTasks.new
1
+ require "bundler/gem_tasks"
29
2
 
30
3
  require 'rake/testtask'
31
- Rake::TestTask.new(:test) do |test|
32
- test.libs << 'lib' << 'test'
33
- test.pattern = 'test/**/test_*.rb'
34
- test.verbose = true
35
- end
4
+ require 'rake/clean'
36
5
 
37
- require 'rcov/rcovtask'
38
- Rcov::RcovTask.new do |test|
39
- test.libs << 'test'
40
- test.pattern = 'test/**/test_*.rb'
41
- test.verbose = true
6
+ Rake::TestTask.new do |t|
7
+ t.libs << 'test'
8
+ t.pattern = 'test/*_test.rb'
9
+ t.verbose = true
42
10
  end
43
11
 
12
+ desc "Run tests"
44
13
  task :default => :test
45
14
 
46
- require 'rake/rdoctask'
47
- Rake::RDocTask.new do |rdoc|
48
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
49
-
50
- rdoc.rdoc_dir = 'rdoc'
51
- rdoc.title = "cityhash #{version}"
52
- rdoc.rdoc_files.include('README*')
53
- rdoc.rdoc_files.include('lib/**/*.rb')
15
+ require 'rake/extensiontask'
16
+ Rake::ExtensionTask.new('cityhash') do |ext|
17
+ ext.lib_dir = 'lib/cityhash'
54
18
  end
19
+
20
+ Rake::Task[:test].prerequisites << :compile
@@ -1,75 +1,21 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
1
  # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "cityhash/version"
5
4
 
6
5
  Gem::Specification.new do |s|
7
- s.name = %q{cityhash}
8
- s.version = "0.5.0"
6
+ s.name = "cityhash"
7
+ s.version = CityHash::VERSION
8
+ s.authors = ["Vasiliy Ermolovich"]
9
+ s.email = ["younash@gmail.com"]
10
+ s.homepage = "http://github.com/nashby/cityhash"
11
+ s.summary = %q{ruby bindings for google's cityhash}
12
+ s.description = %q{ruby bindings for google's cityhash}
9
13
 
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = [%q{nashby}]
12
- s.date = %q{2011-10-28}
13
- s.description = %q{ffi wrapper for google's cityhash}
14
- s.email = %q{younash@gmail.com}
15
- s.extensions = [%q{ext/cityhash/extconf.rb}]
16
- s.extra_rdoc_files = [
17
- "LICENSE.txt",
18
- "README.md"
19
- ]
20
- s.files = [
21
- ".document",
22
- "Gemfile",
23
- "Gemfile.lock",
24
- "LICENSE.txt",
25
- "README.md",
26
- "Rakefile",
27
- "cityhash.gemspec",
28
- "ext/cityhash/city.cc",
29
- "ext/cityhash/city.h",
30
- "ext/cityhash/city_ruby_bridge.cpp",
31
- "ext/cityhash/city_ruby_bridge.h",
32
- "ext/cityhash/extconf.rb",
33
- "lib/cityhash.rb",
34
- "lib/cityhash/version.rb",
35
- "test/helper.rb",
36
- "test/test_cityhash.rb"
37
- ]
38
- s.homepage = %q{http://github.com/nashby/cityhash}
39
- s.licenses = [%q{MIT}]
40
- s.require_paths = [%q{lib}]
41
- s.rubygems_version = %q{1.8.6}
42
- s.summary = %q{ffi wrapper for google's cityhash}
43
- s.test_files = [
44
- "test/helper.rb",
45
- "test/test_cityhash.rb"
46
- ]
14
+ s.rubyforge_project = "cityhash"
47
15
 
48
- if s.respond_to? :specification_version then
49
- s.specification_version = 3
50
-
51
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
52
- s.add_runtime_dependency(%q<ffi>, [">= 0"])
53
- s.add_development_dependency(%q<shoulda>, [">= 0"])
54
- s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
55
- s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
56
- s.add_development_dependency(%q<rcov>, [">= 0"])
57
- s.add_runtime_dependency(%q<ffi>, [">= 0"])
58
- else
59
- s.add_dependency(%q<ffi>, [">= 0"])
60
- s.add_dependency(%q<shoulda>, [">= 0"])
61
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
62
- s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
63
- s.add_dependency(%q<rcov>, [">= 0"])
64
- s.add_dependency(%q<ffi>, [">= 0"])
65
- end
66
- else
67
- s.add_dependency(%q<ffi>, [">= 0"])
68
- s.add_dependency(%q<shoulda>, [">= 0"])
69
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
70
- s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
71
- s.add_dependency(%q<rcov>, [">= 0"])
72
- s.add_dependency(%q<ffi>, [">= 0"])
73
- end
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+ s.extensions = ["ext/cityhash/extconf.rb"]
74
21
  end
75
-
@@ -18,7 +18,7 @@
18
18
  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
19
  // THE SOFTWARE.
20
20
  //
21
- // CityHash Version 1, by Geoff Pike and Jyrki Alakuijala
21
+ // CityHash, by Geoff Pike and Jyrki Alakuijala
22
22
  //
23
23
  // This file provides CityHash64() and related functions.
24
24
  //
@@ -30,20 +30,65 @@
30
30
  #include "city.h"
31
31
 
32
32
  #include <algorithm>
33
+ #include <string.h> // for memcpy and memset
33
34
 
34
35
  using namespace std;
35
36
 
36
- #define UNALIGNED_LOAD64(p) (*(const uint64*)(p))
37
- #define UNALIGNED_LOAD32(p) (*(const uint32*)(p))
37
+ static uint64 UNALIGNED_LOAD64(const char *p) {
38
+ uint64 result;
39
+ memcpy(&result, p, sizeof(result));
40
+ return result;
41
+ }
42
+
43
+ static uint32 UNALIGNED_LOAD32(const char *p) {
44
+ uint32 result;
45
+ memcpy(&result, p, sizeof(result));
46
+ return result;
47
+ }
48
+
49
+ #if !defined(WORDS_BIGENDIAN)
50
+
51
+ #define uint32_in_expected_order(x) (x)
52
+ #define uint64_in_expected_order(x) (x)
53
+
54
+ #else
55
+
56
+ #ifdef _MSC_VER
57
+ #include <stdlib.h>
58
+ #define bswap_32(x) _byteswap_ulong(x)
59
+ #define bswap_64(x) _byteswap_uint64(x)
60
+
61
+ #elif defined(__APPLE__)
62
+ // Mac OS X / Darwin features
63
+ #include <libkern/OSByteOrder.h>
64
+ #define bswap_32(x) OSSwapInt32(x)
65
+ #define bswap_64(x) OSSwapInt64(x)
66
+
67
+ #else
68
+ #include <byteswap.h>
69
+ #endif
70
+
71
+ #define uint32_in_expected_order(x) (bswap_32(x))
72
+ #define uint64_in_expected_order(x) (bswap_64(x))
73
+
74
+ #endif // WORDS_BIGENDIAN
38
75
 
39
76
  #if !defined(LIKELY)
40
- #if defined(__GNUC__)
77
+ #if HAVE_BUILTIN_EXPECT
41
78
  #define LIKELY(x) (__builtin_expect(!!(x), 1))
42
79
  #else
43
80
  #define LIKELY(x) (x)
44
81
  #endif
45
82
  #endif
46
83
 
84
+ static uint64 Fetch64(const char *p) {
85
+ return uint64_in_expected_order(UNALIGNED_LOAD64(p));
86
+ }
87
+
88
+ static uint32 Fetch32(const char *p) {
89
+ return uint32_in_expected_order(UNALIGNED_LOAD32(p));
90
+ }
91
+
47
92
  // Some primes between 2^63 and 2^64 for various uses.
48
93
  static const uint64 k0 = 0xc3a5c85c97cb3127ULL;
49
94
  static const uint64 k1 = 0xb492b66fbe98f273ULL;
@@ -74,13 +119,13 @@ static uint64 HashLen16(uint64 u, uint64 v) {
74
119
 
75
120
  static uint64 HashLen0to16(const char *s, size_t len) {
76
121
  if (len > 8) {
77
- uint64 a = UNALIGNED_LOAD64(s);
78
- uint64 b = UNALIGNED_LOAD64(s + len - 8);
122
+ uint64 a = Fetch64(s);
123
+ uint64 b = Fetch64(s + len - 8);
79
124
  return HashLen16(a, RotateByAtLeast1(b + len, len)) ^ b;
80
125
  }
81
126
  if (len >= 4) {
82
- uint64 a = UNALIGNED_LOAD32(s);
83
- return HashLen16(len + (a << 3), UNALIGNED_LOAD32(s + len - 4));
127
+ uint64 a = Fetch32(s);
128
+ return HashLen16(len + (a << 3), Fetch32(s + len - 4));
84
129
  }
85
130
  if (len > 0) {
86
131
  uint8 a = s[0];
@@ -96,10 +141,10 @@ static uint64 HashLen0to16(const char *s, size_t len) {
96
141
  // This probably works well for 16-byte strings as well, but it may be overkill
97
142
  // in that case.
98
143
  static uint64 HashLen17to32(const char *s, size_t len) {
99
- uint64 a = UNALIGNED_LOAD64(s) * k1;
100
- uint64 b = UNALIGNED_LOAD64(s + 8);
101
- uint64 c = UNALIGNED_LOAD64(s + len - 8) * k2;
102
- uint64 d = UNALIGNED_LOAD64(s + len - 16) * k0;
144
+ uint64 a = Fetch64(s) * k1;
145
+ uint64 b = Fetch64(s + 8);
146
+ uint64 c = Fetch64(s + len - 8) * k2;
147
+ uint64 d = Fetch64(s + len - 16) * k0;
103
148
  return HashLen16(Rotate(a - b, 43) + Rotate(c, 30) + d,
104
149
  a + Rotate(b ^ k3, 20) - c + len);
105
150
  }
@@ -120,32 +165,32 @@ static pair<uint64, uint64> WeakHashLen32WithSeeds(
120
165
  // Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty.
121
166
  static pair<uint64, uint64> WeakHashLen32WithSeeds(
122
167
  const char* s, uint64 a, uint64 b) {
123
- return WeakHashLen32WithSeeds(UNALIGNED_LOAD64(s),
124
- UNALIGNED_LOAD64(s + 8),
125
- UNALIGNED_LOAD64(s + 16),
126
- UNALIGNED_LOAD64(s + 24),
168
+ return WeakHashLen32WithSeeds(Fetch64(s),
169
+ Fetch64(s + 8),
170
+ Fetch64(s + 16),
171
+ Fetch64(s + 24),
127
172
  a,
128
173
  b);
129
174
  }
130
175
 
131
176
  // Return an 8-byte hash for 33 to 64 bytes.
132
177
  static uint64 HashLen33to64(const char *s, size_t len) {
133
- uint64 z = UNALIGNED_LOAD64(s + 24);
134
- uint64 a = UNALIGNED_LOAD64(s) + (len + UNALIGNED_LOAD64(s + len - 16)) * k0;
178
+ uint64 z = Fetch64(s + 24);
179
+ uint64 a = Fetch64(s) + (len + Fetch64(s + len - 16)) * k0;
135
180
  uint64 b = Rotate(a + z, 52);
136
181
  uint64 c = Rotate(a, 37);
137
- a += UNALIGNED_LOAD64(s + 8);
182
+ a += Fetch64(s + 8);
138
183
  c += Rotate(a, 7);
139
- a += UNALIGNED_LOAD64(s + 16);
184
+ a += Fetch64(s + 16);
140
185
  uint64 vf = a + z;
141
186
  uint64 vs = b + Rotate(a, 31) + c;
142
- a = UNALIGNED_LOAD64(s + 16) + UNALIGNED_LOAD64(s + len - 32);
143
- z = UNALIGNED_LOAD64(s + len - 8);
187
+ a = Fetch64(s + 16) + Fetch64(s + len - 32);
188
+ z = Fetch64(s + len - 8);
144
189
  b = Rotate(a + z, 52);
145
190
  c = Rotate(a, 37);
146
- a += UNALIGNED_LOAD64(s + len - 24);
191
+ a += Fetch64(s + len - 24);
147
192
  c += Rotate(a, 7);
148
- a += UNALIGNED_LOAD64(s + len - 16);
193
+ a += Fetch64(s + len - 16);
149
194
  uint64 wf = a + z;
150
195
  uint64 ws = b + Rotate(a, 31) + c;
151
196
  uint64 r = ShiftMix((vf + ws) * k2 + (wf + vs) * k0);
@@ -165,25 +210,23 @@ uint64 CityHash64(const char *s, size_t len) {
165
210
 
166
211
  // For strings over 64 bytes we hash the end first, and then as we
167
212
  // loop we keep 56 bytes of state: v, w, x, y, and z.
168
- uint64 x = UNALIGNED_LOAD64(s);
169
- uint64 y = UNALIGNED_LOAD64(s + len - 16) ^ k1;
170
- uint64 z = UNALIGNED_LOAD64(s + len - 56) ^ k0;
171
- pair<uint64, uint64> v = WeakHashLen32WithSeeds(s + len - 64, len, y);
172
- pair<uint64, uint64> w = WeakHashLen32WithSeeds(s + len - 32, len * k1, k0);
173
- z += ShiftMix(v.second) * k1;
174
- x = Rotate(z + x, 39) * k1;
175
- y = Rotate(y, 33) * k1;
213
+ uint64 x = Fetch64(s + len - 40);
214
+ uint64 y = Fetch64(s + len - 16) + Fetch64(s + len - 56);
215
+ uint64 z = HashLen16(Fetch64(s + len - 48) + len, Fetch64(s + len - 24));
216
+ pair<uint64, uint64> v = WeakHashLen32WithSeeds(s + len - 64, len, z);
217
+ pair<uint64, uint64> w = WeakHashLen32WithSeeds(s + len - 32, y + k1, x);
218
+ x = x * k1 + Fetch64(s);
176
219
 
177
220
  // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
178
221
  len = (len - 1) & ~static_cast<size_t>(63);
179
222
  do {
180
- x = Rotate(x + y + v.first + UNALIGNED_LOAD64(s + 16), 37) * k1;
181
- y = Rotate(y + v.second + UNALIGNED_LOAD64(s + 48), 42) * k1;
223
+ x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1;
224
+ y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1;
182
225
  x ^= w.second;
183
- y ^= v.first;
184
- z = Rotate(z ^ w.first, 33);
226
+ y += v.first + Fetch64(s + 40);
227
+ z = Rotate(z + w.first, 33) * k1;
185
228
  v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first);
186
- w = WeakHashLen32WithSeeds(s + 32, z + w.second, y);
229
+ w = WeakHashLen32WithSeeds(s + 32, z + w.second, y + Fetch64(s + 16));
187
230
  std::swap(z, x);
188
231
  s += 64;
189
232
  len -= 64;
@@ -202,25 +245,26 @@ uint64 CityHash64WithSeeds(const char *s, size_t len,
202
245
  }
203
246
 
204
247
  // A subroutine for CityHash128(). Returns a decent 128-bit hash for strings
205
- // of any length representable in ssize_t. Based on City and Murmur.
248
+ // of any length representable in signed long. Based on City and Murmur.
206
249
  static uint128 CityMurmur(const char *s, size_t len, uint128 seed) {
207
250
  uint64 a = Uint128Low64(seed);
208
251
  uint64 b = Uint128High64(seed);
209
252
  uint64 c = 0;
210
253
  uint64 d = 0;
211
- ssize_t l = len - 16;
254
+ signed long l = len - 16;
212
255
  if (l <= 0) { // len <= 16
256
+ a = ShiftMix(a * k1) * k1;
213
257
  c = b * k1 + HashLen0to16(s, len);
214
- d = Rotate(a + (len >= 8 ? UNALIGNED_LOAD64(s) : c), 32);
258
+ d = ShiftMix(a + (len >= 8 ? Fetch64(s) : c));
215
259
  } else { // len > 16
216
- c = HashLen16(UNALIGNED_LOAD64(s + len - 8) + k1, a);
217
- d = HashLen16(b + len, c + UNALIGNED_LOAD64(s + len - 16));
260
+ c = HashLen16(Fetch64(s + len - 8) + k1, a);
261
+ d = HashLen16(b + len, c + Fetch64(s + len - 16));
218
262
  a += d;
219
263
  do {
220
- a ^= ShiftMix(UNALIGNED_LOAD64(s) * k1) * k1;
264
+ a ^= ShiftMix(Fetch64(s) * k1) * k1;
221
265
  a *= k1;
222
266
  b ^= a;
223
- c ^= ShiftMix(UNALIGNED_LOAD64(s + 8) * k1) * k1;
267
+ c ^= ShiftMix(Fetch64(s + 8) * k1) * k1;
224
268
  c *= k1;
225
269
  d ^= c;
226
270
  s += 16;
@@ -243,49 +287,50 @@ uint128 CityHash128WithSeed(const char *s, size_t len, uint128 seed) {
243
287
  uint64 x = Uint128Low64(seed);
244
288
  uint64 y = Uint128High64(seed);
245
289
  uint64 z = len * k1;
246
- v.first = Rotate(y ^ k1, 49) * k1 + UNALIGNED_LOAD64(s);
247
- v.second = Rotate(v.first, 42) * k1 + UNALIGNED_LOAD64(s + 8);
290
+ v.first = Rotate(y ^ k1, 49) * k1 + Fetch64(s);
291
+ v.second = Rotate(v.first, 42) * k1 + Fetch64(s + 8);
248
292
  w.first = Rotate(y + z, 35) * k1 + x;
249
- w.second = Rotate(x + UNALIGNED_LOAD64(s + 88), 53) * k1;
293
+ w.second = Rotate(x + Fetch64(s + 88), 53) * k1;
250
294
 
251
295
  // This is the same inner loop as CityHash64(), manually unrolled.
252
296
  do {
253
- x = Rotate(x + y + v.first + UNALIGNED_LOAD64(s + 16), 37) * k1;
254
- y = Rotate(y + v.second + UNALIGNED_LOAD64(s + 48), 42) * k1;
297
+ x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1;
298
+ y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1;
255
299
  x ^= w.second;
256
- y ^= v.first;
257
- z = Rotate(z ^ w.first, 33);
300
+ y += v.first + Fetch64(s + 40);
301
+ z = Rotate(z + w.first, 33) * k1;
258
302
  v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first);
259
- w = WeakHashLen32WithSeeds(s + 32, z + w.second, y);
303
+ w = WeakHashLen32WithSeeds(s + 32, z + w.second, y + Fetch64(s + 16));
260
304
  std::swap(z, x);
261
305
  s += 64;
262
- x = Rotate(x + y + v.first + UNALIGNED_LOAD64(s + 16), 37) * k1;
263
- y = Rotate(y + v.second + UNALIGNED_LOAD64(s + 48), 42) * k1;
306
+ x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1;
307
+ y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1;
264
308
  x ^= w.second;
265
- y ^= v.first;
266
- z = Rotate(z ^ w.first, 33);
309
+ y += v.first + Fetch64(s + 40);
310
+ z = Rotate(z + w.first, 33) * k1;
267
311
  v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first);
268
- w = WeakHashLen32WithSeeds(s + 32, z + w.second, y);
312
+ w = WeakHashLen32WithSeeds(s + 32, z + w.second, y + Fetch64(s + 16));
269
313
  std::swap(z, x);
270
314
  s += 64;
271
315
  len -= 128;
272
316
  } while (LIKELY(len >= 128));
273
- y += Rotate(w.first, 37) * k0 + z;
274
317
  x += Rotate(v.first + z, 49) * k0;
318
+ z += Rotate(w.first, 37) * k0;
275
319
  // If 0 < len < 128, hash up to 4 chunks of 32 bytes each from the end of s.
276
320
  for (size_t tail_done = 0; tail_done < len; ) {
277
321
  tail_done += 32;
278
- y = Rotate(y - x, 42) * k0 + v.second;
279
- w.first += UNALIGNED_LOAD64(s + len - tail_done + 16);
280
- x = Rotate(x, 49) * k0 + w.first;
281
- w.first += v.first;
282
- v = WeakHashLen32WithSeeds(s + len - tail_done, v.first, v.second);
322
+ y = Rotate(x + y, 42) * k0 + v.second;
323
+ w.first += Fetch64(s + len - tail_done + 16);
324
+ x = x * k0 + w.first;
325
+ z += w.second + Fetch64(s + len - tail_done);
326
+ w.second += v.first;
327
+ v = WeakHashLen32WithSeeds(s + len - tail_done, v.first + z, v.second);
283
328
  }
284
- // At this point our 48 bytes of state should contain more than
329
+ // At this point our 56 bytes of state should contain more than
285
330
  // enough information for a strong 128-bit hash. We use two
286
- // different 48-byte-to-8-byte hashes to get a 16-byte final result.
331
+ // different 56-byte-to-8-byte hashes to get a 16-byte final result.
287
332
  x = HashLen16(x, v.first);
288
- y = HashLen16(y, w.first);
333
+ y = HashLen16(y + z, w.first);
289
334
  return uint128(HashLen16(x + v.second, w.second) + y,
290
335
  HashLen16(x + w.second, y + v.second));
291
336
  }
@@ -294,14 +339,128 @@ uint128 CityHash128(const char *s, size_t len) {
294
339
  if (len >= 16) {
295
340
  return CityHash128WithSeed(s + 16,
296
341
  len - 16,
297
- uint128(UNALIGNED_LOAD64(s) ^ k3,
298
- UNALIGNED_LOAD64(s + 8)));
342
+ uint128(Fetch64(s) ^ k3,
343
+ Fetch64(s + 8)));
299
344
  } else if (len >= 8) {
300
345
  return CityHash128WithSeed(NULL,
301
346
  0,
302
- uint128(UNALIGNED_LOAD64(s) ^ (len * k0),
303
- UNALIGNED_LOAD64(s + len - 8) ^ k1));
347
+ uint128(Fetch64(s) ^ (len * k0),
348
+ Fetch64(s + len - 8) ^ k1));
304
349
  } else {
305
350
  return CityHash128WithSeed(s, len, uint128(k0, k1));
306
351
  }
307
352
  }
353
+
354
+ #ifdef __SSE4_2__
355
+ #include <citycrc.h>
356
+ #include <nmmintrin.h>
357
+
358
+ // Requires len >= 240.
359
+ static void CityHashCrc256Long(const char *s, size_t len,
360
+ uint32 seed, uint64 *result) {
361
+ uint64 a = Fetch64(s + 56) + k0;
362
+ uint64 b = Fetch64(s + 96) + k0;
363
+ uint64 c = result[0] = HashLen16(b, len);
364
+ uint64 d = result[1] = Fetch64(s + 120) * k0 + len;
365
+ uint64 e = Fetch64(s + 184) + seed;
366
+ uint64 f = seed;
367
+ uint64 g = 0;
368
+ uint64 h = 0;
369
+ uint64 i = 0;
370
+ uint64 j = 0;
371
+ uint64 t = c + d;
372
+
373
+ // 240 bytes of input per iter.
374
+ size_t iters = len / 240;
375
+ len -= iters * 240;
376
+ do {
377
+ #define CHUNK(multiplier, z) \
378
+ { \
379
+ uint64 old_a = a; \
380
+ a = Rotate(b, 41 ^ z) * multiplier + Fetch64(s); \
381
+ b = Rotate(c, 27 ^ z) * multiplier + Fetch64(s + 8); \
382
+ c = Rotate(d, 41 ^ z) * multiplier + Fetch64(s + 16); \
383
+ d = Rotate(e, 33 ^ z) * multiplier + Fetch64(s + 24); \
384
+ e = Rotate(t, 25 ^ z) * multiplier + Fetch64(s + 32); \
385
+ t = old_a; \
386
+ } \
387
+ f = _mm_crc32_u64(f, a); \
388
+ g = _mm_crc32_u64(g, b); \
389
+ h = _mm_crc32_u64(h, c); \
390
+ i = _mm_crc32_u64(i, d); \
391
+ j = _mm_crc32_u64(j, e); \
392
+ s += 40
393
+
394
+ CHUNK(1, 1); CHUNK(k0, 0);
395
+ CHUNK(1, 1); CHUNK(k0, 0);
396
+ CHUNK(1, 1); CHUNK(k0, 0);
397
+ } while (--iters > 0);
398
+
399
+ while (len >= 40) {
400
+ CHUNK(k0, 0);
401
+ len -= 40;
402
+ }
403
+ if (len > 0) {
404
+ s = s + len - 40;
405
+ CHUNK(k0, 0);
406
+ }
407
+ j += i << 32;
408
+ a = HashLen16(a, j);
409
+ h += g << 32;
410
+ b += h;
411
+ c = HashLen16(c, f) + i;
412
+ d = HashLen16(d, e + result[0]);
413
+ j += e;
414
+ i += HashLen16(h, t);
415
+ e = HashLen16(a, d) + j;
416
+ f = HashLen16(b, c) + a;
417
+ g = HashLen16(j, i) + c;
418
+ result[0] = e + f + g + h;
419
+ a = ShiftMix((a + g) * k0) * k0 + b;
420
+ result[1] += a + result[0];
421
+ a = ShiftMix(a * k0) * k0 + c;
422
+ result[2] = a + result[1];
423
+ a = ShiftMix((a + e) * k0) * k0;
424
+ result[3] = a + result[2];
425
+ }
426
+
427
+ // Requires len < 240.
428
+ static void CityHashCrc256Short(const char *s, size_t len, uint64 *result) {
429
+ char buf[240];
430
+ memcpy(buf, s, len);
431
+ memset(buf + len, 0, 240 - len);
432
+ CityHashCrc256Long(buf, 240, ~static_cast<uint32>(len), result);
433
+ }
434
+
435
+ void CityHashCrc256(const char *s, size_t len, uint64 *result) {
436
+ if (LIKELY(len >= 240)) {
437
+ CityHashCrc256Long(s, len, 0, result);
438
+ } else {
439
+ CityHashCrc256Short(s, len, result);
440
+ }
441
+ }
442
+
443
+ uint128 CityHashCrc128WithSeed(const char *s, size_t len, uint128 seed) {
444
+ if (len <= 900) {
445
+ return CityHash128WithSeed(s, len, seed);
446
+ } else {
447
+ uint64 result[4];
448
+ CityHashCrc256(s, len, result);
449
+ uint64 u = Uint128High64(seed) + result[0];
450
+ uint64 v = Uint128Low64(seed) + result[1];
451
+ return uint128(HashLen16(u, v + result[2]),
452
+ HashLen16(Rotate(v, 32), u * k0 + result[3]));
453
+ }
454
+ }
455
+
456
+ uint128 CityHashCrc128(const char *s, size_t len) {
457
+ if (len <= 900) {
458
+ return CityHash128(s, len);
459
+ } else {
460
+ uint64 result[4];
461
+ CityHashCrc256(s, len, result);
462
+ return uint128(result[2], result[3]);
463
+ }
464
+ }
465
+
466
+ #endif
@@ -18,7 +18,7 @@
18
18
  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
19
  // THE SOFTWARE.
20
20
  //
21
- // CityHash Version 1, by Geoff Pike and Jyrki Alakuijala
21
+ // CityHash, by Geoff Pike and Jyrki Alakuijala
22
22
  //
23
23
  // This file provides a few functions for hashing strings. On x86-64
24
24
  // hardware in 2011, CityHash64() is faster than other high-quality
@@ -0,0 +1,47 @@
1
+ #include <ruby.h>
2
+ #include "city.h"
3
+
4
+ // Use this typedef to make the compiler happy when
5
+ // calling rb_define_method()
6
+ typedef VALUE (ruby_method)(...);
7
+
8
+ extern "C" VALUE cityhash_hash64(VALUE mod, VALUE input)
9
+ {
10
+ return ULL2NUM(CityHash64(StringValuePtr(input), RSTRING_LEN(input)));
11
+ }
12
+
13
+ extern "C" VALUE cityhash_hash64_with_seed(VALUE mod, VALUE input, VALUE seed)
14
+ {
15
+ return ULL2NUM(CityHash64WithSeed(StringValuePtr(input), RSTRING_LEN(input), NUM2ULL(seed)));
16
+ }
17
+
18
+ extern "C" VALUE cityhash_hash64_with_seeds(VALUE mod, VALUE input, VALUE seed1, VALUE seed2)
19
+ {
20
+ return ULL2NUM(CityHash64WithSeeds(StringValuePtr(input), RSTRING_LEN(input), NUM2ULL(seed1), NUM2ULL(seed2)));
21
+ }
22
+
23
+ extern "C" VALUE cityhash_hash128(VALUE mod, VALUE input)
24
+ {
25
+ uint128 hash = CityHash128(StringValuePtr(input), RSTRING_LEN(input));
26
+ return rb_str_new((char *)&hash, sizeof(hash));
27
+ }
28
+
29
+ extern "C" VALUE cityhash_hash128_with_seed(VALUE mod, VALUE input, VALUE seed_string)
30
+ {
31
+ uint128 seed = *(uint128 *)StringValuePtr(seed_string);
32
+ uint128 hash = CityHash128WithSeed(StringValuePtr(input), RSTRING_LEN(input), seed);
33
+ return rb_str_new((char *)&hash, sizeof(hash));
34
+ }
35
+
36
+ extern "C" void Init_cityhash()
37
+ {
38
+ VALUE mCityHash = rb_define_module("CityHash");
39
+ VALUE mInternal = rb_define_module_under(mCityHash, "Internal");
40
+
41
+ rb_define_singleton_method(mInternal, "hash64", (ruby_method*) &cityhash_hash64, 1);
42
+ rb_define_singleton_method(mInternal, "hash64_with_seed", (ruby_method*) &cityhash_hash64_with_seed, 2);
43
+ rb_define_singleton_method(mInternal, "hash64_with_seeds", (ruby_method*) &cityhash_hash64_with_seeds, 3);
44
+
45
+ rb_define_singleton_method(mInternal, "hash128", (ruby_method*) &cityhash_hash128, 1);
46
+ rb_define_singleton_method(mInternal, "hash128_with_seed", (ruby_method*) &cityhash_hash128_with_seed, 2);
47
+ }
@@ -1,12 +1,8 @@
1
1
  require 'mkmf'
2
2
 
3
- have_library('objc') if RUBY_PLATFORM =~ /darwin/
4
-
5
- %w{g O3 Wall rdynamic}.each do |flag|
3
+ %w{g O3 Wall}.each do |flag|
6
4
  flag = "-#{flag}"
7
5
  $CPPFLAGS += " #{flag}" unless $CPPFLAGS.split.include? flag
8
6
  end
9
7
 
10
- CONFIG['LDSHARED'] = '$(CXX) -shared' unless RUBY_PLATFORM =~ /darwin/
11
-
12
- create_makefile('cityhash')
8
+ create_makefile('cityhash/cityhash')
@@ -1,63 +1,23 @@
1
- require 'ffi'
1
+ require 'cityhash/version'
2
+ require 'cityhash/cityhash'
2
3
 
3
4
  module CityHash
4
-
5
5
  LOW64_MASK = 0x0000000000000000ffffffffffffffff
6
6
  HIGH64_MASK = 0xffffffffffffffff0000000000000000
7
7
 
8
- module Internal
9
- extend FFI::Library
10
-
11
- ffi_lib(
12
- case RUBY_PLATFORM
13
- when /darwin/
14
- File.join(File.dirname(__FILE__), '..', 'ext', 'cityhash', 'cityhash.bundle')
15
- when /mingw|mswin|linux/
16
- File.join(File.dirname(__FILE__), '..', 'ext', 'cityhash', 'cityhash.so')
17
- else
18
- File.join(File.dirname(__FILE__), '..', 'ext', 'cityhash', "cityhash.#{RbConfig::CONFIG['DLEXT']}")
19
- end
20
- )
21
-
22
- attach_function :city_hash64, :CityHash64, [:string, :size_t], :uint64
23
- attach_function :city_hash64_with_seed, :CityHash64WithSeed, [:string, :size_t, :uint64], :uint64
24
- attach_function :city_hash64_with_seeds, :CityHash64WithSeeds, [:string, :size_t, :uint64, :uint64], :uint64
25
- attach_function :city_hash128, :CityHash128String, [:string, :size_t], :string
26
- attach_function :city_hash128_with_seed, :CityHash128WithSeedString, [:string, :size_t, :uint64, :uint64], :string
8
+ def self.hash64(input, seed1=nil, seed2=nil)
9
+ return Internal.hash64(input) if seed1.nil?
10
+ return Internal.hash64_with_seed(input, seed1.to_i) if seed2.nil?
11
+ Internal.hash64_with_seeds(input, seed1.to_i, seed2.to_i)
27
12
  end
28
13
 
29
- def self.hash64(input, seed1 = nil, seed2 = nil)
30
- input_str = input.to_s
31
-
32
- # Ruby 1.8 compatibility
33
- if input_str.respond_to?(:bytesize)
34
- len = input_str.bytesize
14
+ def self.hash128(input, seed=nil)
15
+ if seed
16
+ seed = [seed & LOW64_MASK, seed & HIGH64_MASK >> 64].pack('QQ')
17
+ digest = Internal.hash128_with_seed(input, seed)
35
18
  else
36
- len = input_str.size
19
+ digest = Internal.hash128(input)
37
20
  end
38
-
39
- return CityHash::Internal.city_hash64(input_str, len) if seed1.nil?
40
- return CityHash::Internal.city_hash64_with_seed(input_str, len, seed1.to_i & LOW64_MASK) if seed2.nil?
41
-
42
- CityHash::Internal.city_hash64_with_seeds(input_str, len, seed1.to_i & LOW64_MASK, seed2.to_i & LOW64_MASK)
21
+ [0..7, 8..15].map { |r| digest[r].unpack('Q').first.to_s }.join.to_i
43
22
  end
44
-
45
- def self.hash128(input, seed = nil)
46
- input_str = input.to_s
47
-
48
- # Ruby 1.8 compatibility
49
- if input_str.respond_to?(:bytesize)
50
- len = input_str.bytesize
51
- else
52
- len = input_str.size
53
- end
54
-
55
- return CityHash::Internal.city_hash128(input_str, len).to_i if seed.nil?
56
-
57
- seed_low = seed.to_i & LOW64_MASK
58
- seed_high = (seed.to_i & HIGH64_MASK) >> 64
59
-
60
- CityHash::Internal.city_hash128_with_seed(input_str, len, seed_low, seed_high).to_i
61
- end
62
-
63
23
  end
@@ -1,12 +1,3 @@
1
1
  module CityHash
2
-
3
- module Version
4
- MAJOR = 0
5
- MINOR = 5
6
- PATCH = 0
7
- BUILD = nil
8
-
9
- STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
10
- end
11
-
2
+ VERSION = "0.6.0"
12
3
  end
@@ -0,0 +1,24 @@
1
+ require 'test_helper'
2
+
3
+ describe CityHash do
4
+ it 'returns 64bit hash' do
5
+ assert_equal 17703940110308125106, CityHash.hash64("test")
6
+ end
7
+
8
+ it "returns 64bit hash with a seed" do
9
+ assert_equal 14900027982776226655, CityHash.hash64("test", 12345)
10
+ end
11
+
12
+ it "returns 64bit hash with seeds" do
13
+ assert_equal 11136353178704814373, CityHash.hash64("test", 12345, 54321)
14
+ end
15
+
16
+ it "returns 128bit hash" do
17
+ assert_equal 1800071687761605184910580728449884026697, CityHash.hash128("test")
18
+ end
19
+
20
+ it "returns 128bit hash with seed" do
21
+ seed = (123 << 64) | 123
22
+ assert_equal 1631427474705635869517741677842296176559, CityHash.hash128("test", seed)
23
+ end
24
+ end
@@ -0,0 +1,4 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/spec'
3
+
4
+ require 'cityhash'
metadata CHANGED
@@ -1,110 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cityhash
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
8
- - nashby
8
+ - Vasiliy Ermolovich
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-10-28 00:00:00.000000000Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: ffi
16
- requirement: &24780520 !ruby/object:Gem::Requirement
17
- none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: '0'
22
- type: :runtime
23
- prerelease: false
24
- version_requirements: *24780520
25
- - !ruby/object:Gem::Dependency
26
- name: shoulda
27
- requirement: &24779860 !ruby/object:Gem::Requirement
28
- none: false
29
- requirements:
30
- - - ! '>='
31
- - !ruby/object:Gem::Version
32
- version: '0'
33
- type: :development
34
- prerelease: false
35
- version_requirements: *24779860
36
- - !ruby/object:Gem::Dependency
37
- name: bundler
38
- requirement: &24779220 !ruby/object:Gem::Requirement
39
- none: false
40
- requirements:
41
- - - ~>
42
- - !ruby/object:Gem::Version
43
- version: 1.0.0
44
- type: :development
45
- prerelease: false
46
- version_requirements: *24779220
47
- - !ruby/object:Gem::Dependency
48
- name: jeweler
49
- requirement: &24778500 !ruby/object:Gem::Requirement
50
- none: false
51
- requirements:
52
- - - ~>
53
- - !ruby/object:Gem::Version
54
- version: 1.5.2
55
- type: :development
56
- prerelease: false
57
- version_requirements: *24778500
58
- - !ruby/object:Gem::Dependency
59
- name: rcov
60
- requirement: &24777780 !ruby/object:Gem::Requirement
61
- none: false
62
- requirements:
63
- - - ! '>='
64
- - !ruby/object:Gem::Version
65
- version: '0'
66
- type: :development
67
- prerelease: false
68
- version_requirements: *24777780
69
- - !ruby/object:Gem::Dependency
70
- name: ffi
71
- requirement: &24776560 !ruby/object:Gem::Requirement
72
- none: false
73
- requirements:
74
- - - ! '>='
75
- - !ruby/object:Gem::Version
76
- version: '0'
77
- type: :runtime
78
- prerelease: false
79
- version_requirements: *24776560
80
- description: ffi wrapper for google's cityhash
81
- email: younash@gmail.com
12
+ date: 2012-04-07 00:00:00.000000000Z
13
+ dependencies: []
14
+ description: ruby bindings for google's cityhash
15
+ email:
16
+ - younash@gmail.com
82
17
  executables: []
83
18
  extensions:
84
19
  - ext/cityhash/extconf.rb
85
- extra_rdoc_files:
86
- - LICENSE.txt
87
- - README.md
20
+ extra_rdoc_files: []
88
21
  files:
89
- - .document
22
+ - .gitignore
23
+ - .travis.yml
90
24
  - Gemfile
91
- - Gemfile.lock
92
25
  - LICENSE.txt
93
26
  - README.md
94
27
  - Rakefile
95
28
  - cityhash.gemspec
96
29
  - ext/cityhash/city.cc
97
30
  - ext/cityhash/city.h
98
- - ext/cityhash/city_ruby_bridge.cpp
99
- - ext/cityhash/city_ruby_bridge.h
31
+ - ext/cityhash/cityhash.cc
100
32
  - ext/cityhash/extconf.rb
101
33
  - lib/cityhash.rb
102
34
  - lib/cityhash/version.rb
103
- - test/helper.rb
104
- - test/test_cityhash.rb
35
+ - test/cityhash_test.rb
36
+ - test/test_helper.rb
105
37
  homepage: http://github.com/nashby/cityhash
106
- licenses:
107
- - MIT
38
+ licenses: []
108
39
  post_install_message:
109
40
  rdoc_options: []
110
41
  require_paths:
@@ -117,19 +48,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
117
48
  version: '0'
118
49
  segments:
119
50
  - 0
120
- hash: -4372501756799673446
51
+ hash: 268501841747995875
121
52
  required_rubygems_version: !ruby/object:Gem::Requirement
122
53
  none: false
123
54
  requirements:
124
55
  - - ! '>='
125
56
  - !ruby/object:Gem::Version
126
57
  version: '0'
58
+ segments:
59
+ - 0
60
+ hash: 268501841747995875
127
61
  requirements: []
128
- rubyforge_project:
129
- rubygems_version: 1.8.6
62
+ rubyforge_project: cityhash
63
+ rubygems_version: 1.8.19
130
64
  signing_key:
131
65
  specification_version: 3
132
- summary: ffi wrapper for google's cityhash
133
- test_files:
134
- - test/helper.rb
135
- - test/test_cityhash.rb
66
+ summary: ruby bindings for google's cityhash
67
+ test_files: []
data/.document DELETED
@@ -1,5 +0,0 @@
1
- lib/**/*.rb
2
- bin/*
3
- -
4
- features/**/*.feature
5
- LICENSE.txt
@@ -1,23 +0,0 @@
1
- GEM
2
- remote: http://rubygems.org/
3
- specs:
4
- ffi (1.0.7)
5
- rake (>= 0.8.7)
6
- git (1.2.5)
7
- jeweler (1.5.2)
8
- bundler (~> 1.0.0)
9
- git (>= 1.2.5)
10
- rake
11
- rake (0.8.7)
12
- rcov (0.9.9)
13
- shoulda (2.11.3)
14
-
15
- PLATFORMS
16
- ruby
17
-
18
- DEPENDENCIES
19
- bundler (~> 1.0.0)
20
- ffi
21
- jeweler (~> 1.5.2)
22
- rcov
23
- shoulda
@@ -1,19 +0,0 @@
1
- #include "city_ruby_bridge.h"
2
- #include <sstream>
3
-
4
- const char* CityHash128String(const char *s, size_t len)
5
- {
6
- std::ostringstream str;
7
- str << Uint128Low64(CityHash128(s, len)) << Uint128High64(CityHash128(s, len));
8
-
9
- return str.str().c_str();
10
- }
11
-
12
- const char* CityHash128WithSeedString(const char *s, size_t len, uint64 seed1, uint64 seed2)
13
- {
14
- uint128 seed(seed1, seed2);
15
- std::ostringstream str;
16
- str << Uint128Low64(CityHash128WithSeed(s, len, seed)) << Uint128High64(CityHash128WithSeed(s, len, seed));
17
-
18
- return str.str().c_str();
19
- }
@@ -1,8 +0,0 @@
1
- #include "city.h"
2
-
3
- typedef uint64_t uint64;
4
- typedef std::pair<uint64, uint64> uint128;
5
-
6
- extern "C" const char* CityHash128String(const char *s, size_t len);
7
-
8
- extern "C" const char* CityHash128WithSeedString(const char *s, size_t len, uint64 seed1, uint64 seed2);
@@ -1,18 +0,0 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- begin
4
- Bundler.setup(:default, :development)
5
- rescue Bundler::BundlerError => e
6
- $stderr.puts e.message
7
- $stderr.puts "Run `bundle install` to install missing gems"
8
- exit e.status_code
9
- end
10
- require 'test/unit'
11
- require 'shoulda'
12
-
13
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
- $LOAD_PATH.unshift(File.dirname(__FILE__))
15
- require 'cityhash'
16
-
17
- class Test::Unit::TestCase
18
- end
@@ -1,26 +0,0 @@
1
- require 'helper'
2
-
3
- class TestCityhash < Test::Unit::TestCase
4
-
5
- should "return 64bit hash" do
6
- assert_equal 17703940110308125106, CityHash.hash64("test")
7
- end
8
-
9
- should "return 64bit hash with a seed" do
10
- assert_equal 14900027982776226655, CityHash.hash64("test", 12345)
11
- end
12
-
13
- should "return 64bit hash with seeds" do
14
- assert_equal 11136353178704814373, CityHash.hash64("test", 12345, 54321)
15
- end
16
-
17
- should "return 128bit hash" do
18
- assert_equal 130554790001792308794529643941127319555, CityHash.hash128("test")
19
- end
20
-
21
- should "return 128bit hash with seed" do
22
- seed = (123 << 64) | 123
23
- assert_equal 183946415266487905135364192266033899899, CityHash.hash128("test", seed)
24
- end
25
-
26
- end