Class: CompTree::Driver
- Inherits:
-
Object
- Object
- CompTree::Driver
- Defined in:
- lib/comp_tree/driver.rb
Overview
Driver is the main interface to the computation tree. It is responsible for defining nodes and running computations.
Instance Attribute Summary collapse
-
#nodes ⇒ Object
readonly
Name-to-node hash.
Instance Method Summary collapse
-
#check_circular(name) ⇒ Object
name – unique node identifier (for example a symbol).
-
#compute(name, max_threads) ⇒ Object
name – unique node identifier (for example a symbol).
-
#define(name, *child_names, &block) ⇒ Object
name – unique node identifier (for example a symbol).
-
#initialize(opts = {}) ⇒ Driver
constructor
See CompTree.build.
-
#reset(name) ⇒ Object
name – unique node identifier (for example a symbol).
Constructor Details
Instance Attribute Details
#nodes ⇒ Object (readonly)
Name-to-node hash.
19 20 21 |
# File 'lib/comp_tree/driver.rb', line 19 def nodes @nodes end |
Instance Method Details
#check_circular(name) ⇒ Object
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.
79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/comp_tree/driver.rb', line 79 def check_circular(name) helper = Proc.new { |root, chain| if chain.include? root return chain + [root] end @nodes[root].children.each { |child| helper.call(child.name, chain + [root]) } } helper.call(name, []) nil end |
#compute(name, max_threads) ⇒ Object
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.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/comp_tree/driver.rb', line 106 def compute(name, max_threads) begin max_threads = max_threads.to_int rescue NoMethodError raise TypeError, "can't convert #{max_threads.class} into Integer" end if max_threads < 0 raise RangeError, "max threads must be nonnegative" end root = @nodes[name] or raise NoNodeError.new(name) if root.computed root.result elsif max_threads == 1 root.compute_now else Algorithm.compute_parallel(root, max_threads == 0 ? nil : max_threads) end end |
#define(name, *child_names, &block) ⇒ Object
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
}
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/comp_tree/driver.rb', line 39 def define(name, *child_names, &block) # # retrieve or create node # node = @nodes[name] ||= @node_class.new(name) raise RedefinitionError.new(node.name) if node.function node.function = block # # retrieve or create children # children = child_names.map { |child_name| @nodes[child_name] ||= @node_class.new(child_name) } # # link # node.children = children children.each { |child| child.parents << node } node end |
#reset(name) ⇒ Object
name – unique node identifier (for example a symbol).
Mark this node and all its children as uncomputed.
68 69 70 |
# File 'lib/comp_tree/driver.rb', line 68 def reset(name) @nodes[name].reset end |