class Bmg::Operator::Image

Image operator.

Extends each tuple with its image in right.

Constants

DEFAULT_OPTIONS

Attributes

as[R]
on[R]
options[R]

Public Class Methods

new(type, left, right, as, on, options = {}) click to toggle source
# File lib/bmg/operator/image.rb, line 37
def initialize(type, left, right, as, on, options = {})
  @type = type
  @left = left
  @right = right
  @as = as
  @on = on
  @options = DEFAULT_OPTIONS.merge(options)
end

Public Instance Methods

each(*args, &bl) click to toggle source
# File lib/bmg/operator/image.rb, line 52
def each(*args, &bl)
  return to_enum unless block_given?
  (options[:jit_optimized] ? self : jit_optimize)._each(*args, &bl)
end
to_ast() click to toggle source
# File lib/bmg/operator/image.rb, line 57
def to_ast
  [ :image, left.to_ast, right.to_ast, as, on, options.dup ]
end

Protected Instance Methods

_each(*args, &bl) click to toggle source
# File lib/bmg/operator/image.rb, line 63
def _each(*args, &bl)
  case s = options[:strategy]
  when :index_right then _each_index_right(*args, &bl)
  when :refilter_right then _each_refilter_right(*args, &bl)
  else
    raise ArgumentError, "Unknown strategy `#{s}`"
  end
end
_each_implem(left_rel, right_rel, *args) { |merge(as => image)| ... } click to toggle source
# File lib/bmg/operator/image.rb, line 89
def _each_implem(left_rel, right_rel, *args)
  # build right index
  index = build_right_index(right_rel)

  # each left with image from right index
  left_rel.each do |tuple|
    key = tuple_project(tuple, on)
    image = index[key] || (options[:array] ? [] : empty_image)
    yield tuple.merge(as => image)
  end
end
_each_index_right(*args, &bl) click to toggle source
# File lib/bmg/operator/image.rb, line 72
def _each_index_right(*args, &bl)
  left_rel, right_rel = self.left, self.right
  _each_implem(left_rel, right_rel, *args, &bl)
end
_each_refilter_right(*args, &bl) click to toggle source
# File lib/bmg/operator/image.rb, line 77
def _each_refilter_right(*args, &bl)
  left_rel, right_rel = self.left, self.right

  # find matching keys on left and rebind the right
  # placeholder to them
  values = left_rel.map{|t| t[on.first] }
  placeholder = options[:refilter_right][:placeholder]
  right_rel = right_rel.bind(placeholder => values)

  _each_implem(left_rel, right_rel, *args, &bl)
end
build_right_index(right) click to toggle source
# File lib/bmg/operator/image.rb, line 101
def build_right_index(right)
  index = Hash.new{|h,k| h[k] = empty_image }
  butlist = options[:preserve] ? [] : on
  right.each_with_object(index) do |t, index|
    key = tuple_project(t, on)
    index[key].operand << tuple_allbut(t, butlist)
  end
  if opt = options[:array]
    sorter = to_sorter(opt)
    index = index.each_with_object({}) do |(k,v),ix|
      ix[k] = sorter ? v.to_a.sort(&sorter) : v.to_a
    end
  end
  index
end