Class: NoSE::Search::Results

Inherits:
Object
  • Object
show all
Defined in:
lib/nose/search/results.rb

Overview

A container for results from a schema search

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(problem = nil, by_id_graph = false) ⇒ Results

Returns a new instance of Results.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/nose/search/results.rb', line 12

def initialize(problem = nil, by_id_graph = false)
  @problem = problem
  return if problem.nil?
  @by_id_graph = by_id_graph

  # Find the indexes the ILP says the query should use
  @query_indexes = Hash.new { |h, k| h[k] = Set.new }
  @problem.query_vars.each do |index, query_vars|
    query_vars.each do |query, var|
      next unless var.value
      @query_indexes[query].add index
    end
  end
end

Instance Attribute Details

#by_id_graphObject

Returns the value of attribute by_id_graph.



8
9
10
# File 'lib/nose/search/results.rb', line 8

def by_id_graph
  @by_id_graph
end

#commandObject

Returns the value of attribute command.



8
9
10
# File 'lib/nose/search/results.rb', line 8

def command
  @command
end

#cost_modelObject

Returns the value of attribute cost_model.



7
8
9
# File 'lib/nose/search/results.rb', line 7

def cost_model
  @cost_model
end

#enumerated_indexesObject

Returns the value of attribute enumerated_indexes.



8
9
10
# File 'lib/nose/search/results.rb', line 8

def enumerated_indexes
  @enumerated_indexes
end

#indexesObject

Returns the value of attribute indexes.



8
9
10
# File 'lib/nose/search/results.rb', line 8

def indexes
  @indexes
end

#plansObject

Returns the value of attribute plans.



8
9
10
# File 'lib/nose/search/results.rb', line 8

def plans
  @plans
end

#revisionObject

Returns the value of attribute revision.



8
9
10
# File 'lib/nose/search/results.rb', line 8

def revision
  @revision
end

#timeObject

Returns the value of attribute time.



8
9
10
# File 'lib/nose/search/results.rb', line 8

def time
  @time
end

#total_costObject

Returns the value of attribute total_cost.



8
9
10
# File 'lib/nose/search/results.rb', line 8

def total_cost
  @total_cost
end

#total_sizeObject

Returns the value of attribute total_size.



8
9
10
# File 'lib/nose/search/results.rb', line 8

def total_size
  @total_size
end

#update_plansObject

Returns the value of attribute update_plans.



8
9
10
# File 'lib/nose/search/results.rb', line 8

def update_plans
  @update_plans
end

#workloadObject

Returns the value of attribute workload.



8
9
10
# File 'lib/nose/search/results.rb', line 8

def workload
  @workload
end

Instance Method Details

#modelModel

Provide access to the underlying model in the workload

Returns:



29
30
31
# File 'lib/nose/search/results.rb', line 29

def model
  @workload.nil? ? @model : @workload.model
end

#model=(model) ⇒ void

This method returns an undefined value.

Assign the model to the workload if it exists, otherwise store it



35
36
37
38
39
40
41
# File 'lib/nose/search/results.rb', line 35

def model=(model)
  if @workload.nil?
    @model = model
  else
    @workload.instance_variable_set :@model, model
  end
end

#plans_from_trees(trees) ⇒ void

This method returns an undefined value.

Set the query plans which should be used based on the entire tree



95
96
97
98
99
100
101
102
103
# File 'lib/nose/search/results.rb', line 95

def plans_from_trees(trees)
  @plans = trees.map do |tree|
    # Exclude support queries since they will be in update plans
    query = tree.query
    next if query.is_a?(SupportQuery)

    select_plan tree
  end.compact
end

#recalculate_cost(new_cost_model = nil) ⇒ void

This method returns an undefined value.

After setting the cost model, recalculate the cost



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/nose/search/results.rb', line 52

def recalculate_cost(new_cost_model = nil)
  new_cost_model = @cost_model if new_cost_model.nil?

  (@plans || []).each do |plan|
    plan.each { |s| s.calculate_cost new_cost_model }
  end
  (@update_plans || []).each do |plan|
    plan.update_steps.each { |s| s.calculate_cost new_cost_model }
    plan.query_plans.each do |query_plan|
      query_plan.each { |s| s.calculate_cost new_cost_model }
    end
  end

  # Recalculate the total
  query_cost = (@plans || []).sum_by do |plan|
    plan.cost * @workload.statement_weights[plan.query]
  end
  update_cost = (@update_plans || []).sum_by do |plan|
    plan.cost * @workload.statement_weights[plan.statement]
  end
  @total_cost = query_cost + update_cost
end

#select_plan(tree) ⇒ Plans::QueryPlan

Select the single query plan from a tree of plans



108
109
110
111
112
113
114
115
116
117
# File 'lib/nose/search/results.rb', line 108

def select_plan(tree)
  query = tree.query
  plan = tree.find do |tree_plan|
    tree_plan.indexes.to_set == @query_indexes[query]
  end
  plan.instance_variable_set :@workload, @workload

  fail InvalidResultsException if plan.nil?
  plan
end

#validatevoid

This method returns an undefined value.

Validate that the results of the search are consistent



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/nose/search/results.rb', line 77

def validate
  validate_indexes
  validate_query_indexes @plans
  validate_update_indexes

  planned_queries = plans.map(&:query).to_set
  fail InvalidResultsException unless \
    (@workload.queries.to_set - planned_queries).empty?
  validate_query_plans @plans

  validate_update_plans
  validate_objective

  freeze
end