Class: NoSE::Plans::UpdatePlanner

Inherits:
Object
  • Object
show all
Defined in:
lib/nose/plans/update_planner.rb

Overview

A planner for update statements in the workload

Instance Method Summary collapse

Constructor Details

#initialize(model, trees, cost_model, by_id_graph = false) ⇒ UpdatePlanner

Returns a new instance of UpdatePlanner.



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# 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

Instance Method Details

#find_plans_for_update(statement, indexes) ⇒ Array<UpdatePlan>

Find the necessary update plans for a given set of indexes

Returns:



212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# 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