partitioner 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.
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
+