class ComputedModel::DepGraph::Sorted

A preprocessed graph with topologically sorted order.

Generated by {ComputedModel::DepGraph#tsort}.

Attributes

nodes_in_order[R]

@return [Array<ComputedModel::DepGraph::Node>]

original[R]

@return [ComputedModel::DepGraph]

Public Class Methods

new(original, nodes_in_order) click to toggle source

@param original [ComputedModel::DepGraph] @param nodes_in_order [Array<ComputedModel::DepGraph::Node>]

# File lib/computed_model/dep_graph.rb, line 198
def initialize(original, nodes_in_order)
  @original = original
  @nodes_in_order = nodes_in_order
end

Public Instance Methods

plan(deps) click to toggle source

Computes the plan for the given requirements.

@param deps [Array] the list of required nodes. Each dependency can optionally include subfields hashes. @return [ComputedModel::Plan]

@example Plain dependencies

sorted.plan([:field1, :field2])

@example Dependencies with subfields

sorted.plan([:field1, field2: { optional_field: {} }])
# File lib/computed_model/dep_graph.rb, line 213
def plan(deps)
  normalized = ComputedModel.normalize_dependencies(deps)
  subfields_hash = {}
  uses = Set[]
  plan_nodes = []

  normalized.each do |name, subfields|
    raise "No dependency info for ##{name}" unless @original[name]

    uses.add(name)
    (subfields_hash[name] ||= []).unshift(*subfields)
  end
  @nodes_in_order.each do |node|
    uses.add(node.name) if node.type == :primary
    next unless uses.include?(node.name)

    node_subfields = ComputedModel::NormalizableArray.new(subfields_hash[node.name] || [])
    deps = Set[]
    node.edges.each_value do |edge|
      specval = edge.evaluate(node_subfields)
      if specval.any?
        deps.add(edge.name)
        uses.add(edge.name)
        (subfields_hash[edge.name] ||= []).unshift(*specval)
      end
    end
    plan_nodes.push(ComputedModel::Plan::Node.new(node.name, deps, node_subfields))
  end
  ComputedModel::Plan.new(plan_nodes.reverse, normalized.keys.to_set)
end