kedama 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.
Files changed (3) hide show
  1. data/README +42 -0
  2. data/lib/kedama.rb +98 -0
  3. metadata +70 -0
data/README ADDED
@@ -0,0 +1,42 @@
1
+ = kedama
2
+
3
+ == Description
4
+
5
+ kedama is ruby port of the libketama.
6
+
7
+ libketama is a consistent hashing library.
8
+
9
+ see http://bit.ly/dVIeGh
10
+
11
+ == Install
12
+
13
+ gem install kedama
14
+
15
+ == Example
16
+
17
+ require 'kedama'
18
+
19
+ nodes = Kedama::Nodes.new
20
+ nodes.add('1.2.3.4:11211', 900)
21
+ nodes.add('5.6.7.8:11211', 300)
22
+ nodes.add('9.8.7.6:11211', 1500)
23
+
24
+ hash = nodes.to_hash
25
+
26
+ 10.times do |i|
27
+ i = i.to_s
28
+ puts i + "\t" + hash[i]
29
+ end
30
+
31
+ # output
32
+ # ---
33
+ # 0 5.6.7.8:11211
34
+ # 1 5.6.7.8:11211
35
+ # 2 9.8.7.6:11211
36
+ # 3 1.2.3.4:11211
37
+ # 4 1.2.3.4:11211
38
+ # 5 1.2.3.4:11211
39
+ # 6 1.2.3.4:11211
40
+ # 7 9.8.7.6:11211
41
+ # 8 9.8.7.6:11211
42
+ # 9 9.8.7.6:11211
data/lib/kedama.rb ADDED
@@ -0,0 +1,98 @@
1
+ require 'digest/md5'
2
+
3
+ module Kedama
4
+ class ConsitentHash
5
+ def initialize(nodes)
6
+ @circle = []
7
+ @names = {}
8
+
9
+ total_weight = nodes.values.inject {|r, i| r + i}
10
+
11
+ nodes.each do |name, weight|
12
+ repls = (40.0 * nodes.length * weight / total_weight).floor
13
+
14
+ repls.times do |i|
15
+ hs = hash_values("#{name}-#{i}")
16
+
17
+ hs.each do |h|
18
+ @circle << h
19
+ @names[h] = name
20
+ end
21
+ end
22
+ end
23
+
24
+ @circle.sort!
25
+ end
26
+
27
+ def to_a
28
+ @circle.map do |h|
29
+ [h, @names[h]]
30
+ end
31
+ end
32
+
33
+ def [](key)
34
+ point = search(key.to_str)
35
+ @names[point]
36
+ end
37
+
38
+ private
39
+ def hash_values(str)
40
+ digest = Digest::MD5.digest(str)
41
+ hs = []
42
+
43
+ until digest.empty?
44
+ bs = digest.slice!(0, 4)
45
+ hs << (bs[3] << 24) + (bs[2] << 16) + (bs[1] << 8) + bs[0]
46
+ end
47
+
48
+ return hs
49
+ end
50
+
51
+ def hashi(str)
52
+ digest = Digest::MD5.digest(str)
53
+ (digest[3] << 24) + (digest[2] << 16) + (digest[1] << 8) + digest[0]
54
+ end
55
+
56
+ def search(key)
57
+ key_hash = hashi(key)
58
+ lowp = 0
59
+ highp = @circle.length
60
+
61
+ while true
62
+ midp = (lowp + highp) / 2;
63
+
64
+ return @circle.first if midp == @circle.length
65
+
66
+ midval = @circle[midp];
67
+ midval1 = midp.zero? ? 0 : @circle[midp - 1]
68
+
69
+ if midval1 < key_hash and key_hash <= midval
70
+ return midval
71
+ end
72
+
73
+ if midval < key_hash
74
+ lowp = midp + 1
75
+ else
76
+ highp = midp - 1
77
+ end
78
+
79
+ return @circle.first if lowp > highp
80
+ end
81
+ end
82
+ end # ConsitentHash
83
+
84
+ class Nodes
85
+ def initialize
86
+ @nodes = {}
87
+ end
88
+
89
+ def add(name, weight)
90
+ @nodes[name.to_str] = weight.to_int
91
+ end
92
+
93
+ def to_hash
94
+ ConsitentHash.new(@nodes)
95
+ end
96
+ end # Nodes
97
+
98
+ end # Kedama
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kedama
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - winebarrel
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-04-17 00:00:00 Z
19
+ dependencies: []
20
+
21
+ description: |
22
+ kedama is ruby port of the libketama.
23
+ libketama is a consistent hashing library.
24
+ see http://bit.ly/dVIeGh
25
+
26
+ email: sgwr_dts@yahoo.co.jp
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files: []
32
+
33
+ files:
34
+ - lib/kedama.rb
35
+ - README
36
+ homepage: https://bitbucket.org/winebarrel/kedama
37
+ licenses: []
38
+
39
+ post_install_message:
40
+ rdoc_options: []
41
+
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ hash: 3
50
+ segments:
51
+ - 0
52
+ version: "0"
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ hash: 3
59
+ segments:
60
+ - 0
61
+ version: "0"
62
+ requirements: []
63
+
64
+ rubyforge_project:
65
+ rubygems_version: 1.7.2
66
+ signing_key:
67
+ specification_version: 3
68
+ summary: kedama is ruby port of the libketama.
69
+ test_files: []
70
+