<commit_before>/****************************************************************/
/*               DO NOT MODIFY THIS HEADER                      */
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*           (c) 2010 Battelle Energy Alliance, LLC             */
/*                   ALL RIGHTS RESERVED                        */
/*                                                              */
/*          Prepared by Battelle Energy Alliance, LLC           */
/*            Under Contract No. DE-AC07-05ID14517              */
/*            With the U. S. Department of Energy               */
/*                                                              */
/*            See COPYRIGHT for full restrictions               */
/****************************************************************/

#ifndef DEPENDENCYRESOLVER_H
#define DEPENDENCYRESOLVER_H

// MOOSE includes
#include "Moose.h"
#include "MooseError.h"

// C++ includes
#include <map>
#include <set>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>
#include <exception>

template <typename T>
class DependencyResolverComparator
{
public:
  DependencyResolverComparator(const std::vector<T> & original_order)
    : _original_order(original_order)
  {
  }

  bool operator()(const T & a, const T & b) const
  {
    auto a_it = std::find(_original_order.begin(), _original_order.end(), a);
    auto b_it = std::find(_original_order.begin(), _original_order.end(), b);

    mooseAssert(a_it != _original_order.end(), "Bad DependencyResolverComparator request");
    mooseAssert(b_it != _original_order.end(), "Bad DependencyResolverComparator request");

    /**
     * Compare the iterators based on their original ordering.
     */
    return a_it < b_it;
  }

private:
  const std::vector<T> & _original_order;
};

template <typename T>
class DependencyResolver
{
public:
  DependencyResolver() {}

  ~DependencyResolver() {}

  /**
   * Insert a dependency pair - the first value or the "key" depends on the second value or the
   * "value"
   */
  void insertDependency(const T & key, const T & value);

  /**
   * Add an independent item to the set
   */
  void addItem(const T & value);

  /**
   * Returns a vector of sets that represent dependency resolved values.  Items in the same
   * subvector have no dependence upon one and other.
   */
  const std::vector<std::vector<T>> & getSortedValuesSets();

  /**
   * This function also returns dependency resolved values but with a simpler single vector
   * interface.
   * Some information may be lost as values at the same level that don't depend on one and other
   * can't
   * be represented in a single vector.  This isn't a problem in practice though.
   */
  const std::vector<T> & getSortedValues();

  bool operator()(const T & a, const T & b);

private:
  /**
   * Helper classes for returning only keys or values in an iterator format
   */
  template <typename map_type>
  class key_iterator;

  template <typename map_type>
  class value_iterator;

  /// This is our main data structure a multimap that contains any number of dependencies in a key = value format
  std::multimap<T, T> _depends;

  /// Extra items that need to come out in the sorted list but contain no dependencies
  std::vector<T> _independent_items;

  // A vector retaining the order in which items were added to the
  // resolver, to disambiguate ordering of items with no
  // mutual interdependencies
  std::vector<T> _ordering_vector;

  /// The sorted vector of sets
  std::vector<std::vector<T>> _ordered_items;

  /// The sorted vector (if requested)
  std::vector<T> _ordered_items_vector;
};

template <typename T>
class CyclicDependencyException : public std::runtime_error
{
public:
  CyclicDependencyException(const std::string & error,
                            const std::multimap<T, T> & cyclic_items) throw()
    : runtime_error(error), _cyclic_items(cyclic_items)
  {
  }

  CyclicDependencyException(const CyclicDependencyException & e) throw()
    : runtime_error(e), _cyclic_items(e._cyclic_items)
  {
  }

  ~CyclicDependencyException() throw() {}

  const std::multimap<T, T> & getCyclicDependencies() const { return _cyclic_items; }

private:
  std::multimap<T, T> _cyclic_items;
};

/**
 * Helper class definitions
 */
template <typename T>
template <typename map_type>
class DependencyResolver<T>::key_iterator : public map_type::iterator
{
public:
  typedef typename map_type::iterator map_iterator;
  typedef typename map_iterator::value_type::first_type key_type;

  key_iterator(const map_iterator & other) : map_type::iterator(other){};

  key_type & operator*() { return map_type::iterator::operator*().first; }
};

template <typename T>
template <typename map_type>
class DependencyResolver<T>::value_iterator : public map_type::iterator
{
public:
  typedef typename map_type::iterator map_iterator;
  typedef typename map_iterator::value_type::second_type value_type;

  value_iterator(const map_iterator & other) : map_type::iterator(other){};

  value_type & operator*() { return map_type::iterator::operator*().second; }
};

/**
 * DependencyResolver class definitions
 */
template <typename T>
void
DependencyResolver<T>::insertDependency(const T & key, const T & value)
{
  _depends.insert(std::make_pair(key, value));
  _ordering_vector.push_back(key);
  _ordering_vector.push_back(value);
}

template <typename T>
void
DependencyResolver<T>::addItem(const T & value)
{
  _independent_items.push_back(value);
  _ordering_vector.push_back(value);
}

template <typename T>
const std::vector<std::vector<T>> &
DependencyResolver<T>::getSortedValuesSets()
{
  /* Make a copy of the map to work on since we will remove values from the map*/
  std::multimap<T, T> depends = _depends;

  // Use the original ordering for ordering subvectors
  DependencyResolverComparator<T> comp(_ordering_vector);
<commit_msg>Avoid DependencyResolver ordering vec redundancies<commit_after>/****************************************************************/
/*               DO NOT MODIFY THIS HEADER                      */
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*           (c) 2010 Battelle Energy Alliance, LLC             */
/*                   ALL RIGHTS RESERVED                        */
/*                                                              */
/*          Prepared by Battelle Energy Alliance, LLC           */
/*            Under Contract No. DE-AC07-05ID14517              */
/*            With the U. S. Department of Energy               */
/*                                                              */
/*            See COPYRIGHT for full restrictions               */
/****************************************************************/

#ifndef DEPENDENCYRESOLVER_H
#define DEPENDENCYRESOLVER_H

// MOOSE includes
#include "Moose.h"
#include "MooseError.h"

// C++ includes
#include <map>
#include <set>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>
#include <exception>

template <typename T>
class DependencyResolverComparator
{
public:
  DependencyResolverComparator(const std::vector<T> & original_order)
    : _original_order(original_order)
  {
  }

  bool operator()(const T & a, const T & b) const
  {
    auto a_it = std::find(_original_order.begin(), _original_order.end(), a);
    auto b_it = std::find(_original_order.begin(), _original_order.end(), b);

    mooseAssert(a_it != _original_order.end(), "Bad DependencyResolverComparator request");
    mooseAssert(b_it != _original_order.end(), "Bad DependencyResolverComparator request");

    /**
     * Compare the iterators based on their original ordering.
     */
    return a_it < b_it;
  }

private:
  const std::vector<T> & _original_order;
};

template <typename T>
class DependencyResolver
{
public:
  DependencyResolver() {}

  ~DependencyResolver() {}

  /**
   * Insert a dependency pair - the first value or the "key" depends on the second value or the
   * "value"
   */
  void insertDependency(const T & key, const T & value);

  /**
   * Add an independent item to the set
   */
  void addItem(const T & value);

  /**
   * Returns a vector of sets that represent dependency resolved values.  Items in the same
   * subvector have no dependence upon one and other.
   */
  const std::vector<std::vector<T>> & getSortedValuesSets();

  /**
   * This function also returns dependency resolved values but with a simpler single vector
   * interface.
   * Some information may be lost as values at the same level that don't depend on one and other
   * can't
   * be represented in a single vector.  This isn't a problem in practice though.
   */
  const std::vector<T> & getSortedValues();

  bool operator()(const T & a, const T & b);

private:
  /**
   * Helper classes for returning only keys or values in an iterator format
   */
  template <typename map_type>
  class key_iterator;

  template <typename map_type>
  class value_iterator;

  /// This is our main data structure a multimap that contains any number of dependencies in a key = value format
  std::multimap<T, T> _depends;

  /// Extra items that need to come out in the sorted list but contain no dependencies
  std::vector<T> _independent_items;

  // A vector retaining the order in which items were added to the
  // resolver, to disambiguate ordering of items with no
  // mutual interdependencies
  std::vector<T> _ordering_vector;

  /// The sorted vector of sets
  std::vector<std::vector<T>> _ordered_items;

  /// The sorted vector (if requested)
  std::vector<T> _ordered_items_vector;
};

template <typename T>
class CyclicDependencyException : public std::runtime_error
{
public:
  CyclicDependencyException(const std::string & error,
                            const std::multimap<T, T> & cyclic_items) throw()
    : runtime_error(error), _cyclic_items(cyclic_items)
  {
  }

  CyclicDependencyException(const CyclicDependencyException & e) throw()
    : runtime_error(e), _cyclic_items(e._cyclic_items)
  {
  }

  ~CyclicDependencyException() throw() {}

  const std::multimap<T, T> & getCyclicDependencies() const { return _cyclic_items; }

private:
  std::multimap<T, T> _cyclic_items;
};

/**
 * Helper class definitions
 */
template <typename T>
template <typename map_type>
class DependencyResolver<T>::key_iterator : public map_type::iterator
{
public:
  typedef typename map_type::iterator map_iterator;
  typedef typename map_iterator::value_type::first_type key_type;

  key_iterator(const map_iterator & other) : map_type::iterator(other){};

  key_type & operator*() { return map_type::iterator::operator*().first; }
};

template <typename T>
template <typename map_type>
class DependencyResolver<T>::value_iterator : public map_type::iterator
{
public:
  typedef typename map_type::iterator map_iterator;
  typedef typename map_iterator::value_type::second_type value_type;

  value_iterator(const map_iterator & other) : map_type::iterator(other){};

  value_type & operator*() { return map_type::iterator::operator*().second; }
};

/**
 * DependencyResolver class definitions
 */
template <typename T>
void
DependencyResolver<T>::insertDependency(const T & key, const T & value)
{
  _depends.insert(std::make_pair(key, value));
  if (std::find(_ordering_vector.begin(), _ordering_vector.end(), key) ==
      _ordering_vector.end())
    _ordering_vector.push_back(key);
  if (std::find(_ordering_vector.begin(), _ordering_vector.end(), value) ==
      _ordering_vector.end())
    _ordering_vector.push_back(value);
}

template <typename T>
void
DependencyResolver<T>::addItem(const T & value)
{
  _independent_items.push_back(value);
  if (std::find(_ordering_vector.begin(), _ordering_vector.end(), value) ==
      _ordering_vector.end())
    _ordering_vector.push_back(value);
}

template <typename T>
const std::vector<std::vector<T>> &
DependencyResolver<T>::getSortedValuesSets()
{
  /* Make a copy of the map to work on since we will remove values from the map*/
  std::multimap<T, T> depends = _depends;

  // Use the original ordering for ordering subvectors
  DependencyResolverComparator<T> comp(_ordering_vector);

{'fraction_non_alphanumeric': 0.12584397624664442, 'fraction_numerical': 0.0021150248108679735, 'mean_word_length': 3.3016095171448567, 'pattern_counts': {'":': 0, '<': 89, '<?xml version=': 0, '>': 87, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2548629', 'n_tokens_mistral': 3569, 'n_tokens_neox': 3401, 'n_words': 1025}