Skip to content

Commit

Permalink
base pass at ruby extension
Browse files Browse the repository at this point in the history
  • Loading branch information
ewdurbin committed Jul 6, 2014
1 parent 4d0f3ff commit b95f1e3
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 4 deletions.
3 changes: 3 additions & 0 deletions lib/ruby/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ GEM
remote: https://rubygems.org/
specs:
rake (0.8.7)
rake-compiler (0.9.2)
rake

PLATFORMS
ruby

DEPENDENCIES
clandestiny!
rake (= 0.8.7)
rake-compiler
5 changes: 5 additions & 0 deletions lib/ruby/Rakefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
require "bundler/gem_tasks"
require 'rake/testtask'
require 'rake/extensiontask'

Rake::ExtensionTask.new('murmur3_native')

Rake::TestTask.new do |t|
t.libs << "ext"
t.libs << "test"
t.test_files = FileList['test/test*.rb']
end
4 changes: 3 additions & 1 deletion lib/ruby/clandestiny.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ Gem::Specification.new do |s|

s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- test/*`.split("\n")
s.require_paths = ['lib']
s.require_paths = ['lib', 'ext']
s.extensions = ['ext/murmur3_native/extconf.rb']

s.add_development_dependency 'rake', '0.8.7'
s.add_development_dependency 'rake-compiler'

s.has_rdoc = false

Expand Down
8 changes: 8 additions & 0 deletions lib/ruby/ext/murmur3_native/extconf.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
require 'mkmf'

dir_config("murmur3_native")
have_library("c", "main")

$defs << "-DRUBY_VERSION_CODE=#{RUBY_VERSION.gsub(/\D/, '')}"

create_makefile("murmur3_native")
77 changes: 77 additions & 0 deletions lib/ruby/ext/murmur3_native/murmur3_native.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#include "ruby.h"

#include <stdint.h>
#include <string.h>

// MurmurHash3 was written by Austin Appleby, and is placed in the public
// domain. The author hereby disclaims copyright to this source code.

uint32_t murmur3_32(const char *key, uint32_t len, uint32_t seed) {
static const uint32_t c1 = 0xcc9e2d51;
static const uint32_t c2 = 0x1b873593;
static const uint32_t r1 = 15;
static const uint32_t r2 = 13;
static const uint32_t m = 5;
static const uint32_t n = 0xe6546b64;

uint32_t hash = seed;

const int nblocks = len / 4;
const uint32_t *blocks = (const uint32_t *) key;
int i;
for (i = 0; i < nblocks; i++) {
uint32_t k = blocks[i];
k *= c1;
k = (k << r1) | (k >> (32 - r1));
k *= c2;

hash ^= k;
hash = ((hash << r2) | (hash >> (32 - r2))) * m + n;
}

const uint8_t *tail = (const uint8_t *) (key + nblocks * 4);
uint32_t k1 = 0;

switch (len & 3) {
case 3:
k1 ^= tail[2] << 16;
case 2:
k1 ^= tail[1] << 8;
case 1:
k1 ^= tail[0];

k1 *= c1;
k1 = (k1 << r1) | (k1 >> (32 - r1));
k1 *= c2;
hash ^= k1;
}

hash ^= len;
hash ^= (hash >> 16);
hash *= 0x85ebca6b;
hash ^= (hash >> 13);
hash *= 0xc2b2ae35;
hash ^= (hash >> 16);

return hash;
}

static VALUE rb_mumur3_32(int argc, VALUE* argv, VALUE self) {
VALUE rstr;
if (argc == 0 || argc > 2) {
rb_raise(rb_eArgError, "accept 1 or 2 arguments: (string[, seed])");
}
rstr = argv[0];
StringValue(rstr);
uint32_t value = murmur3_32(RSTRING_PTR(rstr), RSTRING_LEN(rstr), argc == 1 ? 0 : NUM2UINT(argv[1]));
return UINT2NUM(value);
}

VALUE Murmur3Native = Qnil;

void Init_murmur3_native();

void Init_murmur3_native() {
VALUE Murmur3Native = rb_define_module("Murmur3Native");
rb_define_module_function(Murmur3Native, "murmur3_32", rb_mumur3_32, -1);
}
8 changes: 5 additions & 3 deletions lib/ruby/lib/clandestine.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
require 'murmur3'
require 'murmur3_native'
require 'set'

include Murmur3Native

class RendezvousHash

attr_reader :nodes
attr_reader :hash_function

def initialize(nodes=nil, hash_function=method(:murmur3_32_str_hash))
def initialize(nodes=nil, hash_function=method(:murmur3_32))
@nodes = nodes || []
@hash_function = hash_function
end
Expand Down Expand Up @@ -34,7 +36,7 @@ class Cluster
attr_reader :zone_members
attr_reader :rings

def initialize(cluster=nil, replicas=2, hash_function=method(:murmur3_32_str_hash))
def initialize(cluster=nil, replicas=2, hash_function=method(:murmur3_32))
@hash_function = hash_function

@replicas = replicas
Expand Down
2 changes: 2 additions & 0 deletions lib/ruby/lib/murmur3.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require 'murmur3_native'

## MurmurHash3 was written by Austin Appleby, and is placed in the public
## domain. The author hereby disclaims copyright to this source code.

Expand Down

0 comments on commit b95f1e3

Please sign in to comment.