Module: Contrek::Concurrent::Queueable

Included in:
Part, Sequence
Defined in:
lib/contrek/finder/concurrent/queueable.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#headObject (readonly)

Returns the value of attribute head.



4
5
6
# File 'lib/contrek/finder/concurrent/queueable.rb', line 4

def head
  @head
end

#sizeObject (readonly)

Returns the value of attribute size.



4
5
6
# File 'lib/contrek/finder/concurrent/queueable.rb', line 4

def size
  @size
end

#tailObject (readonly)

Returns the value of attribute tail.



4
5
6
# File 'lib/contrek/finder/concurrent/queueable.rb', line 4

def tail
  @tail
end

Instance Method Details

#add(node) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/contrek/finder/concurrent/queueable.rb', line 30

def add(node)
  node.owner&.rem(node)  # verifies owner presence

  if @tail
    @tail.next = node
    node.prev = @tail
  else
    @head = node
    node.prev = nil
  end
  @tail = node
  node.next = nil
  node.owner = self
  @size += 1

  node.after_add(self)
end

#append(queueable) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/contrek/finder/concurrent/queueable.rb', line 53

def append(queueable)
  return if queueable.size.zero?
  queueable.each do |node|
    node.before_rem(queueable)
    node.owner = self
  end
  if @tail
    @tail.next = queueable.head
    queueable.head.prev = @tail
  else
    @head = queueable.head
  end
  @tail = queueable.tail
  @size += queueable.size
  queueable.reset!

  each { |node| node.after_add(self) }
end

#each(&block) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/contrek/finder/concurrent/queueable.rb', line 87

def each(&block)
  last = nil
  unless @head.nil?
    pointer = @head
    loop do
      yield(pointer)
      last = pointer
      break unless (pointer = pointer.next)
    end
  end
  last
end

#forward!Object



123
124
125
# File 'lib/contrek/finder/concurrent/queueable.rb', line 123

def forward!
  @iterator = iterator.next unless iterator.nil?
end

#initialize(*args, **kwargs, &block) ⇒ Object



5
6
7
8
9
10
11
# File 'lib/contrek/finder/concurrent/queueable.rb', line 5

def initialize(*args, **kwargs, &block)
  super
  @head = nil
  @tail = nil
  @iterator = 0
  @size = 0
end

#intersect_with?(queueable) ⇒ Boolean



160
161
162
# File 'lib/contrek/finder/concurrent/queueable.rb', line 160

def intersect_with?(queueable)
  intersection_with(queueable).any?
end

#intersection_with(queueable) ⇒ Object



145
146
147
148
149
150
151
152
153
# File 'lib/contrek/finder/concurrent/queueable.rb', line 145

def intersection_with(queueable)
  int = []
  each do |node|
    int += queueable.map do |e|
      break [e.payload] if e.payload == node.payload
    end.compact
  end
  int
end

#intersection_with_array?(array) ⇒ Boolean



155
156
157
158
# File 'lib/contrek/finder/concurrent/queueable.rb', line 155

def intersection_with_array?(array)
  each { |node| return true if array.index(node.payload) }
  false
end

#iteratorObject



127
128
129
# File 'lib/contrek/finder/concurrent/queueable.rb', line 127

def iterator
  (@iterator == 0) ? @head : @iterator
end

#map(&block) ⇒ Object



100
101
102
103
104
# File 'lib/contrek/finder/concurrent/queueable.rb', line 100

def map(&block)
  ret_array = []
  each { |node| ret_array << yield(node) }
  ret_array
end

#move_from(queueable, &block) ⇒ Object



72
73
74
75
76
77
78
# File 'lib/contrek/finder/concurrent/queueable.rb', line 72

def move_from(queueable, &block)
  queueable.rewind!
  while (node = queueable.iterator)
    queueable.forward!
    add(node) if yield(node)
  end
end

#next_of!(node) ⇒ Object



135
136
137
138
139
# File 'lib/contrek/finder/concurrent/queueable.rb', line 135

def next_of!(node)
  raise "nil node" if node.nil?
  raise "wrong node" if node.owner != self
  @iterator = node.next
end

#pop!Object



141
142
143
# File 'lib/contrek/finder/concurrent/queueable.rb', line 141

def pop!
  rem(@tail)
end

#rem(node) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/contrek/finder/concurrent/queueable.rb', line 13

def rem(node)
  Raise "Not my node" if node.owner != self

  node.before_rem(self)

  node.prev&.next = node.next
  node.next&.prev = node.prev

  @head = node.next if node == @head
  @tail = node.prev if node == @tail

  node.next = node.prev = node.owner = nil
  @size -= 1

  node
end

#remove_adjacent_pairs(array = nil) ⇒ Object



164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/contrek/finder/concurrent/queueable.rb', line 164

def remove_adjacent_pairs(array = nil)
  array = to_a if array.nil?
  n = array.size
  (0...(n - 1)).each do |i|
    if array[i] == array[i + 1]
      # Remove the pair and call recursively
      new_array = array[0...i] + array[(i + 2)..]
      return remove_adjacent_pairs(new_array)
    end
  end
  array
end

#remove_adjacent_pairs!Object



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/contrek/finder/concurrent/queueable.rb', line 177

def remove_adjacent_pairs!
  unless @tail.nil?
    pointer = @tail
    loop do
      break if pointer == @head
      if pointer.payload == pointer.prev&.payload
        later = pointer.next
        rem pointer.prev
        rem pointer
        pointer = later.nil? ? @tail : later
        redo
      end
      break unless (pointer = pointer.prev)
    end
  end
end

#replace!(queueable) ⇒ Object



48
49
50
51
# File 'lib/contrek/finder/concurrent/queueable.rb', line 48

def replace!(queueable)
  reset!
  append(queueable)
end

#reset!Object



80
81
82
83
84
85
# File 'lib/contrek/finder/concurrent/queueable.rb', line 80

def reset!
  @head = nil
  @tail = nil
  @size = 0
  @iterator = 0
end

#reverse_each(&block) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/contrek/finder/concurrent/queueable.rb', line 106

def reverse_each(&block)
  last = nil
  unless @tail.nil?
    pointer = @tail
    loop do
      yield(pointer)
      last = pointer
      break unless (pointer = pointer.prev)
    end
  end
  last
end

#rewind!Object



131
132
133
# File 'lib/contrek/finder/concurrent/queueable.rb', line 131

def rewind!
  @iterator = 0
end

#to_aObject



119
120
121
# File 'lib/contrek/finder/concurrent/queueable.rb', line 119

def to_a
  map(&:payload)
end