Class: Splashy::Buckets
- Inherits:
-
Object
- Object
- Splashy::Buckets
- Defined in:
- lib/splashy/buckets.rb
Instance Method Summary collapse
-
#add(bucket_name, element) ⇒ Object
Public: Add a single element to a bucket.
-
#fill(bucket_name = nil, &block) ⇒ Object
Public: Put elements into buckets.
-
#initialize(wanted_distribution, wanted_count = nil) ⇒ Buckets
constructor
wanted_distribution - A Hash of desired distributions: { :a => 0.2, :b => 0.5, :c => 0.3 } wanted_count - (optional) Maximum total elements to be selected.
-
#satisfied? ⇒ Boolean
Returns true if the conditions are satisfied enough to select.
-
#select ⇒ Object
Public: Return a distribution of elements based on the desired distribution.
Constructor Details
#initialize(wanted_distribution, wanted_count = nil) ⇒ Buckets
wanted_distribution - A Hash of desired distributions:
{ :a => 0.2, :b => 0.5, :c => 0.3 }
wanted_count - (optional) Maximum total elements to be selected.
otherwise, the maximum size set is selected.
7 8 9 10 11 12 13 14 15 16 17 |
# File 'lib/splashy/buckets.rb', line 7 def initialize( wanted_distribution, wanted_count=nil ) unless wanted_distribution.values.inject(0){ |m,v| m + v } == 1.0 raise ArgumentError.new( "Distribution must sum to 1.0" ) end @wanted_distribution = wanted_distribution @wanted_count = wanted_count @buckets = Hash.new do |hash, name| hash[name] = Bucket.new( name ) end @total_count = 0 end |
Instance Method Details
#add(bucket_name, element) ⇒ Object
Public: Add a single element to a bucket.
44 45 46 47 |
# File 'lib/splashy/buckets.rb', line 44 def add( bucket_name, element ) @buckets[bucket_name] << element @total_count += 1 end |
#fill(bucket_name = nil, &block) ⇒ Object
Public: Put elements into buckets.
bucket_name - If supplied, all yielded elements will be added to that
bucket.
&block - A block that returns (if ‘bucket_name` is not supplied)
an Array: [bucket_name, element]. If `bucket_name` is
supplied, only the element needs to be returned.
Examples
fill { return [bucket_name, element] }
fill( :bucket_name ) { return element }
31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/splashy/buckets.rb', line 31 def fill( bucket_name = nil, &block ) if bucket_name while element = yield( @total_count ) self.add( bucket_name, element ) end else while pair = yield( @total_count ) self.add( *pair ) end end end |
#satisfied? ⇒ Boolean
Returns true if the conditions are satisfied enough to select.
50 51 52 53 54 55 56 57 |
# File 'lib/splashy/buckets.rb', line 50 def satisfied? begin self.assert_satisfied! true rescue DistributionUnsatisfiedError => e false end end |
#select ⇒ Object
Public: Return a distribution of elements based on the desired distribution. If a satisfactory distribution is not possible, a DistributionUnsatisfiedError is raised.
Returns a Hash of elements based on the desired distribution, keyed by the bucket names.
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/splashy/buckets.rb', line 65 def select self.assert_satisfied! total_count = estimated_final_count selected = @wanted_distribution.keys.inject({}) do |memo, bucket_name| bucket = @buckets[bucket_name] count = total_count * @wanted_distribution[bucket_name] count = [1, count.round].max memo[bucket_name] = bucket.elements( count ) memo end # Sometimes we need to fudge by a few to meet the `@wanted_count` selected = self.trim( selected ) if @wanted_count selected end |