newmen/versatile-diamond

View on GitHub
analyzer/lib/organizers/total_chunk.rb

Summary

Maintainability
A
0 mins
Test Coverage
module VersatileDiamond
  module Organizers

    # Describes the chunk which constructs from another chunks and can substract
    # another chunks from self
    class TotalChunk < BaseChunk
      include Modules::GraphDupper
      include MinuendChunk

      attr_reader :typical_reaction

      # Initializes the total chunk by target typical reaction and chunks which are
      # parts of this
      #
      # @param [DependentTypicalReaction] typical_reaction the target of passed chunks
      # @param [Array] chunks the list of parts of creating total chunk
      def initialize(typical_reaction, chunks)
        super(merge_targets(chunks), merge_links(chunks))
        @typical_reaction = typical_reaction

        @_total_links = nil
      end

      # Gets fake name for strong ordering and tests farm
      # @return [Symbol]
      def name
        fixed_reaction_name = @typical_reaction.name.gsub(' ', '_')
        :"__total_chunk_of_#{fixed_reaction_name}"
      end

      # Gets total links of all participants
      # @return [Hash] the graph of of relations between all using specs and atoms
      def total_links
        @_total_links ||=
          adsorb_links(targets, dup_graph(@typical_reaction.links), links)
      end

    private

      # Gets self chunk
      # @return [TotalChunk] self
      def owner
        self
      end

      # Gets set of targets from all passed containers
      # @param [Array] chunks the list of chunks which targets will be merged
      # @return [Set] the set of targets of internal chunks
      def merge_targets(chunks)
        chunks.map(&:targets).reduce(:+)
      end

      # Merges all links from chunks list
      # @param [Array] chunks which links will be merged
      # @return [Hash] the common links hash
      def merge_links(chunks)
        chunks.reduce({}) do |acc, chunk|
          adsorb_links(chunk.targets, acc, chunk.links)
        end
      end

      # Adsorbs all adsorbing links and gets total links
      # @param [Set] targets from which the edges cannot be duplicated
      # @param [Hash] initial_links which will be extended in result
      # @param [Hash] adsorbing_links which will extend the original links
      # @return [Hash] the extended original links
      def adsorb_links(targets, initial_links, adsorbing_links)
        dup_graph(raw_merge_total_links(targets, initial_links, adsorbing_links))
      end

      # @param [Set] targets from which the edges cannot be duplicated
      # @param [Hash] initial_links which will be extended in result
      # @param [Hash] adsorbing_links which will extend the original links
      # @return [Hash] the extended original links
      def raw_merge_total_links(targets, initial_links, adsorbing_links)
        adsorbing_links.each_with_object(initial_links) do |(spec_atom, rels), acc|
          acc[spec_atom] ||= []
          acc[spec_atom] = (acc[spec_atom] + rels).uniq
        end
      end
    end

  end
end