sumbur 0.1.0-jruby

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.
@@ -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