Class: NoSE::Workload

Inherits:
Object show all
Includes:
Loader
Defined in:
lib/nose/workload.rb

Overview

A representation of a query workload over a given set of entities

Constant Summary collapse

LOAD_PATH =

The subdirectory workloads are loaded from

'workloads'

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Loader

included

Constructor Details

#initialize(model = nil, &block) ⇒ Workload

Returns a new instance of Workload.



18
19
20
21
22
23
24
25
# File 'lib/nose/workload.rb', line 18

def initialize(model = nil, &block)
  @statement_weights = { default: {} }
  @model = model || Model.new
  @mix = :default

  # Apply the DSL
  WorkloadDSL.new(self).instance_eval(&block) if block_given?
end

Instance Attribute Details

#mixObject

Returns the value of attribute mix.



16
17
18
# File 'lib/nose/workload.rb', line 16

def mix
  @mix
end

#modelObject (readonly)

Returns the value of attribute model.



15
16
17
# File 'lib/nose/workload.rb', line 15

def model
  @model
end

Instance Method Details

#<<(other) ⇒ self

Add a new Entity or Statement to the workload

Returns:

  • (self)

    the current workload to allow chaining



37
38
39
40
41
42
43
44
45
46
47
# File 'lib/nose/workload.rb', line 37

def <<(other)
  if other.is_a? Entity
    @model.add_entity other.freeze
  elsif other.is_a? Statement
    add_statement other.freeze
  else
    fail TypeError, 'can only add queries and entities to a workload'
  end

  self
end

#==(other) ⇒ Boolean Also known as: eql?

Compare models and statements

Returns:

  • (Boolean)


29
30
31
32
# File 'lib/nose/workload.rb', line 29

def ==(other)
  other.is_a?(Workload) && @model == other.model &&
    statement_weights == other.statement_weights
end

#add_statement(statement, mixes = {}, group: nil, label: nil) ⇒ void

This method returns an undefined value.

Add a new Statement to the workload or parse a string



51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/nose/workload.rb', line 51

def add_statement(statement, mixes = {}, group: nil, label: nil)
  statement = Statement.parse(statement, @model,
                              group: group, label: label) \
    if statement.is_a? String
  statement.freeze

  mixes = { default: mixes } if mixes.is_a? Numeric
  mixes = { default: 1.0 } if mixes.empty?
  mixes.each do |mix, weight|
    @statement_weights[mix] = {} unless @statement_weights.key? mix
    @statement_weights[mix][statement] = weight
  end
end

#fields_exist?Boolean

Check if all the fields used by queries in the workload exist

Returns:

  • (Boolean)


117
118
119
120
121
122
123
124
125
126
127
# File 'lib/nose/workload.rb', line 117

def fields_exist?
  @statement_weights[@mix].each_key do |query|
    # Projected fields and fields in the where clause exist
    fields = query.where.map(&:field) + query.fields
    fields.each do |field|
      return false unless @model.find_field field.value
    end
  end

  true
end

#find_with_tag(tag) ⇒ Statement

Find a statement in the workload with the provided tag

Returns:



95
96
97
98
99
# File 'lib/nose/workload.rb', line 95

def find_with_tag(tag)
  statements.find do |s|
    s.text.end_with? "-- #{tag}"
  end
end

#queriesArray<Statement>

Strip the weights from the query dictionary and return a list of queries

Returns:



67
68
69
70
71
# File 'lib/nose/workload.rb', line 67

def queries
  @statement_weights[@mix].keys.select do |statement|
    statement.is_a? Query
  end
end

#remove_updatesvoid

This method returns an undefined value.

Remove any updates from the workload



103
104
105
# File 'lib/nose/workload.rb', line 103

def remove_updates
  @statement_weights[@mix].select! { |stmt, _| stmt.is_a? Query }
end

#source_codeString

Produce the source code used to define this workload

Returns:

  • (String)


131
132
133
134
135
136
137
138
139
# File 'lib/nose/workload.rb', line 131

def source_code
  return @source_code unless @source_code.nil?

  ns = OpenStruct.new(workload: self)
  tmpl = File.read File.join(File.dirname(__FILE__),
                             '../../templates/workload.erb')
  tmpl = ERB.new(tmpl, nil, '>')
  @source_code = tmpl.result(ns.instance_eval { binding })
end

#statement_weightsHash

Retrieve the weights for the current mix

Returns:

  • (Hash)


81
82
83
# File 'lib/nose/workload.rb', line 81

def statement_weights
  @statement_weights[@mix]
end

#statementsArray<Statement>

Strip the weights and return a list of statements

Returns:



75
76
77
# File 'lib/nose/workload.rb', line 75

def statements
  (@statement_weights[@mix] || {}).keys
end

#support_queries(indexes) ⇒ Object

Get all the support queries for updates in the workload @return



109
110
111
112
113
# File 'lib/nose/workload.rb', line 109

def support_queries(indexes)
  updates.map do |update|
    indexes.map { |index| update.support_queries(index) }
  end.flatten(2)
end

#updatesArray<Statement>

Strip the weights from the query dictionary and return a list of updates

Returns:



87
88
89
90
91
# File 'lib/nose/workload.rb', line 87

def updates
  @statement_weights[@mix].keys.reject do |statement|
    statement.is_a? Query
  end
end