<commit_before># encoding: utf-8

require 'set'

module Nanoc3

  # Represents a directed graph. It is used by the dependency tracker for
  # storing and querying dependencies between items.
  #
  # @example Creating and using a directed graph
  #
  #   # Create a graph with three vertices
  #   graph = DirectedGraph.new(%w( a b c d ))
  #   
  #   # Add edges
  #   graph.add_edge('a', 'b')
  #   graph.add_edge('b', 'c')
  #   graph.add_edge('c', 'd')
  #   
  #   # Get (direct) predecessors
  #   graph.direct_predecessors_of('d').sort
  #     # => %w( c )
  #   graph.predecessors_of('d').sort
  #     # => %w( a b c )
  #   
  #   # Modify edges
  #   graph.remove_edge('a', 'b')
  #   
  #   # Get (direct) predecessors again
  #   graph.direct_predecessors_of('d').sort
  #     # => %w( c )
  #   graph.predecessors_of('d').sort
  #     # => %w( b c )
  class DirectedGraph

    # The list of vertices in this graph.
    #
    # @return [Array]
    attr_reader :vertices

    # @group Creating a graph

    # Creates a new directed graph with the given vertices.
    def initialize(vertices)
      @vertices = vertices

      @from_graph = {}
      @to_graph   = {}

      @vertice_indexes = {}
      @vertices.each_with_index do |v, i|
        @vertice_indexes[v] = i
      end

      @roots = Set.new(@vertices)

      invalidate_caches
    end

    # @group Modifying the graph

    # Adds an edge from the first vertex to the second vertex.
    #
    # @param from Vertex where the edge should start
    #
    # @param to   Vertex where the edge should end
    #
    # @return [void]
    def add_edge(from, to)
      add_vertex(from)
      add_vertex(to)

      @from_graph[from] ||= Set.new
      @from_graph[from] << to

      @to_graph[to] ||= Set.new
      @to_graph[to]  << from

      @roots.delete(to)

      invalidate_caches
    end

    # Removes the edge from the first vertex to the second vertex. If the
    # edge does not exist, nothing is done.
    #
    # @param from Start vertex of the edge
    #
    # @param to   End vertex of the edge
    #
    # @return [void]
    #
    # @since 3.2.0
    def delete_edge(from, to)
      @from_graph[from] ||= Set.new
      @from_graph[from].delete(to)

      @to_graph[to] ||= Set.new
      @to_graph[to].delete(from)

      @roots.add(to) if @to_graph[to].empty?

      invalidate_caches
    end

    # Adds the given vertex to the graph.
    #
    # @param [Vertex] v The vertex to add to the graph
    #
    # @return [void]
    #
    # @since 3.2.0
    def add_vertex(v)
      return if @vertices.include?(v)

      @vertices << v<commit_msg>removed silly Vertex type from directed graph docs<commit_after># encoding: utf-8

require 'set'

module Nanoc3

  # Represents a directed graph. It is used by the dependency tracker for
  # storing and querying dependencies between items.
  #
  # @example Creating and using a directed graph
  #
  #   # Create a graph with three vertices
  #   graph = DirectedGraph.new(%w( a b c d ))
  #   
  #   # Add edges
  #   graph.add_edge('a', 'b')
  #   graph.add_edge('b', 'c')
  #   graph.add_edge('c', 'd')
  #   
  #   # Get (direct) predecessors
  #   graph.direct_predecessors_of('d').sort
  #     # => %w( c )
  #   graph.predecessors_of('d').sort
  #     # => %w( a b c )
  #   
  #   # Modify edges
  #   graph.remove_edge('a', 'b')
  #   
  #   # Get (direct) predecessors again
  #   graph.direct_predecessors_of('d').sort
  #     # => %w( c )
  #   graph.predecessors_of('d').sort
  #     # => %w( b c )
  class DirectedGraph

    # The list of vertices in this graph.
    #
    # @return [Array]
    attr_reader :vertices

    # @group Creating a graph

    # Creates a new directed graph with the given vertices.
    def initialize(vertices)
      @vertices = vertices

      @from_graph = {}
      @to_graph   = {}

      @vertice_indexes = {}
      @vertices.each_with_index do |v, i|
        @vertice_indexes[v] = i
      end

      @roots = Set.new(@vertices)

      invalidate_caches
    end

    # @group Modifying the graph

    # Adds an edge from the first vertex to the second vertex.
    #
    # @param from Vertex where the edge should start
    #
    # @param to   Vertex where the edge should end
    #
    # @return [void]
    def add_edge(from, to)
      add_vertex(from)
      add_vertex(to)

      @from_graph[from] ||= Set.new
      @from_graph[from] << to

      @to_graph[to] ||= Set.new
      @to_graph[to]  << from

      @roots.delete(to)

      invalidate_caches
    end

    # Removes the edge from the first vertex to the second vertex. If the
    # edge does not exist, nothing is done.
    #
    # @param from Start vertex of the edge
    #
    # @param to   End vertex of the edge
    #
    # @return [void]
    #
    # @since 3.2.0
    def delete_edge(from, to)
      @from_graph[from] ||= Set.new
      @from_graph[from].delete(to)

      @to_graph[to] ||= Set.new
      @to_graph[to].delete(from)

      @roots.add(to) if @to_graph[to].empty?

      invalidate_caches
    end

    # Adds the given vertex to the graph.
    #
    # @param v The vertex to add to the graph
    #
    # @return [void]
    #
    # @since 3.2.0
    def add_vertex(v)
      return if @vertices.include?(v)

      @vertices << v
{'fraction_non_alphanumeric': 0.11854103343465046, 'fraction_numerical': 0.00303951367781155, 'mean_word_length': 2.177429088714544, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7228158', 'n_tokens_mistral': 1879, 'n_tokens_neox': 1814, 'n_words': 507}