class Concurrent::Collection::RubyNonConcurrentPriorityQueue

@!macro internal_implementation_note
@!visibility private
@!macro priority_queue

def self.from_list(list, opts = {})

@!macro priority_queue_method_from_list
def self.from_list(list, opts = {})
  queue = new(opts)
  list.each{|item| queue << item }
  queue
end

def clear

@!macro priority_queue_method_clear
def clear
  @queue = [nil]
  @length = 0
  true
end

def delete(item)

@!macro priority_queue_method_delete
def delete(item)
  return false if empty?
  original_length = @length
  k = 1
  while k <= @length
    if @queue[k] == item
      swap(k, @length)
      @length -= 1
      sink(k) || swim(k)
      @queue.pop
    else
      k += 1
    end
  end
  @length != original_length
end

def empty?

@!macro priority_queue_method_empty
def empty?
  size == 0
end

def include?(item)

@!macro priority_queue_method_include
def include?(item)
  @queue.include?(item)
end

def initialize(opts = {})

@!macro priority_queue_method_initialize
def initialize(opts = {})
  order = opts.fetch(:order, :max)
  @comparator = [:min, :low].include?(order) ? -1 : 1
  clear
end

def length

@!macro priority_queue_method_length
def length
  @length
end

def ordered?(x, y)

Returns:
  • (Boolean) - true if the two elements are in the correct priority order

Parameters:
  • y (Integer) -- the second index from which to retrieve a comparable value
  • x (Integer) -- the first index from which to retrieve a comparable value
def ordered?(x, y)
  (@queue[x] <=> @queue[y]) == @comparator
end

def peek

@!macro priority_queue_method_peek
def peek
  empty? ? nil : @queue[1]
end

def pop

@!macro priority_queue_method_pop
def pop
  return nil if empty?
  max = @queue[1]
  swap(1, @length)
  @length -= 1
  sink(1)
  @queue.pop
  max
end

def push(item)

@!macro priority_queue_method_push
def push(item)
  raise ArgumentError.new('cannot enqueue nil') if item.nil?
  @length += 1
  @queue << item
  swim(@length)
  true
end

def sink(k)

Parameters:
  • k (Integer) -- the index at which to start the percolation
def sink(k)
  success = false
  while (j = (2 * k)) <= @length do
    j += 1 if j < @length && ! ordered?(j, j+1)
    break if ordered?(k, j)
    swap(k, j)
    success = true
    k = j
  end
  success
end

def swap(x, y)

Parameters:
  • y (Integer) -- the second index to swap
  • x (Integer) -- the first index to swap
def swap(x, y)
  temp = @queue[x]
  @queue[x] = @queue[y]
  @queue[y] = temp
end

def swim(k)

Parameters:
  • k (Integer) -- the index at which to start the percolation
def swim(k)
  success = false
  while k > 1 && ! ordered?(k/2, k) do
    swap(k, k/2)
    k = k/2
    success = true
  end
  success
end