partitioner 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,25 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ partitioner (0.0.1)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.1.2)
10
+ rspec (2.5.0)
11
+ rspec-core (~> 2.5.0)
12
+ rspec-expectations (~> 2.5.0)
13
+ rspec-mocks (~> 2.5.0)
14
+ rspec-core (2.5.2)
15
+ rspec-expectations (2.5.0)
16
+ diff-lcs (~> 1.1.2)
17
+ rspec-mocks (2.5.0)
18
+
19
+ PLATFORMS
20
+ ruby
21
+
22
+ DEPENDENCIES
23
+ bundler (>= 1.0.0)
24
+ partitioner!
25
+ rspec (>= 2.5.0)
data/README.md ADDED
@@ -0,0 +1,21 @@
1
+ Partitioner
2
+ =============
3
+
4
+ The Partitioner can be used to evenly distribute sets of anything
5
+ with a numeric cost to into buckets.
6
+
7
+ Proposed usage and reason for existence is to distribute specs over
8
+ multiple machines.
9
+
10
+ Inputs
11
+ -------
12
+
13
+ At first, the knowledge base must be preseeded wih your data.
14
+ The datastructure is an Array, where each element is a bi-tupel of
15
+
16
+ [ Identifier, Costs ]
17
+
18
+ Examples
19
+ -------
20
+
21
+ See specs for examples
@@ -0,0 +1,56 @@
1
+ require 'partitioner/bucket'
2
+ class Partitioner
3
+ attr_accessor :kb, :bucket_count
4
+ def initialize(bucket_count = nil)
5
+ @kb = {}
6
+ @bucket_count = bucket_count
7
+ @prepared = false
8
+ end
9
+
10
+ def buckets
11
+ time_optimal_size! unless @bucket_count
12
+ fill_buckets unless @prepared
13
+ @buckets
14
+ end
15
+ alias subsets buckets
16
+
17
+ def smallest_bucket
18
+ cadidate = @buckets.detect(&:empty?)
19
+ candidate ||= @buckets.min {|a,b| a.value_sum <=> b.value_sum}
20
+ candidate
21
+ end
22
+
23
+ def biggest_bucket
24
+ @buckets.max {|a,b| a.value_sum <=> b.value_sum}
25
+ end
26
+
27
+ def fill_buckets
28
+ reset!
29
+ kb = @kb.dup
30
+ kb = kb.sort_by {|x| x.last}.reverse
31
+
32
+ while !kb.empty?
33
+ smallest_bucket << kb.shift
34
+ end
35
+ @prepared = true
36
+ end
37
+
38
+ def reset!
39
+ @buckets = Array.new(@bucket_count) { Bucket.new }
40
+ @prepared = false
41
+ end
42
+
43
+ # optimizes the bucketsize for time
44
+ # takes the longest critical path (biggest task)
45
+ # and calculates the amount of buckets of equal size
46
+ # needed that all other tasks can fit in them
47
+ def time_optimal_size
48
+ total_time = kb.inject(0){|a,b| a+b.last}
49
+ (total_time / kb.map(&:last).max.to_f).ceil
50
+ end
51
+
52
+ def time_optimal_size!
53
+ @bucket_count = time_optimal_size
54
+ end
55
+
56
+ end
@@ -0,0 +1,7 @@
1
+ class Partitioner
2
+ class Bucket < Array
3
+ def value_sum
4
+ self.inject(0) {|a,b| a+b.last}
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "partitioner"
5
+ s.version = "0.1.0"
6
+ s.platform = Gem::Platform::RUBY
7
+ s.authors = []
8
+ s.email = []
9
+ s.homepage = "http://rubygems.org/gems/partitioner"
10
+ s.summary = "get all your tasks parallelized into even buckets."
11
+ s.description = "partitioner. solves the bin packing problem."
12
+
13
+ s.required_rubygems_version = ">= 1.3.6"
14
+ s.rubyforge_project = "partitioner"
15
+
16
+ s.add_development_dependency "bundler", ">= 1.0.0"
17
+ s.add_development_dependency "rspec", ">= 2.5.0"
18
+
19
+
20
+ s.files = `git ls-files`.split("\n")
21
+ s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
22
+ s.require_path = 'lib'
23
+ end
@@ -0,0 +1,61 @@
1
+ require 'rspec'
2
+ require 'partitioner'
3
+
4
+ describe Partitioner do
5
+
6
+ def create_timings(array)
7
+ ret = []
8
+ array.each_with_index do |e,i|
9
+ ret << [i, e]
10
+ end
11
+ ret
12
+ end
13
+
14
+ before(:each) do
15
+ @partition = Partitioner.new(4)
16
+ end
17
+
18
+ it "should be able to just fit in 1" do
19
+ @partition.kb = create_timings([1])
20
+ @partition.subsets.map {|x| x.map(&:last)}.should include [1]
21
+ @partition.subsets.map {|x| x.map(&:last)}.should include []
22
+ end
23
+
24
+ it "should do the right thing with a 1..6 range" do
25
+ @partition.kb = create_timings([1,2,3,4,5,6])
26
+ @partition.subsets.map {|x| x.map(&:last)}.should include [6]
27
+ @partition.subsets.map {|x| x.map(&:last)}.should include [5]
28
+ @partition.subsets.map {|x| x.map(&:last)}.should include [4,1]
29
+ @partition.subsets.map {|x| x.map(&:last)}.should include [3,2]
30
+ end
31
+
32
+ it "should do the right thing with a 1..7 range" do
33
+ @partition.kb = create_timings([1,2,3,4,5,6,7])
34
+ @partition.subsets.map {|x| x.map(&:last)}.should include [7]
35
+ @partition.subsets.map {|x| x.map(&:last)}.should include [6,1]
36
+ @partition.subsets.map {|x| x.map(&:last)}.should include [5,2]
37
+ @partition.subsets.map {|x| x.map(&:last)}.should include [4,3]
38
+ end
39
+
40
+ describe "the optimization capability" do
41
+ describe "of time" do
42
+ describe "calculates the optimum for" do
43
+
44
+ it "a single element" do
45
+ @partition.kb = [[1,1]]
46
+ @partition.time_optimal_size.should == 1
47
+ end
48
+
49
+ it "an even kb" do
50
+ @partition.kb = create_timings([5,5,5,5])
51
+ @partition.time_optimal_size.should == 4
52
+ end
53
+
54
+ it "an extreme kb" do
55
+ @partition.kb = create_timings([5,1,1,1,1])
56
+ @partition.time_optimal_size.should == 2
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: partitioner
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors: []
13
+
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-05-13 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: bundler
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 23
30
+ segments:
31
+ - 1
32
+ - 0
33
+ - 0
34
+ version: 1.0.0
35
+ type: :development
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: rspec
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 27
46
+ segments:
47
+ - 2
48
+ - 5
49
+ - 0
50
+ version: 2.5.0
51
+ type: :development
52
+ version_requirements: *id002
53
+ description: partitioner. solves the bin packing problem.
54
+ email: []
55
+
56
+ executables: []
57
+
58
+ extensions: []
59
+
60
+ extra_rdoc_files: []
61
+
62
+ files:
63
+ - .gitignore
64
+ - Gemfile
65
+ - Gemfile.lock
66
+ - README.md
67
+ - lib/partitioner.rb
68
+ - lib/partitioner/bucket.rb
69
+ - partitioner.gemspec
70
+ - spec/partitioner_spec.rb
71
+ has_rdoc: true
72
+ homepage: http://rubygems.org/gems/partitioner
73
+ licenses: []
74
+
75
+ post_install_message:
76
+ rdoc_options: []
77
+
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
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: 23
95
+ segments:
96
+ - 1
97
+ - 3
98
+ - 6
99
+ version: 1.3.6
100
+ requirements: []
101
+
102
+ rubyforge_project: partitioner
103
+ rubygems_version: 1.3.7
104
+ signing_key:
105
+ specification_version: 3
106
+ summary: get all your tasks parallelized into even buckets.
107
+ test_files: []
108
+