Class: Qfill::Manager

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

Constant Summary collapse

STRATEGY_OPTIONS =
[:drain_to_limit, :drain_to_empty, :sample]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Manager

Returns a new instance of Manager.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/qfill/manager.rb', line 12

def initialize(options = {})
  unless options[:popper] && options[:pusher]
    raise ArgumentError, "#{self.class}: popper and pusher are required options for #{self.class}.new(options)"
  end
  unless options[:strategy].nil? || STRATEGY_OPTIONS.include?(options[:strategy])
    if options[:strategy] == :drain
      warn "Qfill strategy :drain has been renamed :drain_to_limit, please update your code."
      options[:strategy] = :drain_to_limit
    else
      raise ArgumentError, "#{self.class}: strategy is optional, but must be one of #{STRATEGY_OPTIONS.inspect} if provided"
    end
  end
  @popper = options[:popper]
  @pusher = options[:pusher]
  # Provided by user, or defaults to the total number of primary elements in popper list set
  @all_list_max = options[:all_list_max] ? [options[:all_list_max], self.popper.count_primary_elements].min : self.popper.count_primary_elements
  @fill_count = 0
  @strategy = options[:strategy] || :drain_to_limit # or :drain_to_empty or :sample
end

Instance Attribute Details

#all_list_maxObject

Returns the value of attribute all_list_max.



8
9
10
# File 'lib/qfill/manager.rb', line 8

def all_list_max
  @all_list_max
end

#fill_countObject

Returns the value of attribute fill_count.



8
9
10
# File 'lib/qfill/manager.rb', line 8

def fill_count
  @fill_count
end

#popperObject

Returns the value of attribute popper.



8
9
10
# File 'lib/qfill/manager.rb', line 8

def popper
  @popper
end

#pusherObject

Returns the value of attribute pusher.



8
9
10
# File 'lib/qfill/manager.rb', line 8

def pusher
  @pusher
end

#resultObject

Returns the value of attribute result.



8
9
10
# File 'lib/qfill/manager.rb', line 8

def result
  @result
end

#strategyObject

Returns the value of attribute strategy.



8
9
10
# File 'lib/qfill/manager.rb', line 8

def strategy
  @strategy
end

Instance Method Details

#current_strategyObject



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

def current_strategy
  (result.strategy || self.strategy)
end

#fill!Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/qfill/manager.rb', line 32

def fill!
  while !is_full? && !self.popper.primary_empty? && (self.result = self.pusher.current_list)
    if self.current_strategy == :drain_to_empty
      preferred_potential_ratio = 0
      preferred_potential = 0
      self.result.list_ratios.each do |list_name, list_ratio|
        poppy = self.result.preferred.select {|x| x == list_name}
        if poppy
          preferred_potential_ratio += list_ratio
          num = self.popper[list_name].elements.length
          preferred_potential += num
          self.result.max_tracker[list_name] = num
        end
      end
      self.result.preferred_potential = preferred_potential
      self.result.preferred_potential_ratio = preferred_potential_ratio
    end
    self.fill_to_ratio!
    self.pusher.set_next_as_current!
    self.result.elements.shuffle! if self.result.shuffle
  end
end

#fill_according_to_list_ratios!Object

Go through the queues this result should be filled from and push elements from them onto the current result list.



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/qfill/manager.rb', line 75

def fill_according_to_list_ratios!
  added = 0
  tally = 0
  ratio_modifier = 1
  case self.current_strategy
    when :drain_to_empty then
      # Are there any elements in preferred queues that we should add?
      if self.result.preferred_potential > 0
        # Setup a ratio modifier for the non-preferred queues
        result.list_ratios.each do |list_name, list_ratio|
          max_from_list = self.result.max_tracker[list_name] || Qfill::Result.get_limit_from_max_and_ratio(result.max, list_ratio)
          array_to_push = self.popper.next_objects!(list_name, max_from_list)
          self.popper.current_index = self.popper.index_of(list_name)
          added = result.push(array_to_push, list_name)
          puts "[fill_according_to_list_ratios!]#{self}[#{list_name}][added:#{added}]" if Qfill::VERBOSE
          tally += added
        end
        self.fill_count += tally
      end
    when :drain_to_limit
      result.list_ratios.each do |list_name, list_ratio|
        max_from_list = Qfill::Result.get_limit_from_max_and_ratio(result.max, list_ratio)
        array_to_push = self.popper.next_objects!(list_name, max_from_list)
        self.popper.current_index = self.popper.index_of(list_name)
        added = result.push(array_to_push, list_name)
        puts "[fill_according_to_list_ratios!]#{self}[#{list_name}][added:#{added}]" if Qfill::VERBOSE
        tally += added
      end
      self.fill_count += tally
    when :sample then
      #puts "#{!is_full?} && #{result.fill_count} >= #{result.max} && #{!self.popper.totally_empty?} && #{(list_ratio_tuple = result.current_list_ratio)}"
      while !is_full? && !result.is_full? && !self.popper.totally_empty? && (list_ratio_tuple = result.current_list_ratio)
        max_from_list = Qfill::Result.get_limit_from_max_and_ratio(result.max, list_ratio_tuple[1])
        array_to_push = self.popper.next_objects!(list_ratio_tuple[0], max_from_list)
        added = result.push(array_to_push, list_ratio_tuple[0])
        self.fill_count += added
        puts "[fill_according_to_list_ratios!]#{self}[#{list_ratio_tuple[0]}][added:#{added}]" if Qfill::VERBOSE
        result.set_next_as_current!
      end
  end
end

#fill_to_ratio!Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/qfill/manager.rb', line 55

def fill_to_ratio!
  case self.current_strategy
    when :drain_to_empty then
      result.max = self.result.preferred_potential_ratio > 0 ? [(self.result.preferred_potential / self.result.preferred_potential_ratio), self.remaining_to_fill].min : self.remaining_to_fill
    when :drain_to_limit, :sample then
      result.max = Qfill::Result.get_limit_from_max_and_ratio(self.remaining_to_fill, result.ratio)
  end
  #result.max = Qfill::Result.get_limit_from_max_and_ratio(self.all_list_max, result.ratio)
  if !result.list_ratios.empty?
    self.fill_according_to_list_ratios!
  else
    self.fill_up_to_ratio!
  end
end

#fill_up_to_ratio!Object

Go through the primary (non backfill) queues in the popper and push elements from them onto the current result list.



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/qfill/manager.rb', line 118

def fill_up_to_ratio!
  added = 0
  tally = 0
  if self.current_strategy == :drain_to_empty
    self.popper.primary.each do |queue|
      array_to_push = self.popper.next_objects!(queue.name, result.max)
      added = result.push(array_to_push, queue.name)
      self.popper.current_index = self.popper.index_of(queue.name)
      puts "[fill_up_to_ratio!]#{self}[Q:#{queue.name}][added:#{added}]" if Qfill::VERBOSE
      tally += added
    end
    self.fill_count += added
  else
    ratio = 1.0 / self.popper.primary.length # 1 divided by the number of queues
    max_from_list = Qfill::Result.get_limit_from_max_and_ratio(result.max, ratio)
    if self.current_strategy == :drain_to_limit
      self.popper.primary.each do |queue|
        array_to_push = self.popper.next_objects!(queue.name, max_from_list)
        added = result.push(array_to_push, queue.name)
        self.popper.current_index = self.popper.index_of(queue.name)
        puts "[fill_up_to_ratio!]#{self}[Q:#{queue.name}][added:#{added}]" if Qfill::VERBOSE
        tally += added
      end
      self.fill_count += tally
    elsif self.current_strategy == :sample
      while !is_full? && !result.is_full? && !self.popper.totally_empty? && (origin_list = self.popper.current_list)
        array_to_push = self.popper.next_objects!(origin_list.name, max_from_list)
        added = result.push(array_to_push, origin_list.name)
        self.fill_count += added
        puts "[fill_up_to_ratio!]#{self}[Added:#{added}][Max List:#{max_from_list}][ratio:#{ratio}][added:#{added}]" if Qfill::VERBOSE
        self.popper.set_next_as_current!
      end
    end
  end
end

#is_full?Boolean

Returns:

  • (Boolean)


158
159
160
# File 'lib/qfill/manager.rb', line 158

def is_full?
  self.fill_count >= self.all_list_max
end

#remaining_to_fillObject



70
71
72
# File 'lib/qfill/manager.rb', line 70

def remaining_to_fill
  self.all_list_max - self.fill_count
end

#to_sObject



162
163
164
# File 'lib/qfill/manager.rb', line 162

def to_s
  "[#{self.current_strategy}][Result Max:#{result.max}][All Max:#{self.all_list_max}][Current Max:#{self.result.max}][Filled:#{self.fill_count}][Primary #:#{self.popper.count_primary_elements}]"
end