Driver is the main interface to the computation tree. It is responsible for defining nodes and running computations.
Attributes
nodes | [R] |
Name-to-node hash. |
Public Instance methods
name — unique node identifier (for example a symbol).
child_names — unique node identifiers of children.
Define a computation node.
During a computation, the results of the child nodes are passed to the block. The block returns the result of this node’s computation.
In the following example, a computation node named :area is defined which depends on the nodes named :width and :height.
driver.define(:area, :width, :height) { |w, h| w*h }
# File lib/comp_tree/driver.rb, line 39 39: def define(name, *child_names, &block) 40: # 41: # retrieve or create node 42: # 43: node = @nodes[name] ||= @node_class.new(name) 44: raise RedefinitionError.new(node.name) if node.function 45: node.function = block 46: 47: # 48: # retrieve or create children 49: # 50: children = child_names.map { |child_name| 51: @nodes[child_name] ||= @node_class.new(child_name) 52: } 53: 54: # 55: # link 56: # 57: node.children = children 58: children.each { |child| child.parents << node } 59: 60: node 61: end
name — unique node identifier (for example a symbol).
Mark this node and all its children as uncomputed.
# File lib/comp_tree/driver.rb, line 68 68: def reset(name) 69: @nodes[name].reset 70: end
name — unique node identifier (for example a symbol).
Check for a cyclic graph below the given node. If found, returns the names of the nodes (in order) which form a loop. Otherwise returns nil.
# File lib/comp_tree/driver.rb, line 79 79: def check_circular(name) 80: helper = Proc.new { |root, chain| 81: if chain.include? root 82: return chain + [root] 83: end 84: @nodes[root].children.each { |child| 85: helper.call(child.name, chain + [root]) 86: } 87: } 88: helper.call(name, []) 89: nil 90: end
name — unique node identifier (for example a symbol).
max_threads — maximum number of threads, or 0 to indicate no limit.
Compute the tree below name and return the result.
If a node’s computation raises an exception, the exception will be transferred to the caller of compute(). The tree will be left in a dirty state so that individual nodes may be examined. It is your responsibility to call reset() before attempting the computation again, otherwise the result will be undefined.
# File lib/comp_tree/driver.rb, line 106 106: def compute(name, max_threads) 107: begin 108: max_threads = max_threads.to_int 109: rescue NoMethodError 110: raise TypeError, "can't convert #{max_threads.class} into Integer" 111: end 112: if max_threads < 0 113: raise RangeError, "max threads must be nonnegative" 114: end 115: 116: root = @nodes[name] or raise NoNodeError.new(name) 117: if root.computed 118: root.result 119: elsif max_threads == 1 120: root.compute_now 121: else 122: Algorithm.compute_parallel(root, max_threads == 0 ? nil : max_threads) 123: end 124: end