class NoSE::Plans::UpdatePlanner
A planner for update statements in the workload
Public Class Methods
new(model, trees, cost_model, by_id_graph = false)
click to toggle source
# File lib/nose/plans/update_planner.rb, line 188 def initialize(model, trees, cost_model, by_id_graph = false) @logger = Logging.logger['nose::update_planner'] @model = model @cost_model = cost_model @by_id_graph = by_id_graph # Remove anything not a support query then group by statement and index @query_plans = trees.select do |tree| tree.query.is_a? SupportQuery end @query_plans = @query_plans.group_by { |tree| tree.query.statement } @query_plans.each do |plan_stmt, plan_trees| @query_plans[plan_stmt] = plan_trees.group_by do |tree| index = tree.query.index index = index.to_id_path if @by_id_path index end end end
Public Instance Methods
find_plans_for_update(statement, indexes)
click to toggle source
Find the necessary update plans for a given set of indexes @return [Array<UpdatePlan>]
# File lib/nose/plans/update_planner.rb, line 212 def find_plans_for_update(statement, indexes) indexes = indexes.map(&:to_id_graph).to_set if @by_id_graph indexes.map do |index| next unless statement.modifies_index?(index) if (@query_plans[statement] && @query_plans[statement][index]).nil? trees = [] if statement.is_a? Insert cardinality = 1 else cardinality = Cardinality.filter index.entries, statement.eq_fields, statement.range_field end else # Get the cardinality of the last step to use for the update state trees = @query_plans[statement][index] plans = trees.map do |tree| tree.select_using_indexes(indexes).min_by(&:cost) end # Multiply the cardinalities because we are crossing multiple # relationships and need the cross-product cardinality = plans.product_by { |p| p.last.state.cardinality } end state = UpdateState.new statement, cardinality update_steps = update_steps statement, index, state UpdatePlan.new statement, index, trees, update_steps, @cost_model end.compact end
Private Instance Methods
update_steps(statement, index, state)
click to toggle source
Find the required update steps @return [Array<UpdatePlanStep>]
# File lib/nose/plans/update_planner.rb, line 251 def update_steps(statement, index, state) update_steps = [] update_steps << DeletePlanStep.new(index, state) \ if statement.requires_delete?(index) if statement.requires_insert?(index) fields = if statement.is_a?(Connect) statement.conditions.each_value.map(&:field) else statement.settings.map(&:field) end update_steps << InsertPlanStep.new(index, state, fields) end update_steps end