sumbur 0.1.0-jruby

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,13 @@
1
+ require "sumbur/version"
2
+
3
+ module Sumbur
4
+ begin
5
+ require 'sumbur/native_sumbur'
6
+ include NativeSumbur
7
+ extend NativeSumbur
8
+ rescue LoadError
9
+ require 'sumbur/pure_ruby'
10
+ include PureRuby
11
+ extend PureRuby
12
+ end
13
+ end
@@ -0,0 +1,31 @@
1
+ module Sumbur
2
+ module PureRuby
3
+ extend self
4
+
5
+ def sumbur(hashed_integer, cluster_capacity)
6
+ raise ArgumentError, "Sumbur is not applicable to empty cluster" if cluster_capacity == 0
7
+ raise ArgumentError, "Sumbur accepts only positive 32bit integers" if hashed_integer < 0 || hashed_integer > 0xFFFFFFFF
8
+
9
+ l = 0xFFFFFFFF
10
+ part = l / cluster_capacity
11
+
12
+ return 0 if l - hashed_integer < part
13
+
14
+ h = hashed_integer
15
+ n = 1
16
+ i = 2
17
+ while i <= cluster_capacity
18
+ c = l / (i * (i-1))
19
+ if c <= h
20
+ h -= c
21
+ else
22
+ h += c * (i-n-1)
23
+ n = i
24
+ break if l / n - h < part
25
+ end
26
+ i += 1
27
+ end
28
+ n - 1
29
+ end
30
+ end
31
+ end
Binary file
@@ -0,0 +1,3 @@
1
+ module Sumbur
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,86 @@
1
+ require 'minitest/spec'
2
+ require 'minitest/autorun'
3
+
4
+ $spread_cache = {}
5
+
6
+ HASHED = (1..1_000_000).map{|i|
7
+ h = i ^ (i >> 16)
8
+ h = (h * 0x85ebca6b) & 0xFFffFFff
9
+ h ^= h >> 13
10
+ h = (h * 0xc2b2ae35) & 0xFFffFFff
11
+ [h ^ (h >> 16), i]
12
+ }
13
+
14
+ def spread(num, capa, sumbur)
15
+ start = Time.now
16
+ #v = $spread_cache[ [num, capa, sumbur] ] ||=
17
+ v = HASHED[0, num].
18
+ map{|hash, int| [sumbur.sumbur(hash, capa), int]}.
19
+ group_by{|serv, int| serv}
20
+ d = Time.now - start
21
+ puts format("%s %.4f", [num, capa, sumbur].inspect, d) if d > 0.01
22
+ v
23
+ end
24
+
25
+ shared_example = proc do
26
+ it "should spread capacity" do
27
+ for num, eps in [[100_000, 0.05], [1_000_000, 0.011]]
28
+ for capa in [2,3,7,8,17,18]
29
+ spread(num, capa, sumbur).each{|serv, ints|
30
+ ints.size.must_be_within_epsilon num/capa, eps
31
+ }
32
+ end
33
+ end
34
+ end
35
+
36
+ it "should reshard values cleanly" do
37
+ for num in [100_000, 1_000_000]
38
+ for capa in [2,3,7,8,17,18]
39
+ cur = spread(num, capa, sumbur)
40
+ nxt = spread(num, capa+1, sumbur)
41
+ moved = 0
42
+ for i in 0...capa
43
+ (nxt[i] - cur[i]).must_be_empty
44
+ moved += mvd = (cur[i] - nxt[i]).size
45
+ mvd.must_be_within_epsilon (num/capa - num/(capa+1)), 40000.0/num
46
+ end
47
+ moved.must_be_within_epsilon num/(capa+1), 7000.0/num
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ require 'sumbur/pure_ruby'
54
+ describe "Pure Ruby" do
55
+ def sumbur
56
+ Sumbur::PureRuby
57
+ end
58
+ class_exec &shared_example
59
+ end if false
60
+
61
+ begin
62
+ if RUBY_ENGINE == 'jruby'
63
+ require 'sumbur/sumbur.jar'
64
+ else
65
+ require 'sumbur/native_sumbur'
66
+ end
67
+
68
+ describe "Native" do
69
+ def sumbur
70
+ if RUBY_ENGINE == 'jruby'
71
+ Sumbur::Java
72
+ else
73
+ Sumbur::NativeSumbur
74
+ end
75
+ end
76
+ class_exec &shared_example
77
+
78
+ it "should produce same spread as pure ruby version" do
79
+ for capa in [2,3,4,7,8,9,17,18,19]
80
+ spread(1_000_000, capa, sumbur).must_equal spread(1_000_000, capa, Sumbur::PureRuby)
81
+ end
82
+ end if false
83
+ end
84
+ rescue LoadError
85
+ puts "Native version is not tested"
86
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sumbur
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: jruby
7
+ authors:
8
+ - Sokolov Yura 'funny-falcon'
9
+ - Maksim Kalinchenko
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+
14
+ date: 2012-08-10 00:00:00 Z
15
+ dependencies: []
16
+
17
+ description: Sumbur - consistent spreading for server balancing
18
+ email:
19
+ - funny.falcon@gmail.com
20
+ - uint32@mail.ru
21
+ executables: []
22
+
23
+ extensions: []
24
+
25
+ extra_rdoc_files: []
26
+
27
+ files:
28
+ - lib/sumbur.rb
29
+ - lib/sumbur/pure_ruby.rb
30
+ - lib/sumbur/sumbur.jar
31
+ - lib/sumbur/version.rb
32
+ - test/test_sumbur.rb
33
+ homepage: https://github.com/mailru/sumbur-ruby
34
+ licenses: []
35
+
36
+ post_install_message:
37
+ rdoc_options: []
38
+
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ requirements: []
54
+
55
+ rubyforge_project:
56
+ rubygems_version: 1.8.15
57
+ signing_key:
58
+ specification_version: 3
59
+ summary: Sumbur - consistent spreading for server balancing
60
+ test_files:
61
+ - test/test_sumbur.rb