Class: Tap::Support::Schema

Inherits:
Object show all
Includes:
Utils
Defined in:
lib/tap/support/schema.rb

Defined Under Namespace

Modules: Utils

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Utils

format_fork, format_instance, format_merge, format_options, format_round, format_sequence, format_sync_merge, shell_quote

Constructor Details

#initialize(nodes = []) ⇒ Schema

Returns a new instance of Schema.



125
126
127
128
# File 'lib/tap/support/schema.rb', line 125

def initialize(nodes=[])
  @nodes = nodes
  @current_index = 1
end

Instance Attribute Details

#nodesObject (readonly)

An array of the nodes registered in self.



123
124
125
# File 'lib/tap/support/schema.rb', line 123

def nodes
  @nodes
end

Class Method Details

.load(argv) ⇒ Object



110
111
112
113
114
# File 'lib/tap/support/schema.rb', line 110

def load(argv)
  parser = Parser.new
  parser.load(argv)
  parser.schema
end

.load_file(path) ⇒ Object



116
117
118
119
# File 'lib/tap/support/schema.rb', line 116

def load_file(path)
  argv = YAML.load_file(path)
  load(argv)
end

.parse(argv = ARGV) ⇒ Object



106
107
108
# File 'lib/tap/support/schema.rb', line 106

def parse(argv=ARGV)
  Support::Parser.new(argv).schema
end

Instance Method Details

#[](index) ⇒ Object

Retrieves the node at index, or instantiates a new Node if one does not already exists.



132
133
134
# File 'lib/tap/support/schema.rb', line 132

def [](index)
  nodes[index] ||= Node.new
end

#argvsObject

Returns an array of the argvs for each nodes.



169
170
171
172
173
# File 'lib/tap/support/schema.rb', line 169

def argvs
  nodes.collect do |node|
    node == nil ? nil : node.argv
  end
end

#build(app) ⇒ Object



237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/tap/support/schema.rb', line 237

def build(app)
  tasks = {}
  
  # instantiate the nodes
  nodes.each do |node|
    tasks[node] = yield(node.argv) if node
  end
  
  # instantiate and reconfigure globals
  instances = []
  globals.each do |node|
    task, args = tasks.delete(node)
    instance = task.class.instance
    
    if instances.include?(instance)
      raise "global specified multple times: #{instance}"
    end
    
    instance.reconfigure(task.config.to_hash)
    instance.enq(*args)
    instances << instance
  end

  # build the workflow
  joins.each_pair do |join, (source_node, target_nodes)|
    raise "unassigned join: #{join}" if source_node == nil || target_nodes.empty?

    targets = target_nodes.collect do |target_node|
      tasks[target_node][0]
    end
    source = tasks[source_node][0]
    
    join.join(source, targets)
  end

  # build queues
  queues = rounds.compact.collect do |round|
    round.each do |node|
      task, args = tasks.delete(node)
      task.enq(*args)
    end

    app.queue.clear
  end
  
  # notify any args that will be overlooked
  tasks.each_pair do |node, (task, args)|
    next if args.empty?
    warn "warning: ignoring args for node (#{nodes.index(node)}) #{task} [#{args.join(' ')}]"
  end

  queues
end

#compactObject

Removes all nil nodes, and nodes with empty argvs. Additionally reassigns rounds by shifting later rounds up to fill any nils in the rounds array.

Returns self.



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/tap/support/schema.rb', line 152

def compact
  # remove nil and empty nodes
  nodes.delete_if do |node|
    node == nil || node.argv.empty?
  end
  
  # reassign rounds
  index = 0
  rounds.compact.each do |round|
    round.each {|node| node.round = index }
    index += 1
  end
  
  self
end

#dumpObject

Creates an array dump of the contents of self.



292
293
294
295
296
# File 'lib/tap/support/schema.rb', line 292

def dump
  segments = argvs
  each_schema_str {|str| segments << str }
  segments
end

#globals(as_indicies = false) ⇒ Object

Returns a collection of global nodes (nodes with no input or output set).



193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/tap/support/schema.rb', line 193

def globals(as_indicies=false)
  globals = []
  nodes.each do |node|
    globals << node if node && node.global?
  end
  
  globals.collect! do |node| 
    nodes.index(node)
  end if as_indicies
  
  globals
end

#joins(as_indicies = false) ⇒ Object

Returns a hash of [join, [source_node, target_nodes]] pairs across all nodes.



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/tap/support/schema.rb', line 208

def joins(as_indicies=false)
  joins = {}
  nodes.each do |node|
    next unless node
    
    case node.input
    when Join, ReverseJoin
      (joins[node.input] ||= [nil,[]])[1] << node
    end
    
    case node.output
    when Join, ReverseJoin
      (joins[node.output] ||= [nil,[]])[0] = node
    end
  end
  
  if as_indicies
    summary = []
    joins.each_pair do |join, (source_node, target_nodes)|
      target_indicies = target_nodes.collect {|node| nodes.index(node) }
      summary << [join.name, nodes.index(source_node), target_indicies, join.options]
    end
    
    summary.sort_by {|entry| entry[1] || -1 }
  else
    joins
  end
end

#rounds(as_indicies = false) ⇒ Object

Returns a collection of nodes sorted

into arrays by node.round.



177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/tap/support/schema.rb', line 177

def rounds(as_indicies=false)
  rounds = []
  nodes.each do |node|
    (rounds[node.round] ||= []) << node if node && node.round
  end
  
  rounds.each do |round|
    next unless round
    round.collect! {|node| nodes.index(node) }
  end if as_indicies

  rounds
end

#set(join_class, source_indicies, target_indicies, options = {}) ⇒ Object

Sets a join between the source and targets.

Returns the new join.



138
139
140
141
142
143
144
145
# File 'lib/tap/support/schema.rb', line 138

def set(join_class, source_indicies, target_indicies, options={})
  join = join_class.new(options)

  [*source_indicies].each {|source_index| self[source_index].output = join }
  [*target_indicies].each {|target_index| self[target_index].input = join  }

  join
end

#to_sObject

Constructs a command-line string for the schema, ex: ‘– a – b –0:1’.



300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'lib/tap/support/schema.rb', line 300

def to_s
  segments = []
  nodes.each do |node|
    segments << "--"
    
    node.argv.each do |arg| 
      segments << shell_quote(arg)
    end unless node == nil
  end
  
  each_schema_str {|str| segments << "--#{str}" }
  segments.join(' ')
end