drake 0.8.2.1.0.3 → 0.8.2.1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES.drake +5 -0
- data/README +5 -4
- data/Rakefile.drake +3 -34
- data/lib/rake.rb +6 -4
- data/lib/rake/parallel.rb +4 -7
- metadata +2 -12
- data/lib/rake/comp_tree/algorithm.rb +0 -234
- data/lib/rake/comp_tree/bucket_ipc.rb +0 -175
- data/lib/rake/comp_tree/driver.rb +0 -291
- data/lib/rake/comp_tree/error.rb +0 -51
- data/lib/rake/comp_tree/node.rb +0 -189
- data/lib/rake/comp_tree/quix/builtin/kernel/tap.rb +0 -57
- data/lib/rake/comp_tree/quix/diagnostic.rb +0 -92
- data/lib/rake/comp_tree/quix/kernel.rb +0 -109
- data/lib/rake/comp_tree/retriable_fork.rb +0 -66
- data/lib/rake/comp_tree/task_node.rb +0 -46
| @@ -1,291 +0,0 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 3 | 
            -
             | 
| 4 | 
            -
            ######################################################
         | 
| 5 | 
            -
            # 
         | 
| 6 | 
            -
            # **** DO NOT EDIT ****
         | 
| 7 | 
            -
            # 
         | 
| 8 | 
            -
            # **** THIS IS A GENERATED FILE *****
         | 
| 9 | 
            -
            # 
         | 
| 10 | 
            -
            ######################################################
         | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
            require 'rake/comp_tree/bucket_ipc'
         | 
| 15 | 
            -
            require 'rake/comp_tree/quix/diagnostic'
         | 
| 16 | 
            -
            require 'rake/comp_tree/quix/kernel'
         | 
| 17 | 
            -
            require 'rake/comp_tree/algorithm'
         | 
| 18 | 
            -
            require 'rake/comp_tree/node'
         | 
| 19 | 
            -
            require 'rake/comp_tree/task_node'
         | 
| 20 | 
            -
            require 'rake/comp_tree/error'
         | 
| 21 | 
            -
             | 
| 22 | 
            -
            require 'thread'
         | 
| 23 | 
            -
             | 
| 24 | 
            -
            module Rake::CompTree
         | 
| 25 | 
            -
              #
         | 
| 26 | 
            -
              # Driver is the main interface to the computation tree.  It is
         | 
| 27 | 
            -
              # responsible for defining nodes and running computations.
         | 
| 28 | 
            -
              #
         | 
| 29 | 
            -
              class Driver
         | 
| 30 | 
            -
                DEFAULTS = {
         | 
| 31 | 
            -
                  :threads => 1,
         | 
| 32 | 
            -
                  :fork => false,
         | 
| 33 | 
            -
                  :timeout => 5.0,
         | 
| 34 | 
            -
                  :wait_interval => 0.02,
         | 
| 35 | 
            -
                }
         | 
| 36 | 
            -
             | 
| 37 | 
            -
                include Quix::Diagnostic #:nodoc:
         | 
| 38 | 
            -
                include Quix::Kernel #:nodoc:
         | 
| 39 | 
            -
                
         | 
| 40 | 
            -
                #
         | 
| 41 | 
            -
                # Begin a new computation tree.
         | 
| 42 | 
            -
                #
         | 
| 43 | 
            -
                # Options hash:
         | 
| 44 | 
            -
                #
         | 
| 45 | 
            -
                # <tt>:node_class</tt> -- (Class) Rake::CompTree::Node subclass from
         | 
| 46 | 
            -
                # which nodes are created.
         | 
| 47 | 
            -
                #
         | 
| 48 | 
            -
                # <tt>:discard_result</tt> -- (boolean) If you are <em>not</em>
         | 
| 49 | 
            -
                # interested in the final answer, but only in the actions which
         | 
| 50 | 
            -
                # complete the computation, then set this to +true+.  This is
         | 
| 51 | 
            -
                # equivalent to saying <tt>:node_class => Rake::CompTree::TaskNode</tt>.
         | 
| 52 | 
            -
                # (If you are forking processes, it is good to know that IPC is
         | 
| 53 | 
            -
                # not needed to communicate the result.)
         | 
| 54 | 
            -
                #
         | 
| 55 | 
            -
                def initialize(opts = nil)
         | 
| 56 | 
            -
                  if opts and opts[:node_class] and opts[:discard_result]
         | 
| 57 | 
            -
                    raise(
         | 
| 58 | 
            -
                      Error::ArgumentError,
         | 
| 59 | 
            -
                      "#{self.class.name}.new: :discard_result and :node_class " +
         | 
| 60 | 
            -
                      "are mutually exclusive")
         | 
| 61 | 
            -
                  end
         | 
| 62 | 
            -
             | 
| 63 | 
            -
                  @node_class =
         | 
| 64 | 
            -
                    if opts and opts[:node_class]
         | 
| 65 | 
            -
                      opts[:node_class]
         | 
| 66 | 
            -
                    elsif opts and opts[:discard_result]
         | 
| 67 | 
            -
                      TaskNode
         | 
| 68 | 
            -
                    else
         | 
| 69 | 
            -
                      Node
         | 
| 70 | 
            -
                    end
         | 
| 71 | 
            -
             | 
| 72 | 
            -
                  @nodes = Hash.new
         | 
| 73 | 
            -
             | 
| 74 | 
            -
                  if block_given?
         | 
| 75 | 
            -
                    yield self
         | 
| 76 | 
            -
                  end
         | 
| 77 | 
            -
                end
         | 
| 78 | 
            -
             | 
| 79 | 
            -
                #
         | 
| 80 | 
            -
                # Name-to-node hash.
         | 
| 81 | 
            -
                #
         | 
| 82 | 
            -
                attr_reader :nodes
         | 
| 83 | 
            -
             | 
| 84 | 
            -
                #
         | 
| 85 | 
            -
                # Define a computation node.
         | 
| 86 | 
            -
                #
         | 
| 87 | 
            -
                # There are three distinct forms of a node definition.  In each of
         | 
| 88 | 
            -
                # the following examples, a computation node named +area+ is
         | 
| 89 | 
            -
                # defined which depends on the nodes +height+, +width+, +offset+.
         | 
| 90 | 
            -
                #
         | 
| 91 | 
            -
                # The method_missing form:
         | 
| 92 | 
            -
                #  driver.define_area(:width, :height, :offset) { |width, height, offset|
         | 
| 93 | 
            -
                #    width*height - offset
         | 
| 94 | 
            -
                #  }
         | 
| 95 | 
            -
                #
         | 
| 96 | 
            -
                # The eval form:
         | 
| 97 | 
            -
                #  driver.define_area :width, :height, :offset, %{
         | 
| 98 | 
            -
                #    width*height - offset
         | 
| 99 | 
            -
                #  }
         | 
| 100 | 
            -
                # (Note the '%' before the brace.)
         | 
| 101 | 
            -
                #
         | 
| 102 | 
            -
                # The raw form:
         | 
| 103 | 
            -
                #  driver.define(:area, :width, :height, :offset) { |width, height, offset|
         | 
| 104 | 
            -
                #    width*height - offset
         | 
| 105 | 
            -
                #  }
         | 
| 106 | 
            -
                #
         | 
| 107 | 
            -
                def define(*args, &block)
         | 
| 108 | 
            -
                  parent_name = args.first
         | 
| 109 | 
            -
                  children_names = args[1..-1]
         | 
| 110 | 
            -
                  
         | 
| 111 | 
            -
                  unless parent_name
         | 
| 112 | 
            -
                    raise Error::ArgumentError, "No name given for node"
         | 
| 113 | 
            -
                  end
         | 
| 114 | 
            -
                  
         | 
| 115 | 
            -
                  #
         | 
| 116 | 
            -
                  # retrieve or create parent and children
         | 
| 117 | 
            -
                  #
         | 
| 118 | 
            -
                  parent =
         | 
| 119 | 
            -
                    if t = @nodes[parent_name]
         | 
| 120 | 
            -
                      t
         | 
| 121 | 
            -
                    else 
         | 
| 122 | 
            -
                      @nodes[parent_name] = @node_class.new(parent_name)
         | 
| 123 | 
            -
                    end
         | 
| 124 | 
            -
             | 
| 125 | 
            -
                  if parent.function
         | 
| 126 | 
            -
                    raise Error::RedefinitionError, "Node #{parent.name} already defined."
         | 
| 127 | 
            -
                  end
         | 
| 128 | 
            -
                  parent.function = block
         | 
| 129 | 
            -
                  
         | 
| 130 | 
            -
                  children = children_names.map { |child_name|
         | 
| 131 | 
            -
                    if t = @nodes[child_name]
         | 
| 132 | 
            -
                      t
         | 
| 133 | 
            -
                    else
         | 
| 134 | 
            -
                      @nodes[child_name] = @node_class.new(child_name)
         | 
| 135 | 
            -
                    end
         | 
| 136 | 
            -
                  }
         | 
| 137 | 
            -
             | 
| 138 | 
            -
                  #
         | 
| 139 | 
            -
                  # link
         | 
| 140 | 
            -
                  #
         | 
| 141 | 
            -
                  parent.children = children
         | 
| 142 | 
            -
                  children.each { |child|
         | 
| 143 | 
            -
                    child.parents << parent
         | 
| 144 | 
            -
                  }
         | 
| 145 | 
            -
                end
         | 
| 146 | 
            -
             | 
| 147 | 
            -
                #
         | 
| 148 | 
            -
                # parsing/evaling helper
         | 
| 149 | 
            -
                #
         | 
| 150 | 
            -
                def evaling_define(*args) #:nodoc:
         | 
| 151 | 
            -
                  function_name = args[0]
         | 
| 152 | 
            -
                  function_arg_names = args[1..-2]
         | 
| 153 | 
            -
                  function_string = args.last.to_str
         | 
| 154 | 
            -
                  
         | 
| 155 | 
            -
                  comma_separated = function_arg_names.map { |name|
         | 
| 156 | 
            -
                    name.to_s
         | 
| 157 | 
            -
                  }.join(",")
         | 
| 158 | 
            -
             | 
| 159 | 
            -
                  eval_me = %{ 
         | 
| 160 | 
            -
                    lambda { |#{comma_separated}|
         | 
| 161 | 
            -
                      #{function_string}
         | 
| 162 | 
            -
                    }
         | 
| 163 | 
            -
                  }
         | 
| 164 | 
            -
             | 
| 165 | 
            -
                  function = eval(eval_me, TOPLEVEL_BINDING)
         | 
| 166 | 
            -
             | 
| 167 | 
            -
                  define(function_name, *function_arg_names, &function)
         | 
| 168 | 
            -
                end
         | 
| 169 | 
            -
             | 
| 170 | 
            -
                def method_missing(symbol, *args, &block) #:nodoc:
         | 
| 171 | 
            -
                  if match = symbol.to_s.match(%r!\Adefine_(\w+)\Z!)
         | 
| 172 | 
            -
                    method_name = match.captures.first.to_sym
         | 
| 173 | 
            -
                    if block
         | 
| 174 | 
            -
                      define(method_name, *args, &block)
         | 
| 175 | 
            -
                    else
         | 
| 176 | 
            -
                      evaling_define(method_name, *args)
         | 
| 177 | 
            -
                    end
         | 
| 178 | 
            -
                  else
         | 
| 179 | 
            -
                    super(symbol, *args, &block)
         | 
| 180 | 
            -
                  end
         | 
| 181 | 
            -
                end
         | 
| 182 | 
            -
             | 
| 183 | 
            -
                #
         | 
| 184 | 
            -
                # Mark this node and all its children as uncomputed.
         | 
| 185 | 
            -
                #
         | 
| 186 | 
            -
                # Arguments:
         | 
| 187 | 
            -
                #
         | 
| 188 | 
            -
                # +name+ -- (Symbol) node name.
         | 
| 189 | 
            -
                #
         | 
| 190 | 
            -
                def reset(name)
         | 
| 191 | 
            -
                  @nodes[name].reset
         | 
| 192 | 
            -
                end
         | 
| 193 | 
            -
             | 
| 194 | 
            -
                #
         | 
| 195 | 
            -
                # Check for a cyclic graph below the given node.  Raises
         | 
| 196 | 
            -
                # Rake::CompTree::Error::CircularError if found.
         | 
| 197 | 
            -
                #
         | 
| 198 | 
            -
                # Arguments:
         | 
| 199 | 
            -
                #
         | 
| 200 | 
            -
                # +name+ -- (Symbol) node name.
         | 
| 201 | 
            -
                #
         | 
| 202 | 
            -
                def check_circular(name)
         | 
| 203 | 
            -
                  helper = lambda { |root, chain|
         | 
| 204 | 
            -
                    if chain.include? root
         | 
| 205 | 
            -
                      raise Error::CircularError,
         | 
| 206 | 
            -
                        "Circular dependency detected: #{root} => #{chain.last} => #{root}"
         | 
| 207 | 
            -
                    end
         | 
| 208 | 
            -
                    @nodes[root].children.each { |child|
         | 
| 209 | 
            -
                      helper.call(child.name, chain + [root])
         | 
| 210 | 
            -
                    }
         | 
| 211 | 
            -
                  }
         | 
| 212 | 
            -
                  helper.call(name, [])
         | 
| 213 | 
            -
                end
         | 
| 214 | 
            -
             | 
| 215 | 
            -
                #
         | 
| 216 | 
            -
                # Compute this node.
         | 
| 217 | 
            -
                #
         | 
| 218 | 
            -
                # Arguments:
         | 
| 219 | 
            -
                #
         | 
| 220 | 
            -
                # +name+ -- (Symbol) node name.
         | 
| 221 | 
            -
                #
         | 
| 222 | 
            -
                # Options hash:
         | 
| 223 | 
            -
                #
         | 
| 224 | 
            -
                # <tt>:threads</tt> -- (Integer) Number of parallel threads.
         | 
| 225 | 
            -
                #
         | 
| 226 | 
            -
                # <tt>:fork</tt> -- (boolean) Whether to fork each computation
         | 
| 227 | 
            -
                # node into its own process.
         | 
| 228 | 
            -
                #
         | 
| 229 | 
            -
                # Defaults options are taken from Driver::DEFAULTS.
         | 
| 230 | 
            -
                #
         | 
| 231 | 
            -
                def compute(name, opts = nil)
         | 
| 232 | 
            -
                  #
         | 
| 233 | 
            -
                  # Undocumented options:
         | 
| 234 | 
            -
                  #
         | 
| 235 | 
            -
                  # <tt>:wait_interval</tt> -- (seconds) (Obscure) How long to
         | 
| 236 | 
            -
                  # wait after an IPC failure.
         | 
| 237 | 
            -
                  #
         | 
| 238 | 
            -
                  # <tt>:timeout</tt> -- (seconds) (Obscure) Give up after this
         | 
| 239 | 
            -
                  # period of persistent IPC failures.
         | 
| 240 | 
            -
                  #
         | 
| 241 | 
            -
             | 
| 242 | 
            -
                  abort_on_exception {
         | 
| 243 | 
            -
                    compute_private(name, opts || Hash.new)
         | 
| 244 | 
            -
                  }
         | 
| 245 | 
            -
                end
         | 
| 246 | 
            -
             | 
| 247 | 
            -
                private
         | 
| 248 | 
            -
                
         | 
| 249 | 
            -
                def compute_private(name, opts_in)
         | 
| 250 | 
            -
                  opts = DEFAULTS.merge(opts_in)
         | 
| 251 | 
            -
                  root = @nodes[name]
         | 
| 252 | 
            -
             | 
| 253 | 
            -
                  if opts[:threads] < 1
         | 
| 254 | 
            -
                    raise Error::ArgumentError, "threads is #{opts[:threads]}"
         | 
| 255 | 
            -
                  end
         | 
| 256 | 
            -
             | 
| 257 | 
            -
                  if opts[:threads] == 1
         | 
| 258 | 
            -
                    root.result = root.compute_now
         | 
| 259 | 
            -
                  elsif opts[:fork] and not @node_class.discard_result?
         | 
| 260 | 
            -
                    #
         | 
| 261 | 
            -
                    # Use buckets to send results across forks.
         | 
| 262 | 
            -
                    #
         | 
| 263 | 
            -
                    result = nil
         | 
| 264 | 
            -
                    BucketIPC::Driver.new(opts[:threads], opts) { |buckets|
         | 
| 265 | 
            -
                      result =
         | 
| 266 | 
            -
                        Algorithm.compute_multithreaded(
         | 
| 267 | 
            -
                          root, opts[:threads], opts[:fork], buckets)
         | 
| 268 | 
            -
                    }
         | 
| 269 | 
            -
                    result
         | 
| 270 | 
            -
                  else
         | 
| 271 | 
            -
                    #
         | 
| 272 | 
            -
                    # Multithreaded computation without fork.
         | 
| 273 | 
            -
                    #
         | 
| 274 | 
            -
                    Algorithm.compute_multithreaded(
         | 
| 275 | 
            -
                      root, opts[:threads], opts[:fork], nil)
         | 
| 276 | 
            -
                  end
         | 
| 277 | 
            -
                end
         | 
| 278 | 
            -
              end
         | 
| 279 | 
            -
            end
         | 
| 280 | 
            -
             | 
| 281 | 
            -
             | 
| 282 | 
            -
             | 
| 283 | 
            -
            ######################################################
         | 
| 284 | 
            -
            # 
         | 
| 285 | 
            -
            # **** DO NOT EDIT ****
         | 
| 286 | 
            -
            # 
         | 
| 287 | 
            -
            # **** THIS IS A GENERATED FILE *****
         | 
| 288 | 
            -
            # 
         | 
| 289 | 
            -
            ######################################################
         | 
| 290 | 
            -
             | 
| 291 | 
            -
             | 
    
        data/lib/rake/comp_tree/error.rb
    DELETED
    
    | @@ -1,51 +0,0 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 3 | 
            -
             | 
| 4 | 
            -
            ######################################################
         | 
| 5 | 
            -
            # 
         | 
| 6 | 
            -
            # **** DO NOT EDIT ****
         | 
| 7 | 
            -
            # 
         | 
| 8 | 
            -
            # **** THIS IS A GENERATED FILE *****
         | 
| 9 | 
            -
            # 
         | 
| 10 | 
            -
            ######################################################
         | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
            module Rake::CompTree
         | 
| 15 | 
            -
              module Error
         | 
| 16 | 
            -
                # Base class for Rake::CompTree errors.
         | 
| 17 | 
            -
                class Base < StandardError ; end
         | 
| 18 | 
            -
                
         | 
| 19 | 
            -
                # Internal error inside Rake::CompTree.  Please send a bug report.
         | 
| 20 | 
            -
                class AssertionFailed < Base ; end
         | 
| 21 | 
            -
                
         | 
| 22 | 
            -
                # Bad arguments were passed to a method.
         | 
| 23 | 
            -
                class ArgumentError < Base ; end
         | 
| 24 | 
            -
                
         | 
| 25 | 
            -
                #
         | 
| 26 | 
            -
                # Attempt to redefine a Node.
         | 
| 27 | 
            -
                #
         | 
| 28 | 
            -
                # If you wish to only replace the function, set
         | 
| 29 | 
            -
                #   driver.nodes[name].function = some_new_lambda
         | 
| 30 | 
            -
                #
         | 
| 31 | 
            -
                class RedefinitionError < Base ; end
         | 
| 32 | 
            -
                
         | 
| 33 | 
            -
                # A Cyclic graph was detected.
         | 
| 34 | 
            -
                class CircularError < Base ; end
         | 
| 35 | 
            -
             | 
| 36 | 
            -
                # No function was defined for this node.
         | 
| 37 | 
            -
                class NoFunctionError < Base ; end
         | 
| 38 | 
            -
              end
         | 
| 39 | 
            -
            end
         | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
            ######################################################
         | 
| 44 | 
            -
            # 
         | 
| 45 | 
            -
            # **** DO NOT EDIT ****
         | 
| 46 | 
            -
            # 
         | 
| 47 | 
            -
            # **** THIS IS A GENERATED FILE *****
         | 
| 48 | 
            -
            # 
         | 
| 49 | 
            -
            ######################################################
         | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
    
        data/lib/rake/comp_tree/node.rb
    DELETED
    
    | @@ -1,189 +0,0 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 3 | 
            -
             | 
| 4 | 
            -
            ######################################################
         | 
| 5 | 
            -
            # 
         | 
| 6 | 
            -
            # **** DO NOT EDIT ****
         | 
| 7 | 
            -
            # 
         | 
| 8 | 
            -
            # **** THIS IS A GENERATED FILE *****
         | 
| 9 | 
            -
            # 
         | 
| 10 | 
            -
            ######################################################
         | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
            require 'rake/comp_tree/quix/diagnostic'
         | 
| 15 | 
            -
            require 'thread'
         | 
| 16 | 
            -
             | 
| 17 | 
            -
            module Rake::CompTree
         | 
| 18 | 
            -
              #
         | 
| 19 | 
            -
              # Base class for nodes in the computation tree.
         | 
| 20 | 
            -
              # 
         | 
| 21 | 
            -
              class Node
         | 
| 22 | 
            -
                include Quix::Diagnostic #:nodoc:
         | 
| 23 | 
            -
             | 
| 24 | 
            -
                attr_reader :name                   #:nodoc:
         | 
| 25 | 
            -
             | 
| 26 | 
            -
                attr_accessor :parents              #:nodoc:
         | 
| 27 | 
            -
                attr_accessor :children             #:nodoc:
         | 
| 28 | 
            -
                attr_accessor :function             #:nodoc:
         | 
| 29 | 
            -
                attr_accessor :result               #:nodoc:
         | 
| 30 | 
            -
                attr_accessor :shared_lock          #:nodoc:
         | 
| 31 | 
            -
             | 
| 32 | 
            -
                #
         | 
| 33 | 
            -
                # Create a node
         | 
| 34 | 
            -
                #
         | 
| 35 | 
            -
                def initialize(name) #:nodoc:
         | 
| 36 | 
            -
                  @name = name
         | 
| 37 | 
            -
                  @mutex = Mutex.new
         | 
| 38 | 
            -
                  @children = []
         | 
| 39 | 
            -
                  @parents = []
         | 
| 40 | 
            -
                  reset_self
         | 
| 41 | 
            -
                end
         | 
| 42 | 
            -
             | 
| 43 | 
            -
                #
         | 
| 44 | 
            -
                # Reset the computation for this node.
         | 
| 45 | 
            -
                #
         | 
| 46 | 
            -
                def reset_self #:nodoc:
         | 
| 47 | 
            -
                  @shared_lock = 0
         | 
| 48 | 
            -
                  @children_results = nil
         | 
| 49 | 
            -
                  @result = nil
         | 
| 50 | 
            -
                end
         | 
| 51 | 
            -
             | 
| 52 | 
            -
                #
         | 
| 53 | 
            -
                # Reset the computation for this node and all children.
         | 
| 54 | 
            -
                #
         | 
| 55 | 
            -
                def reset #:nodoc:
         | 
| 56 | 
            -
                  each_downward { |node|
         | 
| 57 | 
            -
                    node.reset_self
         | 
| 58 | 
            -
                  }
         | 
| 59 | 
            -
                end
         | 
| 60 | 
            -
             | 
| 61 | 
            -
                def each_downward(&block) #:nodoc:
         | 
| 62 | 
            -
                  block.call(self)
         | 
| 63 | 
            -
                  @children.each { |child|
         | 
| 64 | 
            -
                    child.each_downward(&block)
         | 
| 65 | 
            -
                  }
         | 
| 66 | 
            -
                end
         | 
| 67 | 
            -
             | 
| 68 | 
            -
                def each_upward(&block) #:nodoc:
         | 
| 69 | 
            -
                  block.call(self)
         | 
| 70 | 
            -
                  @parents.each { |parent|
         | 
| 71 | 
            -
                    parent.each_upward(&block)
         | 
| 72 | 
            -
                  }
         | 
| 73 | 
            -
                end
         | 
| 74 | 
            -
             | 
| 75 | 
            -
                def each_child #:nodoc:
         | 
| 76 | 
            -
                  @children.each { |child|
         | 
| 77 | 
            -
                    yield(child)
         | 
| 78 | 
            -
                  }
         | 
| 79 | 
            -
                end
         | 
| 80 | 
            -
             | 
| 81 | 
            -
                #
         | 
| 82 | 
            -
                # Force computation of all children; intended for
         | 
| 83 | 
            -
                # single-threaded mode.
         | 
| 84 | 
            -
                #
         | 
| 85 | 
            -
                def compute_now #:nodoc:
         | 
| 86 | 
            -
                  unless @children_results
         | 
| 87 | 
            -
                    @children_results = @children.map { |child|
         | 
| 88 | 
            -
                      child.compute_now
         | 
| 89 | 
            -
                    }
         | 
| 90 | 
            -
                  end
         | 
| 91 | 
            -
                  compute
         | 
| 92 | 
            -
                end
         | 
| 93 | 
            -
                
         | 
| 94 | 
            -
                #
         | 
| 95 | 
            -
                # If all children have been computed, return their results;
         | 
| 96 | 
            -
                # otherwise return nil.
         | 
| 97 | 
            -
                #
         | 
| 98 | 
            -
                def children_results #:nodoc:
         | 
| 99 | 
            -
                  if @children_results
         | 
| 100 | 
            -
                    @children_results
         | 
| 101 | 
            -
                  else
         | 
| 102 | 
            -
                    results = @children.map { |child|
         | 
| 103 | 
            -
                      if child_result = child.result
         | 
| 104 | 
            -
                        child_result
         | 
| 105 | 
            -
                      else
         | 
| 106 | 
            -
                        return nil
         | 
| 107 | 
            -
                      end
         | 
| 108 | 
            -
                    }
         | 
| 109 | 
            -
                    @children_results = results
         | 
| 110 | 
            -
                  end
         | 
| 111 | 
            -
                end
         | 
| 112 | 
            -
             | 
| 113 | 
            -
                def trace_compute #:nodoc:
         | 
| 114 | 
            -
                  debug {
         | 
| 115 | 
            -
                    # --- own mutex
         | 
| 116 | 
            -
                    trace "Computing #{@name}"
         | 
| 117 | 
            -
                    raise Error::AssertionFailed if @result
         | 
| 118 | 
            -
                    raise Error::AssertionFailed unless @mutex.locked?
         | 
| 119 | 
            -
                    raise Error::AssertionFailed unless @children_results
         | 
| 120 | 
            -
                  }
         | 
| 121 | 
            -
                end
         | 
| 122 | 
            -
             | 
| 123 | 
            -
                #
         | 
| 124 | 
            -
                # Compute this node; children must be computed and lock must be
         | 
| 125 | 
            -
                # already acquired.
         | 
| 126 | 
            -
                #
         | 
| 127 | 
            -
                def compute #:nodoc:
         | 
| 128 | 
            -
                  unless defined?(@function) and @function
         | 
| 129 | 
            -
                    raise Error::NoFunctionError,
         | 
| 130 | 
            -
                      "No function was defined for node '#{@name.inspect}'"
         | 
| 131 | 
            -
                  end
         | 
| 132 | 
            -
                  @function.call(*@children_results)
         | 
| 133 | 
            -
                end
         | 
| 134 | 
            -
             | 
| 135 | 
            -
                def try_lock #:nodoc:
         | 
| 136 | 
            -
                  # --- shared tree mutex and own mutex
         | 
| 137 | 
            -
                  if @shared_lock == 0 and @mutex.try_lock
         | 
| 138 | 
            -
                    trace "Locking #{@name}"
         | 
| 139 | 
            -
                    each_upward { |node|
         | 
| 140 | 
            -
                      node.shared_lock += 1
         | 
| 141 | 
            -
                      trace "#{node.name} locked by #{@name}: level: #{node.shared_lock}"
         | 
| 142 | 
            -
                    }
         | 
| 143 | 
            -
                    true
         | 
| 144 | 
            -
                  else
         | 
| 145 | 
            -
                    false
         | 
| 146 | 
            -
                  end
         | 
| 147 | 
            -
                end
         | 
| 148 | 
            -
             | 
| 149 | 
            -
                def unlock #:nodoc:
         | 
| 150 | 
            -
                  # --- shared tree mutex and own mutex
         | 
| 151 | 
            -
                  debug {
         | 
| 152 | 
            -
                    raise Error::AssertionFailed unless @mutex.locked?
         | 
| 153 | 
            -
                    trace "Unlocking #{@name}"
         | 
| 154 | 
            -
                  }
         | 
| 155 | 
            -
                  each_upward { |node|
         | 
| 156 | 
            -
                    node.shared_lock -= 1
         | 
| 157 | 
            -
                    debug {
         | 
| 158 | 
            -
                      if node.shared_lock == 0
         | 
| 159 | 
            -
                        trace "#{node.name} unlocked by #{@name}"
         | 
| 160 | 
            -
                      end
         | 
| 161 | 
            -
                    }
         | 
| 162 | 
            -
                  }
         | 
| 163 | 
            -
                  @mutex.unlock
         | 
| 164 | 
            -
                end
         | 
| 165 | 
            -
             | 
| 166 | 
            -
                class << self
         | 
| 167 | 
            -
                  #
         | 
| 168 | 
            -
                  # Throw away the computation result?
         | 
| 169 | 
            -
                  #
         | 
| 170 | 
            -
                  # This Node base class always returns false.
         | 
| 171 | 
            -
                  #
         | 
| 172 | 
            -
                  def discard_result?
         | 
| 173 | 
            -
                    false
         | 
| 174 | 
            -
                  end
         | 
| 175 | 
            -
                end
         | 
| 176 | 
            -
              end
         | 
| 177 | 
            -
            end
         | 
| 178 | 
            -
             | 
| 179 | 
            -
             | 
| 180 | 
            -
             | 
| 181 | 
            -
            ######################################################
         | 
| 182 | 
            -
            # 
         | 
| 183 | 
            -
            # **** DO NOT EDIT ****
         | 
| 184 | 
            -
            # 
         | 
| 185 | 
            -
            # **** THIS IS A GENERATED FILE *****
         | 
| 186 | 
            -
            # 
         | 
| 187 | 
            -
            ######################################################
         | 
| 188 | 
            -
             | 
| 189 | 
            -
             |