Class: Qfill::Result

Inherits:
List
  • Object
show all
Defined in:
lib/qfill/result.rb

Instance Attribute Summary collapse

Attributes inherited from List

#elements, #filter, #name

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Result

Returns a new instance of Result.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/qfill/result.rb', line 40

def initialize(options = {})
  super(options)
  @list_ratios = options[:list_ratios] || {}
  with_ratio = list_ratio_as_array.map { |tuple| tuple[1] }.compact
  ratio_leftover = (1 - with_ratio.sum)
  if ratio_leftover.negative?
    raise ArgumentError,
          "#{self.class}: invalid list_ratios for queue '#{name}'. List Ratios (#{with_ratio.join(' + ')}) must not total more than 1"
  end

  @ratio = options[:ratio] || 1
  @max = 0
  @preferred = options[:preferred] # Used by :drain_to_empty and :drain_to_limit
  @preferred_potential = 0
  @preferred_potential_ratio = 0
  @fill_tracker = {}
  @max_tracker = {}
  # Doesn't reset to 0 on reset!
  @total_count = 0
  # Does reset to 0 on reset!
  @current_count = 0
  @shuffle = options[:shuffle] || false
  @current_list_ratio_index = 0 # Used by :sample strategy
  @validate = use_validation?
end

Instance Attribute Details

#current_countObject

Returns the value of attribute current_count.



16
17
18
# File 'lib/qfill/result.rb', line 16

def current_count
  @current_count
end

#current_list_ratio_indexObject

Returns the value of attribute current_list_ratio_index.



16
17
18
# File 'lib/qfill/result.rb', line 16

def current_list_ratio_index
  @current_list_ratio_index
end

#fill_trackerObject

Returns the value of attribute fill_tracker.



16
17
18
# File 'lib/qfill/result.rb', line 16

def fill_tracker
  @fill_tracker
end

#list_ratiosObject

Returns the value of attribute list_ratios.



16
17
18
# File 'lib/qfill/result.rb', line 16

def list_ratios
  @list_ratios
end

#maxObject

Returns the value of attribute max.



16
17
18
# File 'lib/qfill/result.rb', line 16

def max
  @max
end

#max_trackerObject

Returns the value of attribute max_tracker.



16
17
18
# File 'lib/qfill/result.rb', line 16

def max_tracker
  @max_tracker
end

#preferredObject

Returns the value of attribute preferred.



16
17
18
# File 'lib/qfill/result.rb', line 16

def preferred
  @preferred
end

#preferred_potentialObject

Returns the value of attribute preferred_potential.



16
17
18
# File 'lib/qfill/result.rb', line 16

def preferred_potential
  @preferred_potential
end

#preferred_potential_ratioObject

Returns the value of attribute preferred_potential_ratio.



16
17
18
# File 'lib/qfill/result.rb', line 16

def preferred_potential_ratio
  @preferred_potential_ratio
end

#ratioObject

Returns the value of attribute ratio.



16
17
18
# File 'lib/qfill/result.rb', line 16

def ratio
  @ratio
end

#shuffleObject

Returns the value of attribute shuffle.



16
17
18
# File 'lib/qfill/result.rb', line 16

def shuffle
  @shuffle
end

#total_countObject

Returns the value of attribute total_count.



16
17
18
# File 'lib/qfill/result.rb', line 16

def total_count
  @total_count
end

#validateObject

Returns the value of attribute validate.



16
17
18
# File 'lib/qfill/result.rb', line 16

def validate
  @validate
end

Class Method Details

.get_limit_from_max_and_ratio(all_list_max, ratio, remain = nil) ⇒ Object



30
31
32
33
34
35
36
37
38
# File 'lib/qfill/result.rb', line 30

def self.get_limit_from_max_and_ratio(all_list_max, ratio, remain = nil)
  return 1 if remain == 1

  limit = (all_list_max * ratio).round(0)
  # If we rounded down to zero we have to keep at least one.
  # This is because with small origin sets all ratios might round down to 0.
  limit += 1 if limit.zero?
  remain ? [limit, remain].min : limit
end

Instance Method Details

#add!(object) ⇒ Object



93
94
95
# File 'lib/qfill/result.rb', line 93

def add!(object)
  elements << object
end

#allow?(object, list_name) ⇒ Boolean

Returns:

  • (Boolean)


97
98
99
100
101
# File 'lib/qfill/result.rb', line 97

def allow?(object, list_name)
  !filter.respond_to?(:call) ||
    # If there is a filter, then it must return true to proceed
    filter.run(object, list_name)
end

#bump_fill_tracker!(list_name) ⇒ Object



103
104
105
106
107
# File 'lib/qfill/result.rb', line 103

def bump_fill_tracker!(list_name)
  fill_tracker[list_name] += 1
  self.total_count += 1
  self.current_count += 1
end

#current_list_ratioObject



130
131
132
# File 'lib/qfill/result.rb', line 130

def current_list_ratio
  list_ratio_as_array[current_list_ratio_index]
end

#is_full?Boolean

Results can overfill, because fractions.

Returns:

  • (Boolean)


150
151
152
# File 'lib/qfill/result.rb', line 150

def is_full?
  self.total_count >= max
end

#list_ratio_as_arrayObject



125
126
127
128
# File 'lib/qfill/result.rb', line 125

def list_ratio_as_array
  # [["high",0.4],["medium",0.4],["low",0.2]]
  @list_ratio_as_array ||= list_ratios.to_a
end

#list_ratio_full?(list_name, max_from_list) ⇒ Boolean

Returns:

  • (Boolean)


66
67
68
# File 'lib/qfill/result.rb', line 66

def list_ratio_full?(list_name, max_from_list)
  fill_tracker[list_name] >= max_from_list
end


89
90
91
# File 'lib/qfill/result.rb', line 89

def print(list_name)
  puts "Added to #{list_name}.\nResult List #{name} now has #{elements.length} total objects.\nSources:\n #{fill_tracker.inspect} "
end

#push(objects, list_name) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/qfill/result.rb', line 70

def push(objects, list_name)
  validate!(list_name)
  added = 0
  fill_tracker[list_name] ||= 0
  objects.each do |object|
    # The objects have already been popped.
    # The only valid reason to not push an object at this point is if !allow?.
    # break if is_full?

    next unless allow?(object, list_name)

    bump_fill_tracker!(list_name)
    add!(object)
    added += 1
    # self.print(list_name)
  end
  added
end

#reset!Object



144
145
146
147
# File 'lib/qfill/result.rb', line 144

def reset!
  self.current_list_ratio_index = 0
  self.current_count = 0
end

#set_next_as_current!Object



134
135
136
137
138
139
140
141
142
# File 'lib/qfill/result.rb', line 134

def set_next_as_current!
  next_index = current_list_ratio_index + 1
  if (next_index) == list_ratio_as_array.length
    # If we have iterated through all the list_ratios, then we reset
    reset!
  else
    self.current_list_ratio_index = next_index
  end
end

#to_sObject



154
155
156
# File 'lib/qfill/result.rb', line 154

def to_s
  "Qfill::Result: ratio: #{ratio}, list_ratios: #{list_ratios}, fill_tracker: #{fill_tracker}, total_count: #{self.total_count}, current_count: #{self.current_count}, filter: #{!!filter ? 'Yes' : 'No'}, current_list_ratio_index: #{current_list_ratio_index}, max: #{max}"
end

#use_validation?Boolean

Returns:

  • (Boolean)


121
122
123
# File 'lib/qfill/result.rb', line 121

def use_validation?
  !list_ratios.empty?
end

#valid?(list_name) ⇒ Boolean

Does the queue being pushed into match one of the list_ratios

Returns:

  • (Boolean)


110
111
112
# File 'lib/qfill/result.rb', line 110

def valid?(list_name)
  list_ratios.key?(list_name)
end

#validate!(list_name) ⇒ Object



114
115
116
117
118
119
# File 'lib/qfill/result.rb', line 114

def validate!(list_name)
  if validate && !valid?(list_name)
    raise ArgumentError,
          "#{self.class}: #{list_name} is an invalid list_name.  Valid list_names are: #{list_ratios.keys}"
  end
end