Class: RedShift::Queue

Inherits:
Object show all
Defined in:
lib/redshift/queue.rb

Defined Under Namespace

Classes: QueueEmptyError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(component) ⇒ Queue

Returns a new instance of Queue.



10
11
12
13
14
15
# File 'lib/redshift/queue.rb', line 10

def initialize component
  @q = []
  @step_count = nil
  @discrete_step = nil
  @component = component
end

Instance Attribute Details

#componentObject (readonly)

Owner of the queue.



8
9
10
# File 'lib/redshift/queue.rb', line 8

def component
  @component
end

Instance Method Details

#head_matches(*conds) ⇒ Object

Called from guard evaluation in step_discrete. Returns true if at least one entry in the head of the queue matches all of the conditions, which may be Procs (called to return boolean) or any objects with #===.



80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/redshift/queue.rb', line 80

def head_matches(*conds)
  return false if @q.empty?
  head = @q[0]
  case head
  when SimultaneousQueueEntries
    head.any? do |head_item|
      item_matches conds, head_item
    end
  else
    item_matches conds, head
  end
end

#item_matches(conds, item) ⇒ Object



93
94
95
96
97
98
99
100
101
102
# File 'lib/redshift/queue.rb', line 93

def item_matches conds, item
  conds.all? do |cond|
    case cond
    when Proc
      cond.call(item)
    else
      cond === item
    end
  end
end

#popObject

When popping from a queue, the result may be an instance of SimultaneousQueueEntries, which should probably be handled specially.



49
50
51
52
53
54
55
56
# File 'lib/redshift/queue.rb', line 49

def pop
  if @q.empty?
    raise QueueEmptyError, "tried to pop empty queue in #{@component.inspect}"
  end
  obj = @q.shift
  @component.dec_queue_ready_count if @q.empty?
  obj
end

#push(obj) ⇒ Object Also known as: <<



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/redshift/queue.rb', line 17

def push obj
  world = @component.world
  step_count = world.step_count
  discrete_step = world.discrete_step
  
  if step_count == @step_count and discrete_step == @discrete_step
    last = @q[-1]
    case last
    when SimultaneousQueueEntries
      last << obj
    when nil; raise "Internal error: expected simultaneous queue entry."
    else
      @q[-1] = SimultaneousQueueEntries[last, obj]
    end
  
  else
    was_empty = @q.empty?
    @step_count = step_count
    @discrete_step = discrete_step
    @q << obj
    @component.inc_queue_ready_count if was_empty
  end
  
  self
end

#unpop(obj) ⇒ Object

Correctly handles case when obj is SimultaneousQueueEntries.



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/redshift/queue.rb', line 59

def unpop obj
  was_empty = @q.empty?
  case obj
  when SimultaneousQueueEntries
    case obj.size
    when 0
      was_empty = false # just to prevent the inc
    when 1
      @q.unshift obj.first
    else
      @q.unshift obj
    end
  else
    @q.unshift obj
  end
  @component.inc_queue_ready_count if was_empty
end