dalli-ext-spymemcached 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source :rubygems
2
+
3
+ # Specify your gem's dependencies in dalli-ext-spymemcached.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # Dalli Extension: Spymemcached
2
+
3
+ Memcached clients all use their own way of deciding which server from a list
4
+ of configured servers a specific key should be stored on. Hence different
5
+ memcached libraries often don't work to well together.
6
+
7
+ This gem changes [Dalli][]'s server hashing algorithm to match that of the
8
+ [Spymemcached][] Java client.
9
+
10
+ ## Usage
11
+
12
+ ```ruby
13
+ require 'dalli'
14
+ require 'dalli-ext-spymemcached'
15
+ ```
16
+
17
+ # Licence
18
+
19
+ (The MIT License)
20
+
21
+ Copyright (c) 2012 Global Personals, Ltd.
22
+
23
+ Permission is hereby granted, free of charge, to any person obtaining a copy
24
+ of this software and associated documentation files (the "Software"), to deal
25
+ in the Software without restriction, including without limitation the rights
26
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27
+ copies of the Software, and to permit persons to whom the Software is
28
+ furnished to do so, subject to the following conditions:
29
+
30
+ The above copyright notice and this permission notice shall be included in
31
+ all copies or substantial portions of the Software.
32
+
33
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
39
+ THE SOFTWARE.
40
+
41
+ [dalli]: https://github.com/mperham/dalli
42
+ [spymemcached]: http://code.google.com/p/spymemcached/
@@ -0,0 +1,2 @@
1
+ require 'dalli-ext-spymemcached/version'
2
+ require 'dalli-ext-spymemcached/ring'
@@ -0,0 +1,40 @@
1
+ require 'dalli'
2
+
3
+ module Dalli
4
+ module Ext
5
+ module Spymemcached
6
+
7
+ # Impliments the same hashing algorithm to chose a server as
8
+ # spymemcached Java library.
9
+ class Ring < Dalli::Ring
10
+ MAX = 2 ** 31 - 1 # 32 bit signed int max
11
+ MIN = -2 ** 31 # 32 bit signed int min
12
+
13
+ def hash_for(key)
14
+ hashed_key = key.each_byte.inject(0) do |hash, byte|
15
+ hash = 31 * hash + byte
16
+ hash = MAX - (MIN - hash) + 1 while hash < MIN
17
+ hash = MIN - (MAX - hash) - 1 while hash > MAX
18
+ hash
19
+ end
20
+
21
+ hashed_key & "ffffffff".hex
22
+ end
23
+
24
+ def server_for_key(key)
25
+ server = @servers[hash_for(key) % @servers.length] if @servers.any?
26
+
27
+ unless server && server.alive?
28
+ raise Dalli::NetworkError, "No servers available"
29
+ end
30
+
31
+ server
32
+ end
33
+
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ # Replace default implementation.
40
+ Dalli::Ring = Dalli::Ext::Spymemcached::Ring
@@ -0,0 +1,7 @@
1
+ module Dalli
2
+ module Ext
3
+ module Spymemcached
4
+ VERSION = "1.0.1"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dalli::Ring do
4
+ let(:server_klass) do
5
+ Struct.new(:hostname, :port, :weight) do
6
+ def alive?
7
+ true
8
+ end
9
+ end
10
+ end
11
+ let(:foo) {server_klass.new("foo.com", 11211, 1)}
12
+ let(:bar) {server_klass.new("bar.com", 11211, 1)}
13
+ let(:baz) {server_klass.new("baz.com", 11211, 1)}
14
+ let(:ring) {Dalli::Ring.new([foo, bar, baz], {})}
15
+ let(:empty_ring) {Dalli::Ring.new([], {})}
16
+
17
+ it "should hash as expected" do
18
+ ring.hash_for("foo").should == 101574
19
+ ring.hash_for("bar").should == 97299
20
+ ring.hash_for("baz").should == 97307
21
+ ring.hash_for("1234").should == 1509442
22
+ end
23
+
24
+ it "should return the expected server" do
25
+ ring.server_for_key("0123").should == foo
26
+ ring.server_for_key("1234").should == bar
27
+ ring.server_for_key("2345").should == baz
28
+
29
+ ring.server_for_key("abc").should == foo
30
+ ring.server_for_key("abcd").should == bar
31
+ ring.server_for_key("abcdef").should == foo
32
+
33
+ ring.server_for_key("bb5eiplr").should == foo
34
+ ring.server_for_key("5zvutsib").should == baz
35
+ ring.server_for_key("19yh6i75").should == baz
36
+ end
37
+
38
+ it "should raise a Dalli::NetworkError if no server is defined" do
39
+ expect {
40
+ empty_ring.server_for_key("0123")
41
+ }.to raise_error(Dalli::NetworkError, "No servers available")
42
+ end
43
+ end
@@ -0,0 +1,12 @@
1
+ require 'simplecov'
2
+ SimpleCov.start do
3
+ add_filter "/spec/"
4
+ add_filter {|file| file.source.join !~ /def/}
5
+ end
6
+
7
+
8
+ require 'rspec'
9
+ require 'rspec/autorun'
10
+
11
+ require 'dalli'
12
+ require 'dalli-ext-spymemcached'
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dalli-ext-spymemcached
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jim Myhrberg
9
+ - Mat Sadler
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-06-07 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: dalli
17
+ requirement: &2156262200 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *2156262200
26
+ - !ruby/object:Gem::Dependency
27
+ name: rake
28
+ requirement: &2156261520 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: *2156261520
37
+ - !ruby/object:Gem::Dependency
38
+ name: rspec
39
+ requirement: &2156260900 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *2156260900
48
+ - !ruby/object:Gem::Dependency
49
+ name: simplecov
50
+ requirement: &2156260100 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *2156260100
59
+ description: Dalli server-hashing algorithm to match spymemcachedJava library.
60
+ email:
61
+ - contact@jimeh.me
62
+ - matsadler@globalpersonals.co.uk
63
+ executables: []
64
+ extensions: []
65
+ extra_rdoc_files: []
66
+ files:
67
+ - lib/dalli-ext-spymemcached/ring.rb
68
+ - lib/dalli-ext-spymemcached/version.rb
69
+ - lib/dalli-ext-spymemcached.rb
70
+ - spec/dalli-ext-spymemcached/ring_spec.rb
71
+ - spec/spec_helper.rb
72
+ - README.md
73
+ - Gemfile
74
+ homepage: ''
75
+ licenses: []
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ! '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ requirements: []
93
+ rubyforge_project:
94
+ rubygems_version: 1.8.11
95
+ signing_key:
96
+ specification_version: 3
97
+ summary: Dalli server-hashing algorithm to match spymemcachedJava library.
98
+ test_files:
99
+ - spec/dalli-ext-spymemcached/ring_spec.rb
100
+ - spec/spec_helper.rb