<commit_before>// This file is part of the dune-stuff project:
//   https://users.dune-project.org/projects/dune-stuff/
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_LA_SOLVER_STUFF_HH
#define DUNE_STUFF_LA_SOLVER_STUFF_HH

#include <type_traits>
#include <cmath>

#if HAVE_DUNE_ISTL
# include <dune/istl/operators.hh>
# include <dune/istl/preconditioners.hh>
# include <dune/istl/solvers.hh>
# include <dune/istl/paamg/amg.hh>
#endif // HAVE_DUNE_ISTL

#include <dune/stuff/common/exceptions.hh>
#include <dune/stuff/common/configtree.hh>
#include <dune/stuff/la/container/istl.hh>

#include "../solver.hh"

namespace Dune {
namespace Stuff {
namespace LA {

#if HAVE_DUNE_ISTL

template< class S, class CommunicatorType >
class Solver< IstlRowMajorSparseMatrix< S >, CommunicatorType >
  : protected SolverUtils
{
public:
  typedef IstlRowMajorSparseMatrix< S > MatrixType;

#if !HAVE_MPI
  Solver(const MatrixType& matrix)
    : matrix_(matrix)
  {}
#endif // !HAVE_MPI

  Solver(const MatrixType& matrix,
         const CommunicatorType&
#if HAVE_MPI
                                 communicator
#else
                                 /*communicator*/
#endif
                                                 )
    : matrix_(matrix)
#if HAVE_MPI
    , communicator_(communicator)
#endif
  {}

  static std::vector< std::string > options()
  {
    return { "bicgstab.amg.ilu0"
#if !HAVE_MPI
           , "bicgstab.ilut"
#endif
           };
  } // ... options()

  static Common::ConfigTree options(const std::string& type)
  {
    SolverUtils::check_given(type, options());
    Common::ConfigTree iterative_options({"max_iter", "precision", "verbose"},
                                         {"10000",    "1e-10",     "0"});
#if !HAVE_MPI
    iterative_options.set("post_check_solves_system", "1e-5");
#endif
    if (type == "bicgstab.amg.ilu0") {
      iterative_options.set("smoother.iterations", "1");
      iterative_options.set("smoother.relaxation_factor", "1");
      iterative_options.set("preconditioner.max_level", "100");
      iterative_options.set("preconditioner.coarse_target", "1000");
      iterative_options.set("preconditioner.min_coarse_rate", "1.2");
      iterative_options.set("preconditioner.prolong_damp", "1.6");
      iterative_options.set("preconditioner.anisotropy_dim", "2");
      iterative_options.set("preconditioner.isotropy_dim", "2");
      iterative_options.set("preconditioner.verbose", "1");
      iterative_options.set("smoother.verbose", "1");
#if !HAVE_MPI
    } else if (type == "bicgstab.ilut") {
        iterative_options.set("preconditioner.iterations", "2");
        iterative_options.set("preconditioner.relaxation_factor", "1.0");
#endif // !HAVE_MPI
    } else
      DUNE_THROW_COLORFULLY(Exceptions::internal_error,
                            "Given type '" << type << "' is not supported, although it was reported by options()!");
    iterative_options.set("type", type);
    return iterative_options;
  } // ... options(...)

  void apply(const IstlDenseVector< S >& rhs, IstlDenseVector< S >& solution) const
  {
    apply(rhs, solution, options()[0]);
  }

  void apply(const IstlDenseVector< S >& rhs, IstlDenseVector< S >& solution, const std::string& type) const
  {
    apply(rhs, solution, options(type));
  }

  /**
   *  \note does a copy of the rhs
   */
  void apply(const IstlDenseVector< S >& rhs, IstlDenseVector< S >& solution, const Common::ConfigTree& opts) const
  {
    if (!opts.has_key("type"))
      DUNE_THROW_COLORFULLY(Exceptions::configuration_error,
                            "Given options (see below) need to have at least the key 'type' set!\n\n" << opts);
    const auto type = opts.get< std::string >("type");
    SolverUtils::check_given(type, options());
    const Common::ConfigTree default_opts = options(type);
    IstlDenseVector< S > writable_rhs = rhs.copy();
    // solve
    if (type == "bicgstab.amg.ilu0") {
#if HAVE_MPI
      typedef typename MatrixType::BackendType           IstlMatrixType;
      typedef typename IstlDenseVector< S >::BackendType IstlVectorType;

      typedef SeqILU0< IstlMatrixType, IstlVectorType, IstlVectorType, 1 > SequentialSmootherType;
      typedef BlockPreconditioner< IstlVectorType, IstlVectorType,
                                   CommunicatorType,
                                   SequentialSmootherType> SmootherType;

      typedef OverlappingSchwarzOperator< IstlMatrixType, IstlVectorType, IstlVectorType,
                                          CommunicatorType > MatrixOperatorType;
      MatrixOperatorType matrix_operator(matrix_.backend(), communicator_);

      Amg::Parameters criterion_parameters(opts.get("preconditioner.max_level", default_opts.get< size_t >("preconditioner.max_level")),
                                          opts.get("preconditioner.coarse_target",
                                                   default_opts.get< size_t >("preconditioner.coarse_target")),
                                          opts.get("preconditioner.min_coarse_rate",
                                                   default_opts.get< S >("preconditioner.min_coarse_rate")),
                                          opts.get("preconditioner.prolong_damp", default_opts.get< S >("preconditioner.prolong_damp")));
      criterion_parameters.setDefaultValuesIsotropic(opts.get("preconditioner.isotropy_dim",
                                                              default_opts.get< size_t >("preconditioner.isotropy_dim")));
      criterion_parameters.setDefaultValuesAnisotropic(opts.get("preconditioner.anisotropy_dim",
                                                               default_opts.get< size_t >("preconditioner.anisotropy_dim"))); // <- dim
      criterion_parameters.setDebugLevel(opts.get("preconditioner.verbose",
                                                  default_opts.get< size_t >("preconditioner.verbose")));

      typename Amg::SmootherTraits< SmootherType >::Arguments smoother_arguments;
      smoother_arguments.iterations = opts.get("smoother.iterations", default_opts.get< size_t >("smoother.iterations"));
      smoother_arguments.relaxationFactor = opts.get("smoother.relaxation_factor",
                                               default_opts.get< S >("smoother.relaxation_factor"));

      Amg::CoarsenCriterion< Amg::SymmetricCriterion< IstlMatrixType, Amg::FirstDiagonal > >
          smoother_criterion(criterion_parameters);
      typedef Amg::AMG< MatrixOperatorType, IstlVectorType, SmootherType, CommunicatorType > PreconditionerType;
      PreconditionerType preconditioner(matrix_operator, smoother_criterion, smoother_arguments, communicator_);

      OverlappingSchwarzScalarProduct< IstlVectorType, CommunicatorType > scalar_product(communicator_);

      InverseOperatorResult statistics;
      BiCGSTABSolver< IstlVectorType > solver(matrix_operator,
                                              scalar_product,
                                              preconditioner,
                                              opts.get("precision", default_opts.get< S >("precision")),
                                              opts.get("max_iter", default_opts.get< size_t >("max_iter")),
                                              (communicator_.communicator().rank() == 0)
                                                  ? opts.get("verbose", default_opts.get< int >("verbose"))
                                                  : 0);
      solver.apply(solution.backend(), writable_rhs.backend(), statistics);
      if (!statistics.converged)
        DUNE_THROW_COLORFULLY(Exceptions::linear_solver_failed_bc_it_did_not_converge,
                              "The dune-istl backend reported 'InverseOperatorResult.converged == false'!\n"
                              << "Those were the given options:\n\n"
                              << opts);
#else // HAVE_MPI
      typedef MatrixAdapter< typename MatrixType::BackendType,
                             typename IstlDenseVector< S >::BackendType,
                             typename IstlDenseVector< S >::BackendType > MatrixOperatorType;
      MatrixOperatorType matrix_operator(matrix_.backend());
      typedef SeqILU0< typename MatrixType::BackendType,
                       typename IstlDenseVector< S >::BackendType,
                       typename IstlDenseVector< S >::BackendType > SmootherType;
      typedef Dune::Amg::AMG< MatrixOperatorType,
                              typename IstlDenseVector< S >::BackendType,
                              SmootherType > PreconditionerType;
      Dune::SeqScalarProduct< typename IstlDenseVector< S >::BackendType > scalar_product;
      typedef typename Dune::Amg::SmootherTraits< SmootherType >::Arguments SmootherArgs;
      SmootherArgs smootherArgs;
      smootherArgs.iterations = opts.get("smoother.iterations", default_opts.get< size_t >("smoother.iterations"));
      smootherArgs.relaxationFactor = opts.get("smoother.relaxation_factor",
                                               default_opts.get< S >("smoother.relaxation_factor"));

      Dune::Amg::Parameters params(opts.get("preconditioner.max_level", default_opts.get< size_t >("preconditioner.max_level")),
                                   opts.get("preconditioner.coarse_target",
                                            default_opts.get< size_t >("preconditioner.coarse_target")),
                                   opts.get("preconditioner.min_coarse_rate",
                                            default_opts.get< S >("preconditioner.min_coarse_rate")),
                                   opts.get("preconditioner.prolong_damp", default_opts.get< S >("preconditioner.prolong_damp")));
      params.setDefaultValuesIsotropic(opts.get("preconditioner.isotropy_dim",
                                                              default_opts.get< size_t >("preconditioner.isotropy_dim")));
      params.setDefaultValuesAnisotropic(opts.get("preconditioner.anisotropy_dim",
                                                  default_opts.get< size_t >("preconditioner.anisotropy_dim"))); // <- dim
      typedef Dune::Amg::CoarsenCriterion
          < Dune::Amg::SymmetricCriterion< typename MatrixType::BackendType, Dune::Amg::FirstDiagonal > > AmgCriterion;
      AmgCriterion amg_criterion(params);
      amg_criterion.setDebugLevel(opts.get("preconditioner.verbose", default_opts.get< size_t >("preconditioner.verbose")));
      PreconditionerType preconditioner(matrix_operator, amg_criterion, smootherArgs);
      typedef BiCGSTABSolver< typename IstlDenseVector< S >::BackendType > SolverType;
      SolverType solver(matrix_operator,
                        scalar_product,
                        preconditioner,
                        opts.get("precision", default_opts.get< S >("precision")),
                        opts.get("max_iter", default_opts.get< size_t >("max_iter")),
                        opts.get("verbose", default_opts.get< size_t >("verbose")));
      InverseOperatorResult stat;
      solver.apply(solution.backend(), writable_rhs.backend(), stat);
      if (!stat.converged)
        DUNE_THROW_COLORFULLY(Exceptions::linear_solver_failed_bc_it_did_not_converge,
                              "The dune-istl backend reported 'InverseOperatorResult.converged == false'!\n"
                              << "Those were the given options:\n\n"
                              << opts);
#endif // HAVE_MPI
#if !HAVE_MPI
    } else if (type == "bicgstab.ilut") {
      typedef MatrixAdapter< typename MatrixType::BackendType,
                             typename IstlDenseVector< S >::BackendType,
                             typename IstlDenseVector< S >::BackendType > MatrixOperatorType;
      MatrixOperatorType matrix_operator(matrix_.backend());
      typedef SeqILUn< typename MatrixType::BackendType,
                       typename IstlDenseVector< S >::BackendType,
                       typename IstlDenseVector< S >::BackendType > PreconditionerType;
      PreconditionerType preconditioner(matrix_.backend(),
                                        opts.get("preconditioner.iterations",
                                                 default_opts.get< size_t >("preconditioner.iterations")),
                                        opts.get("preconditioner.relaxation_factor",
                                                 default_opts.get< S >("preconditioner.relaxation_factor")));
      typedef BiCGSTABSolver< typename IstlDenseVector< S >::BackendType > SolverType;
      SolverType solver(matrix_operator,
                        preconditioner,
                        opts.get("precision", default_opts.get< S >("precision")),
                        opts.get("max_iter", default_opts.get< size_t >("max_iter")),
                        opts.get("verbose", default_opts.get< int >("verbose")));
      InverseOperatorResult stat;
      solver.apply(solution.backend(), writable_rhs.backend(), stat);
      if (!stat.converged)
        DUNE_THROW_COLORFULLY(Exceptions::linear_solver_failed_bc_it_did_not_converge,
                              "The dune-istl backend reported 'InverseOperatorResult.converged == false'!\n"
                              << "Those were the given options:\n\n"
                              << opts);
#endif // !HAVE_MPI
    } else
      DUNE_THROW_COLORFULLY(Exceptions::internal_error,
                            "Given type '" << type << "' is not supported, although it was reported by options()!");
#if !HAVE_MPI
    // check (use writable_rhs as tmp)
    const S post_check_solves_system_theshhold = opts.get("post_check_solves_system",
                                                          default_opts.get< S >("post_check_solves_system"));
    if (post_check_solves_system_theshhold > 0) {
      matrix_.mv(solution, writable_rhs);
      writable_rhs -= rhs;
      const S sup_norm = writable_rhs.sup_norm();
      if (sup_norm > post_check_solves_system_theshhold || std::isnan(sup_norm) || std::isinf(sup_norm))
        DUNE_THROW_COLORFULLY(Exceptions::linear_solver_failed_bc_the_solution_does_not_solve_the_system,
                              "The computed solution does not solve the system (although the dune-istl backend "
                              << "reported no error) and you requested checking (see options below)!\n"
                              << "If you want to disable this check, set 'post_check_solves_system = 0' in the options."
                              << "\n\n"
                              << "  (A * x - b).sup_norm() = " << writable_rhs.sup_norm() << "\n\n"
                              << "Those were the given options:\n\n"
                              << opts);
    }
#endif // !HAVE_MPI
  } // ... apply(...)

private:
  const MatrixType& matrix_;
#if HAVE_MPI
  const CommunicatorType& communicator_;
#endif
}; // class Solver

#else // HAVE_DUNE_ISTL

template< class S >
class Solver< IstlRowMajorSparseMatrix< S > >{ static_assert(Dune::AlwaysFalse< S >::value,
                                                             "You are missing dune-istl!"); };

#endif // HAVE_DUNE_ISTL

} // namespace LA
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_LA_SOLVER_STUFF_HH
<commit_msg>[la.solver.istl] clean up the amg * reorder parallel/sequential variants to share as much as possible * default to no output<commit_after>// This file is part of the dune-stuff project:
//   https://users.dune-project.org/projects/dune-stuff/
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_STUFF_LA_SOLVER_STUFF_HH
#define DUNE_STUFF_LA_SOLVER_STUFF_HH

#include <type_traits>
#include <cmath>

#if HAVE_DUNE_ISTL
# include <dune/istl/operators.hh>
# include <dune/istl/preconditioners.hh>
# include <dune/istl/solvers.hh>
# include <dune/istl/paamg/amg.hh>
#endif // HAVE_DUNE_ISTL

#include <dune/stuff/common/exceptions.hh>
#include <dune/stuff/common/configtree.hh>
#include <dune/stuff/la/container/istl.hh>

#include "../solver.hh"

namespace Dune {
namespace Stuff {
namespace LA {

#if HAVE_DUNE_ISTL

template< class S, class CommunicatorType >
class Solver< IstlRowMajorSparseMatrix< S >, CommunicatorType >
  : protected SolverUtils
{
public:
  typedef IstlRowMajorSparseMatrix< S > MatrixType;

#if !HAVE_MPI
  Solver(const MatrixType& matrix)
    : matrix_(matrix)
  {}
#endif // !HAVE_MPI

  Solver(const MatrixType& matrix,
         const CommunicatorType&
#if HAVE_MPI
                                 communicator
#else
                                 /*communicator*/
#endif
                                                 )
    : matrix_(matrix)
#if HAVE_MPI
    , communicator_(communicator)
#endif
  {}

  static std::vector< std::string > options()
  {
    return { "bicgstab.amg.ilu0"
#if !HAVE_MPI
           , "bicgstab.ilut"
#endif
           };
  } // ... options()

  static Common::ConfigTree options(const std::string& type)
  {
    SolverUtils::check_given(type, options());
    Common::ConfigTree iterative_options({"max_iter", "precision", "verbose"},
                                         {"10000",    "1e-10",     "0"});
#if !HAVE_MPI
    iterative_options.set("post_check_solves_system", "1e-5");
#endif
    if (type == "bicgstab.amg.ilu0") {
      iterative_options.set("smoother.iterations", "1");
      iterative_options.set("smoother.relaxation_factor", "1");
      iterative_options.set("smoother.verbose", "0");
      iterative_options.set("preconditioner.max_level", "100");
      iterative_options.set("preconditioner.coarse_target", "1000");
      iterative_options.set("preconditioner.min_coarse_rate", "1.2");
      iterative_options.set("preconditioner.prolong_damp", "1.6");
      iterative_options.set("preconditioner.anisotropy_dim", "2"); // <- this should be the dimDomain if the discretizations!
      iterative_options.set("preconditioner.isotropy_dim", "2");   // <- this as well
      iterative_options.set("preconditioner.verbose", "0");
#if !HAVE_MPI
    } else if (type == "bicgstab.ilut") {
        iterative_options.set("preconditioner.iterations", "2");
        iterative_options.set("preconditioner.relaxation_factor", "1.0");
#endif // !HAVE_MPI
    } else
      DUNE_THROW_COLORFULLY(Exceptions::internal_error,
                            "Given type '" << type << "' is not supported, although it was reported by options()!");
    iterative_options.set("type", type);
    return iterative_options;
  } // ... options(...)

  void apply(const IstlDenseVector< S >& rhs, IstlDenseVector< S >& solution) const
  {
    apply(rhs, solution, options()[0]);
  }

  void apply(const IstlDenseVector< S >& rhs, IstlDenseVector< S >& solution, const std::string& type) const
  {
    apply(rhs, solution, options(type));
  }

  /**
   *  \note does a copy of the rhs
   */
  void apply(const IstlDenseVector< S >& rhs, IstlDenseVector< S >& solution, const Common::ConfigTree& opts) const
  {
    if (!opts.has_key("type"))
      DUNE_THROW_COLORFULLY(Exceptions::configuration_error,
                            "Given options (see below) need to have at least the key 'type' set!\n\n" << opts);
    const auto type = opts.get< std::string >("type");
    SolverUtils::check_given(type, options());
    const Common::ConfigTree default_opts = options(type);
    IstlDenseVector< S > writable_rhs = rhs.copy();
    // solve
    if (type == "bicgstab.amg.ilu0") {
      // define the matrix operator
      typedef typename MatrixType::BackendType           IstlMatrixType;
      typedef typename IstlDenseVector< S >::BackendType IstlVectorType;
#if HAVE_MPI
      typedef OverlappingSchwarzOperator< IstlMatrixType, IstlVectorType, IstlVectorType, CommunicatorType >
          MatrixOperatorType;
      MatrixOperatorType matrix_operator(matrix_.backend(), communicator_);
#else // HAVE_MPI
      typedef MatrixAdapter< IstlMatrixType, IstlVectorType, IstlVectorType > MatrixOperatorType;
      MatrixOperatorType matrix_operator(matrix_.backend());
#endif // HAVE_MPI

      // define the scalar product
#if HAVE_MPI
      OverlappingSchwarzScalarProduct< IstlVectorType, CommunicatorType > scalar_product(communicator_);
#else
      Dune::SeqScalarProduct< typename IstlDenseVector< S >::BackendType > scalar_product;
#endif

      // define ILU0 as the smoother for the AMG
#if HAVE_MPI
      typedef SeqILU0< IstlMatrixType, IstlVectorType, IstlVectorType, 1 > SequentialSmootherType;
      typedef BlockPreconditioner< IstlVectorType, IstlVectorType,
                                   CommunicatorType,
                                   SequentialSmootherType> SmootherType;
#else // HAVE_MPI
      typedef SeqILU0< IstlMatrixType, IstlVectorType, IstlVectorType > SmootherType;
#endif
      typename Amg::SmootherTraits< SmootherType >::Arguments smoother_parameters;
      smoother_parameters.iterations = opts.get("smoother.iterations",
                                                default_opts.get< size_t >("smoother.iterations"));
      smoother_parameters.relaxationFactor = opts.get("smoother.relaxation_factor",
                                                      default_opts.get< S >("smoother.relaxation_factor"));

      // define the AMG as the preconditioner for the BiCGStab solver
      Amg::Parameters amg_parameters(opts.get("preconditioner.max_level",
                                              default_opts.get< size_t >("preconditioner.max_level")),
                                     opts.get("preconditioner.coarse_target",
                                              default_opts.get< size_t >("preconditioner.coarse_target")),
                                     opts.get("preconditioner.min_coarse_rate",
                                              default_opts.get< S >("preconditioner.min_coarse_rate")),
                                     opts.get("preconditioner.prolong_damp",
                                              default_opts.get< S >("preconditioner.prolong_damp")));
      amg_parameters.setDefaultValuesIsotropic(opts.get("preconditioner.isotropy_dim",
                                                        default_opts.get< size_t >("preconditioner.isotropy_dim")));
      amg_parameters.setDefaultValuesAnisotropic(opts.get("preconditioner.anisotropy_dim",
                                                          default_opts.get< size_t >("preconditioner.anisotropy_dim")));
      amg_parameters.setDebugLevel(opts.get("preconditioner.verbose",
                                            default_opts.get< size_t >("preconditioner.verbose")));
      Amg::CoarsenCriterion< Amg::SymmetricCriterion< IstlMatrixType, Amg::FirstDiagonal > >
          amg_criterion(amg_parameters);
#if HAVE_MPI
      typedef Amg::AMG< MatrixOperatorType, IstlVectorType, SmootherType, CommunicatorType > PreconditionerType;
      PreconditionerType preconditioner(matrix_operator, amg_criterion, smoother_parameters, communicator_);
#else // HAVE_MPI
      typedef Amg::AMG< MatrixOperatorType, IstlVectorType, SmootherType > PreconditionerType;
      PreconditionerType preconditioner(matrix_operator, amg_criterion, smoother_parameters);
#endif // HAVE_MPI

      // define the BiCGStab as the actual solver
      BiCGSTABSolver< IstlVectorType > solver(matrix_operator,
                                              scalar_product,
                                              preconditioner,
                                              opts.get("precision", default_opts.get< S >("precision")),
                                              opts.get("max_iter", default_opts.get< size_t >("max_iter")),
#if HAVE_MPI
                                              (communicator_.communicator().rank() == 0)
                                                  ? opts.get("verbose", default_opts.get< int >("verbose"))
                                                  : 0
#else // HAVE_MPI
                                              opts.get("verbose", default_opts.get< int >("verbose"))
#endif
                                                                                );

      // call the solver an do the actual work
      InverseOperatorResult stats;
      solver.apply(solution.backend(), writable_rhs.backend(), stats);
      if (!stats.converged)
        DUNE_THROW_COLORFULLY(Exceptions::linear_solver_failed_bc_it_did_not_converge,
                              "The dune-istl backend reported 'InverseOperatorResult.converged == false'!\n"
                              << "Those were the given options:\n\n"
                              << opts);
#if !HAVE_MPI
    } else if (type == "bicgstab.ilut") {
      typedef MatrixAdapter< typename MatrixType::BackendType,
                             typename IstlDenseVector< S >::BackendType,
                             typename IstlDenseVector< S >::BackendType > MatrixOperatorType;
      MatrixOperatorType matrix_operator(matrix_.backend());
      typedef SeqILUn< typename MatrixType::BackendType,
                       typename IstlDenseVector< S >::BackendType,
                       typename IstlDenseVector< S >::BackendType > PreconditionerType;
      PreconditionerType preconditioner(matrix_.backend(),
                                        opts.get("preconditioner.iterations",
                                                 default_opts.get< size_t >("preconditioner.iterations")),
                                        opts.get("preconditioner.relaxation_factor",
                                                 default_opts.get< S >("preconditioner.relaxation_factor")));
      typedef BiCGSTABSolver< typename IstlDenseVector< S >::BackendType > SolverType;
      SolverType solver(matrix_operator,
                        preconditioner,
                        opts.get("precision", default_opts.get< S >("precision")),
                        opts.get("max_iter", default_opts.get< size_t >("max_iter")),
                        opts.get("verbose", default_opts.get< int >("verbose")));
      InverseOperatorResult stat;
      solver.apply(solution.backend(), writable_rhs.backend(), stat);
      if (!stat.converged)
        DUNE_THROW_COLORFULLY(Exceptions::linear_solver_failed_bc_it_did_not_converge,
                              "The dune-istl backend reported 'InverseOperatorResult.converged == false'!\n"
                              << "Those were the given options:\n\n"
                              << opts);
#endif // !HAVE_MPI
    } else
      DUNE_THROW_COLORFULLY(Exceptions::internal_error,
                            "Given type '" << type << "' is not supported, although it was reported by options()!");
#if !HAVE_MPI
    // check (use writable_rhs as tmp)
    const S post_check_solves_system_theshhold = opts.get("post_check_solves_system",
                                                          default_opts.get< S >("post_check_solves_system"));
    if (post_check_solves_system_theshhold > 0) {
      matrix_.mv(solution, writable_rhs);
      writable_rhs -= rhs;
      const S sup_norm = writable_rhs.sup_norm();
      if (sup_norm > post_check_solves_system_theshhold || std::isnan(sup_norm) || std::isinf(sup_norm))
        DUNE_THROW_COLORFULLY(Exceptions::linear_solver_failed_bc_the_solution_does_not_solve_the_system,
                              "The computed solution does not solve the system (although the dune-istl backend "
                              << "reported no error) and you requested checking (see options below)!\n"
                              << "If you want to disable this check, set 'post_check_solves_system = 0' in the options."
                              << "\n\n"
                              << "  (A * x - b).sup_norm() = " << writable_rhs.sup_norm() << "\n\n"
                              << "Those were the given options:\n\n"
                              << opts);
    }
#endif // !HAVE_MPI
  } // ... apply(...)

private:
  const MatrixType& matrix_;
#if HAVE_MPI
  const CommunicatorType& communicator_;
#endif
}; // class Solver

#else // HAVE_DUNE_ISTL

template< class S >
class Solver< IstlRowMajorSparseMatrix< S > >{ static_assert(Dune::AlwaysFalse< S >::value,
                                                             "You are missing dune-istl!"); };

#endif // HAVE_DUNE_ISTL

} // namespace LA
} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_LA_SOLVER_STUFF_HH
<|endoftext|>


<commit_before>//
// javaTools.cxx
//

/*
OME Bio-Formats ITK plugin for calling Bio-Formats from the Insight Toolkit.
Copyright (c) 2008-@year@, UW-Madison LOCI.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the UW-Madison LOCI nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY UW-MADISON LOCI ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL UW-MADISON LOCI BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/*
IMPORTANT NOTE: Although this software is distributed according to a
"BSD-style" license, it requires the OME Bio-Formats Java library to do
anything useful, which is licensed under the GPL v2 or later.
As such, if you wish to distribute this software with Bio-Formats itself,
your combined work must be distributed under the terms of the GPL.
*/
#include <iostream>
#include <string>
#include <sstream>
#include "javaTools.h"

#ifndef PATH_MAX
#define PATH_MAX 1024
#endif

#ifdef WIN32
#include <windows.h>
#include <errno.h>
#define mkdir fake_posix_mkdir
static int fake_posix_mkdir(const char *name)
{
          return mkdir(name);
}

static void die(const char *fmt, ...)
{
  va_list ap;

  va_start(ap, fmt);
  vfprintf(stderr, fmt, ap);
  va_end(ap);
  fputc('\n', stderr);

  exit(1);
}

static void *xcalloc(size_t size, size_t nmemb)
{
  void *result = calloc(size, nmemb);
  if (!result)
    die("Out of memory");

  return result;
}

static void string_release(std::string *string)
{
  if (string) {
    free(string);
  }
}

struct entry {
  char d_name[PATH_MAX];
  int d_namlen;
} entry;

struct dir {
  std::string pattern;
  HANDLE handle;
  WIN32_FIND_DATA find_data;
  int done;
  struct entry entry;
};

struct dir *open_dir(const char *path)
{
  struct dir *result = (dir*)xcalloc(sizeof(struct dir), 1);
  if (!result)
    return result;
/*
  result->pattern = (std::string*)malloc(strlen(path) + 3);
  if (!result->pattern) {
    errno = ENOMEM;
    return NULL;
  }
*/
  result->pattern.assign(path);
  result->pattern.append(".*");
  result->handle = FindFirstFile(result->pattern.c_str(), &(result->find_data));
  if (result->handle == INVALID_HANDLE_VALUE) {
    //free(result->pattern);
    free(result);
    return NULL;
  }
  result->done = 0;
  return result;
}

struct entry *read_dir(struct dir *dir)
{
  if (dir->done)
    return NULL;
  strcpy(dir->entry.d_name, dir->find_data.cFileName);
  dir->entry.d_namlen = strlen(dir->entry.d_name);
  if (FindNextFile(dir->handle, &dir->find_data) == 0)
    dir->done = 1;
  return &dir->entry;
}

int close_dir(struct dir *dir)
{
  //string_release(dir->pattern);
  FindClose(dir->handle);
  free(dir);
  return 0;
}

#define DIR struct dir
#define dirent entry
#define opendir open_dir
#define readdir read_dir
#define closedir close_dir
#else
#include <dirent.h>
#endif

#if defined (_WIN32)
#define PATHSTEP ';'
#define SLASH '\\'
#else
#define PATHSTEP ':'
#define SLASH '/'
#endif

#ifdef __APPLE__
#define PATH "DYLD_LIBRARY_PATH"
#endif
#ifdef __linux__
#define PATH "LD_LIBRARY_PATH"
#endif
#ifdef _WIN32
#define PATH "PATH"
#endif
#ifdef _WIN64
#define PATH "PATH"
#endif

using namespace std;

void JavaTools::createJVM()
{
  JavaTools::createJVM("jar", true, 256, vector<string>(), vector<string>(), vector<string>());
}

void JavaTools::createJVM(string jarFolder)
{
  JavaTools::createJVM(jarFolder, true, 256, vector<string>(), vector<string>(), vector<string>());
}

void JavaTools::createJVM(int memory)
{
  JavaTools::createJVM("jar", true, memory, vector<string>(), vector<string>(), vector<string>());
}

void JavaTools::createJVM(bool headless)
{
  JavaTools::createJVM("jar", headless, 256, vector<string>(), vector<string>(), vector<string>());
}

void JavaTools::createJVM(bool headless, int memory)
{
  JavaTools::createJVM("jar", headless, memory, vector<string>(), vector<string>(), vector<string>());
}

void JavaTools::createJVM(string jarFolder, bool headless, int memory)
{
  JavaTools::createJVM(jarFolder, headless, memory, vector<string>(), vector<string>(), vector<string>());
}

/**
 * jarFolder is the name of the path to a directory of jars to be added to the classpath (default: jar)
 * headless turns headless on or off for JVM instantiation (default: on)
 * memory controls memory for instantiation of JVM in MB (default: 256)
 * extraClasspath is a list of additional classpath entries to include
 * extraJavaLibraryPath is a list of path entries to be appended to the JVM's java.library.path. ( default: .)
 * extraOptions is a list of any other desired arguments to the JVM, added to the jace::OptionList (e.g., "-verbose:jni")
 */
void JavaTools::createJVM(string jarFolder, bool headless, int memory,
  vector<string> extraClasspath, vector<string> extraJavaLibraryPath, vector<string> extraOptions)
{
  try {
    jace::StaticVmLoader* tmpLoader = (jace::StaticVmLoader*)jace::helper::getVmLoader();
    if(tmpLoader == NULL) {

      // initialize the Java virtual machine
      jace::OptionList list;
      jace::StaticVmLoader loader(JNI_VERSION_1_4);

      string classpath ("");

      DIR *d;
      struct dirent *dir;

//TODO: test jar/*
      // All .jar files in the jarFolder are added to the JVM's classpath
      d = opendir(jarFolder.c_str());

      if(d)
      {
        while ((dir = readdir(d)) != NULL)
        {
          string tmpName(dir->d_name);

          if(tmpName.find(".jar") != string::npos)
          {
            if(classpath.length() >= 1)
            {
              classpath += PATHSTEP;
            }
            classpath += jarFolder + SLASH + dir->d_name;
          }
        }

        closedir(d);
      }

      // All items in the extraClasspath are added to the JVM's classpath
      if(!extraClasspath.empty())
      {
        for(vector<string>::iterator it = extraClasspath.begin(); it != extraClasspath.end(); it++)
        {
          classpath += PATHSTEP;
          classpath += *it;
        }
      }

      //std::cout << "extraClasspath : " << extraClasspath << std::endl;
      //std::cout << "Classpath for JVM: " << classpath << std::endl;

      // Gets the system-specific path environment variable's contents (which will eventually be passed to java.library.path in this JVM)
      std::string pName = PATH;
      char * libPath;
      libPath = getenv(pName.c_str());
      std::string jLibPath("");
      if(libPath != NULL)
      {
        jLibPath = libPath;
      }

      // If no extra Java library path is specified, the current working directory is appended and passed to java.library.path.
      // Otherwise, each provided path is appended.
      if(extraJavaLibraryPath.empty())
      {
        if(jLibPath.length() >= 1)
        {
          jLibPath += PATHSTEP;
        }
        jLibPath += '.';
      }
      else
      {
        for(vector<string>::iterator it = extraJavaLibraryPath.begin(); it != extraJavaLibraryPath.end(); it++)
        {
          if(jLibPath.length() >= 1)
          {
           jLibPath += PATHSTEP;
          }
          jLibPath += *it;
        }
      }

      list.push_back(jace::ClassPath(classpath));
      list.push_back(jace::CustomOption("-Xcheck:jni"));

      // Int to string conversion
      std::string mem;
      std::stringstream out;
      out << memory;
      mem = out.str();

      list.push_back(jace::CustomOption("-Xmx" + mem + "m"));

      if (headless)
      {
        list.push_back(jace::CustomOption("-Djava.awt.headless=true"));
      }

      list.push_back(jace::CustomOption("-Djava.library.path=" + jLibPath));

      // All extra options are added as CustomOptions for JVM instantiation
      if (!extraOptions.empty()) {
        for (vector<string>::iterator it = extraOptions.begin(); it != extraOptions.end(); it++)
        {
          list.push_back(jace::CustomOption(*it));
        }
      }

      jace::helper::createVm(loader, list, false);
    }
  }
  catch (jace::JNIException& jniException) {
    std::cerr << "Exception creating JVM: " << jniException.what() << std::endl;
  }
}
<commit_msg>Fixed append in Windows directory search<commit_after>//
// javaTools.cxx
//

/*
OME Bio-Formats ITK plugin for calling Bio-Formats from the Insight Toolkit.
Copyright (c) 2008-@year@, UW-Madison LOCI.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the UW-Madison LOCI nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY UW-MADISON LOCI ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL UW-MADISON LOCI BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/*
IMPORTANT NOTE: Although this software is distributed according to a
"BSD-style" license, it requires the OME Bio-Formats Java library to do
anything useful, which is licensed under the GPL v2 or later.
As such, if you wish to distribute this software with Bio-Formats itself,
your combined work must be distributed under the terms of the GPL.
*/
#include <iostream>
#include <string>
#include <sstream>
#include "javaTools.h"

#ifndef PATH_MAX
#define PATH_MAX 1024
#endif

#ifdef WIN32
#include <windows.h>
#include <errno.h>
#define mkdir fake_posix_mkdir
static int fake_posix_mkdir(const char *name)
{
          return mkdir(name);
}

static void die(const char *fmt, ...)
{
  va_list ap;

  va_start(ap, fmt);
  vfprintf(stderr, fmt, ap);
  va_end(ap);
  fputc('\n', stderr);

  exit(1);
}

static void *xcalloc(size_t size, size_t nmemb)
{
  void *result = calloc(size, nmemb);
  if (!result)
    die("Out of memory");

  return result;
}

static void string_release(std::string *string)
{
  if (string) {
    free(string);
  }
}

struct entry {
  char d_name[PATH_MAX];
  int d_namlen;
} entry;

struct dir {
  std::string pattern;
  HANDLE handle;
  WIN32_FIND_DATA find_data;
  int done;
  struct entry entry;
};

struct dir *open_dir(const char *path)
{
  struct dir *result = (dir*)xcalloc(sizeof(struct dir), 1);
  if (!result)
    return result;
/*
  result->pattern = (std::string*)malloc(strlen(path) + 3);
  if (!result->pattern) {
    errno = ENOMEM;
    return NULL;
  }
*/
  result->pattern.assign(path);
  result->pattern.append("\\*");
  result->handle = FindFirstFile(result->pattern.c_str(), &(result->find_data));
  if (result->handle == INVALID_HANDLE_VALUE) {
    //free(result->pattern);
    free(result);
    return NULL;
  }
  result->done = 0;
  return result;
}

struct entry *read_dir(struct dir *dir)
{
  if (dir->done)
    return NULL;
  strcpy(dir->entry.d_name, dir->find_data.cFileName);
  dir->entry.d_namlen = strlen(dir->entry.d_name);
  if (FindNextFile(dir->handle, &dir->find_data) == 0)
    dir->done = 1;
  return &dir->entry;
}

int close_dir(struct dir *dir)
{
  //string_release(dir->pattern);
  FindClose(dir->handle);
  free(dir);
  return 0;
}

#define DIR struct dir
#define dirent entry
#define opendir open_dir
#define readdir read_dir
#define closedir close_dir
#else
#include <dirent.h>
#endif

#if defined (_WIN32)
#define PATHSTEP ';'
#define SLASH '\\'
#else
#define PATHSTEP ':'
#define SLASH '/'
#endif

#ifdef __APPLE__
#define PATH "DYLD_LIBRARY_PATH"
#endif
#ifdef __linux__
#define PATH "LD_LIBRARY_PATH"
#endif
#ifdef _WIN32
#define PATH "PATH"
#endif
#ifdef _WIN64
#define PATH "PATH"
#endif

using namespace std;

void JavaTools::createJVM()
{
  JavaTools::createJVM("jar", true, 256, vector<string>(), vector<string>(), vector<string>());
}

void JavaTools::createJVM(string jarFolder)
{
  JavaTools::createJVM(jarFolder, true, 256, vector<string>(), vector<string>(), vector<string>());
}

void JavaTools::createJVM(int memory)
{
  JavaTools::createJVM("jar", true, memory, vector<string>(), vector<string>(), vector<string>());
}

void JavaTools::createJVM(bool headless)
{
  JavaTools::createJVM("jar", headless, 256, vector<string>(), vector<string>(), vector<string>());
}

void JavaTools::createJVM(bool headless, int memory)
{
  JavaTools::createJVM("jar", headless, memory, vector<string>(), vector<string>(), vector<string>());
}

void JavaTools::createJVM(string jarFolder, bool headless, int memory)
{
  JavaTools::createJVM(jarFolder, headless, memory, vector<string>(), vector<string>(), vector<string>());
}

/**
 * jarFolder is the name of the path to a directory of jars to be added to the classpath (default: jar)
 * headless turns headless on or off for JVM instantiation (default: on)
 * memory controls memory for instantiation of JVM in MB (default: 256)
 * extraClasspath is a list of additional classpath entries to include
 * extraJavaLibraryPath is a list of path entries to be appended to the JVM's java.library.path. ( default: .)
 * extraOptions is a list of any other desired arguments to the JVM, added to the jace::OptionList (e.g., "-verbose:jni")
 */
void JavaTools::createJVM(string jarFolder, bool headless, int memory,
  vector<string> extraClasspath, vector<string> extraJavaLibraryPath, vector<string> extraOptions)
{
  try {
    jace::StaticVmLoader* tmpLoader = (jace::StaticVmLoader*)jace::helper::getVmLoader();
    if(tmpLoader == NULL) {

      // initialize the Java virtual machine
      jace::OptionList list;
      jace::StaticVmLoader loader(JNI_VERSION_1_4);

      string classpath ("");

      DIR *d;
      struct dirent *dir;

//TODO: test jar/*
      // All .jar files in the jarFolder are added to the JVM's classpath
      d = opendir(jarFolder.c_str());

      if(d)
      {
        while ((dir = readdir(d)) != NULL)
        {
          string tmpName(dir->d_name);

          if(tmpName.find(".jar") != string::npos)
          {
            if(classpath.length() >= 1)
            {
              classpath += PATHSTEP;
            }
            classpath += jarFolder + SLASH + dir->d_name;
          }
        }

        closedir(d);
      }

      // All items in the extraClasspath are added to the JVM's classpath
      if(!extraClasspath.empty())
      {
        for(vector<string>::iterator it = extraClasspath.begin(); it != extraClasspath.end(); it++)
        {
          classpath += PATHSTEP;
          classpath += *it;
        }
      }

      //std::cout << "extraClasspath : " << extraClasspath << std::endl;
      //std::cout << "Classpath for JVM: " << classpath << std::endl;

      // Gets the system-specific path environment variable's contents (which will eventually be passed to java.library.path in this JVM)
      std::string pName = PATH;
      char * libPath;
      libPath = getenv(pName.c_str());
      std::string jLibPath("");
      if(libPath != NULL)
      {
        jLibPath = libPath;
      }

      // If no extra Java library path is specified, the current working directory is appended and passed to java.library.path.
      // Otherwise, each provided path is appended.
      if(extraJavaLibraryPath.empty())
      {
        if(jLibPath.length() >= 1)
        {
          jLibPath += PATHSTEP;
        }
        jLibPath += '.';
      }
      else
      {
        for(vector<string>::iterator it = extraJavaLibraryPath.begin(); it != extraJavaLibraryPath.end(); it++)
        {
          if(jLibPath.length() >= 1)
          {
           jLibPath += PATHSTEP;
          }
          jLibPath += *it;
        }
      }

      list.push_back(jace::ClassPath(classpath));
      list.push_back(jace::CustomOption("-Xcheck:jni"));

      // Int to string conversion
      std::string mem;
      std::stringstream out;
      out << memory;
      mem = out.str();

      list.push_back(jace::CustomOption("-Xmx" + mem + "m"));

      if (headless)
      {
        list.push_back(jace::CustomOption("-Djava.awt.headless=true"));
      }

      list.push_back(jace::CustomOption("-Djava.library.path=" + jLibPath));

      // All extra options are added as CustomOptions for JVM instantiation
      if (!extraOptions.empty()) {
        for (vector<string>::iterator it = extraOptions.begin(); it != extraOptions.end(); it++)
        {
          list.push_back(jace::CustomOption(*it));
        }
      }

      jace::helper::createVm(loader, list, false);
    }
  }
  catch (jace::JNIException& jniException) {
    std::cerr << "Exception creating JVM: " << jniException.what() << std::endl;
  }
}
<|endoftext|>


<commit_before>#include "RigidBody.h"

#include <stdexcept>

using Eigen::Isometry3d;
using Eigen::Matrix;
using Eigen::Vector3d;

using std::ostream;
using std::runtime_error;
using std::string;
using std::stringstream;
using std::vector;

RigidBody::RigidBody()
    : collision_filter_group(DrakeCollision::DEFAULT_GROUP),
      collision_filter_ignores(DrakeCollision::NONE_MASK),
      parent(nullptr) {
  robotnum = 0;
  position_num_start = 0;
  velocity_num_start = 0;
  body_index = 0;
  mass = 0.0;
  com = Vector3d::Zero();
  I << Matrix<double, TWIST_SIZE, TWIST_SIZE>::Zero();
}

const std::string& RigidBody::name() const { return name_; }

const std::string& RigidBody::model_name() const { return model_name_; }

int RigidBody::get_model_id() const { return robotnum; }

void RigidBody::set_model_id(int model_id) { robotnum = model_id; }

void RigidBody::setJoint(std::unique_ptr<DrakeJoint> new_joint) {
  this->joint = move(new_joint);
}

const DrakeJoint& RigidBody::getJoint() const {
  if (joint) {
    return (*joint);
  } else {
    throw runtime_error("ERROR: RigidBody::getJoint(): Rigid body \"" + name_
      + "\" in model " + model_name_ + " does not have a joint!");
  }
}

bool RigidBody::hasParent() const { return parent != nullptr; }

void RigidBody::addVisualElement(const DrakeShapes::VisualElement& element) {
  visual_elements.push_back(element);
}

const DrakeShapes::VectorOfVisualElements& RigidBody::getVisualElements()
    const {
  return visual_elements;
}

void RigidBody::setCollisionFilter(const DrakeCollision::bitmask& group,
                                   const DrakeCollision::bitmask& ignores) {
  setCollisionFilterGroup(group);
  setCollisionFilterIgnores(ignores);
}

bool RigidBody::adjacentTo(const RigidBody& other) const {
  return ((has_as_parent(other) && !(joint && joint->isFloating())) ||
          (other.has_as_parent(*this) &&
           !(other.joint && other.joint->isFloating())));
}

bool RigidBody::appendCollisionElementIdsFromThisBody(
    const string& group_name, vector<DrakeCollision::ElementId>& ids) const {
  auto group_ids_iter = collision_element_groups.find(group_name);
  if (group_ids_iter != collision_element_groups.end()) {
    ids.reserve(ids.size() + distance(group_ids_iter->second.begin(),
                                      group_ids_iter->second.end()));
    ids.insert(ids.end(), group_ids_iter->second.begin(),
               group_ids_iter->second.end());
    return true;
  } else {
    return false;
  }
}

bool RigidBody::appendCollisionElementIdsFromThisBody(
    vector<DrakeCollision::ElementId>& ids) const {
  ids.reserve(ids.size() + collision_element_ids.size());
  ids.insert(ids.end(), collision_element_ids.begin(),
             collision_element_ids.end());
  return true;
}

void RigidBody::ApplyTransformToJointFrame(
    const Eigen::Isometry3d& transform_body_to_joint) {
  I = transformSpatialInertia(transform_body_to_joint, I);
  for (auto& v : visual_elements) {
    v.SetLocalTransform(transform_body_to_joint * v.getLocalTransform());
  }
}

RigidBody::CollisionElement::CollisionElement(const CollisionElement& other)
    : DrakeCollision::Element(other) {}

RigidBody::CollisionElement::CollisionElement(
    const Isometry3d& T_element_to_link, const RigidBody* const body)
    : DrakeCollision::Element(T_element_to_link) {
  set_body(body);
}

RigidBody::CollisionElement::CollisionElement(
    const DrakeShapes::Geometry& geometry, const Isometry3d& T_element_to_link,
    const RigidBody* const body)
    : DrakeCollision::Element(geometry, T_element_to_link) {
  set_body(body);
}

RigidBody::CollisionElement* RigidBody::CollisionElement::clone() const {
  return new CollisionElement(*this);
}

bool RigidBody::CollisionElement::CollidesWith(
    const DrakeCollision::Element* other) const {
  auto other_rb = dynamic_cast<const RigidBody::CollisionElement*>(other);
  bool collides = true;
  if (other_rb != nullptr) {
    collides = get_body()->CollidesWith(*other_rb->get_body());
  }
  return collides;
}

ostream& operator<<(ostream& out, const RigidBody& b) {
  std::string parent_joint_name =
      b.hasParent() ? b.getJoint().getName() : "no parent joint";

  std::stringstream collision_element_str;
  collision_element_str << "[";
  for (size_t ii = 0; ii < b.collision_element_ids.size(); ii++) {
    collision_element_str << b.collision_element_ids[ii];
    if (ii < b.collision_element_ids.size() - 1) collision_element_str << ", ";
  }
  collision_element_str << "]";

  out << "RigidBody\n"
      << "  - link name: " << b.name_ << "\n"
      << "  - parent joint: " << parent_joint_name << "\n"
      << "  - Collision elements IDs: " << collision_element_str.str();

  return out;
}
<commit_msg>Temporary fix in RigidBody::CollisionElement constructor<commit_after>#include "RigidBody.h"

#include <stdexcept>

using Eigen::Isometry3d;
using Eigen::Matrix;
using Eigen::Vector3d;

using std::ostream;
using std::runtime_error;
using std::string;
using std::stringstream;
using std::vector;

RigidBody::RigidBody()
    : collision_filter_group(DrakeCollision::DEFAULT_GROUP),
      collision_filter_ignores(DrakeCollision::NONE_MASK),
      parent(nullptr) {
  robotnum = 0;
  position_num_start = 0;
  velocity_num_start = 0;
  body_index = 0;
  mass = 0.0;
  com = Vector3d::Zero();
  I << Matrix<double, TWIST_SIZE, TWIST_SIZE>::Zero();
}

const std::string& RigidBody::name() const { return name_; }

const std::string& RigidBody::model_name() const { return model_name_; }

int RigidBody::get_model_id() const { return robotnum; }

void RigidBody::set_model_id(int model_id) { robotnum = model_id; }

void RigidBody::setJoint(std::unique_ptr<DrakeJoint> new_joint) {
  this->joint = move(new_joint);
}

const DrakeJoint& RigidBody::getJoint() const {
  if (joint) {
    return (*joint);
  } else {
    throw runtime_error("ERROR: RigidBody::getJoint(): Rigid body \"" + name_
      + "\" in model " + model_name_ + " does not have a joint!");
  }
}

bool RigidBody::hasParent() const { return parent != nullptr; }

void RigidBody::addVisualElement(const DrakeShapes::VisualElement& element) {
  visual_elements.push_back(element);
}

const DrakeShapes::VectorOfVisualElements& RigidBody::getVisualElements()
    const {
  return visual_elements;
}

void RigidBody::setCollisionFilter(const DrakeCollision::bitmask& group,
                                   const DrakeCollision::bitmask& ignores) {
  setCollisionFilterGroup(group);
  setCollisionFilterIgnores(ignores);
}

bool RigidBody::adjacentTo(const RigidBody& other) const {
  return ((has_as_parent(other) && !(joint && joint->isFloating())) ||
          (other.has_as_parent(*this) &&
           !(other.joint && other.joint->isFloating())));
}

bool RigidBody::appendCollisionElementIdsFromThisBody(
    const string& group_name, vector<DrakeCollision::ElementId>& ids) const {
  auto group_ids_iter = collision_element_groups.find(group_name);
  if (group_ids_iter != collision_element_groups.end()) {
    ids.reserve(ids.size() + distance(group_ids_iter->second.begin(),
                                      group_ids_iter->second.end()));
    ids.insert(ids.end(), group_ids_iter->second.begin(),
               group_ids_iter->second.end());
    return true;
  } else {
    return false;
  }
}

bool RigidBody::appendCollisionElementIdsFromThisBody(
    vector<DrakeCollision::ElementId>& ids) const {
  ids.reserve(ids.size() + collision_element_ids.size());
  ids.insert(ids.end(), collision_element_ids.begin(),
             collision_element_ids.end());
  return true;
}

void RigidBody::ApplyTransformToJointFrame(
    const Eigen::Isometry3d& transform_body_to_joint) {
  I = transformSpatialInertia(transform_body_to_joint, I);
  for (auto& v : visual_elements) {
    v.SetLocalTransform(transform_body_to_joint * v.getLocalTransform());
  }
}

RigidBody::CollisionElement::CollisionElement(const CollisionElement& other)
    : DrakeCollision::Element(other) {}

RigidBody::CollisionElement::CollisionElement(
    const Isometry3d& T_element_to_link, const RigidBody* const body)
    : DrakeCollision::Element(T_element_to_link) {
  set_body(body);
}

RigidBody::CollisionElement::CollisionElement(
    const DrakeShapes::Geometry& geometry, const Isometry3d& T_element_to_link,
    const RigidBody* const body)
    : DrakeCollision::Element(geometry, T_element_to_link) {
  set_body(body);
  // This is a temporary hack to avoid having the user to set collision
  // elements to static when added to the world.
  // Collision elements should be set to static in a later Initialize() stage as
  // described in issue #2661.
  // TODO(amcastro-tri): remove this hack.
  if (body->name() == "world") set_static();
}

RigidBody::CollisionElement* RigidBody::CollisionElement::clone() const {
  return new CollisionElement(*this);
}

bool RigidBody::CollisionElement::CollidesWith(
    const DrakeCollision::Element* other) const {
  auto other_rb = dynamic_cast<const RigidBody::CollisionElement*>(other);
  bool collides = true;
  if (other_rb != nullptr) {
    collides = get_body()->CollidesWith(*other_rb->get_body());
  }
  return collides;
}

ostream& operator<<(ostream& out, const RigidBody& b) {
  std::string parent_joint_name =
      b.hasParent() ? b.getJoint().getName() : "no parent joint";

  std::stringstream collision_element_str;
  collision_element_str << "[";
  for (size_t ii = 0; ii < b.collision_element_ids.size(); ii++) {
    collision_element_str << b.collision_element_ids[ii];
    if (ii < b.collision_element_ids.size() - 1) collision_element_str << ", ";
  }
  collision_element_str << "]";

  out << "RigidBody\n"
      << "  - link name: " << b.name_ << "\n"
      << "  - parent joint: " << parent_joint_name << "\n"
      << "  - Collision elements IDs: " << collision_element_str.str();

  return out;
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "bench.h"

#include "chainparams.h"
#include "main.h"
#include "consensus/validation.h"

namespace block_bench {
#include "bench/data/block413567.raw.h"
}

// These are the two major time-sinks which happen after we have fully received
// a block off the wire, but before we can relay the block on to peers using
// compact block relay.

static void DeserializeBlockTest(benchmark::State& state)
{
    CDataStream stream((const char*)block_bench::block413567,
            (const char*)&block_bench::block413567[sizeof(block_bench::block413567)],
            SER_NETWORK, PROTOCOL_VERSION);
    char a;
    stream.write(&a, 1); // Prevent compaction

    while (state.KeepRunning()) {
        CBlock block;
        stream >> block;
        assert(stream.Rewind(sizeof(block_bench::block413567)));
    }
}

static void DeserializeAndCheckBlockTest(benchmark::State& state)
{
    CDataStream stream((const char*)block_bench::block413567,
            (const char*)&block_bench::block413567[sizeof(block_bench::block413567)],
            SER_NETWORK, PROTOCOL_VERSION);
    char a;
    stream.write(&a, 1); // Prevent compaction

    Consensus::Params params = Params(CBaseChainParams::MAIN).GetConsensus();

    while (state.KeepRunning()) {
        CBlock block; // Note that CBlock caches its checked state, so we need to recreate it here
        stream >> block;
        assert(stream.Rewind(sizeof(block_bench::block413567)));

        CValidationState validationState;
        assert(CheckBlock(block, validationState, params));
    }
}

BENCHMARK(DeserializeBlockTest);
BENCHMARK(DeserializeAndCheckBlockTest);
<commit_msg>[bench] Avoid function call arguments which are pointers to uninitialized values<commit_after>// Copyright (c) 2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "bench.h"

#include "chainparams.h"
#include "main.h"
#include "consensus/validation.h"

namespace block_bench {
#include "bench/data/block413567.raw.h"
}

// These are the two major time-sinks which happen after we have fully received
// a block off the wire, but before we can relay the block on to peers using
// compact block relay.

static void DeserializeBlockTest(benchmark::State& state)
{
    CDataStream stream((const char*)block_bench::block413567,
            (const char*)&block_bench::block413567[sizeof(block_bench::block413567)],
            SER_NETWORK, PROTOCOL_VERSION);
    char a = '\0';
    stream.write(&a, 1); // Prevent compaction

    while (state.KeepRunning()) {
        CBlock block;
        stream >> block;
        assert(stream.Rewind(sizeof(block_bench::block413567)));
    }
}

static void DeserializeAndCheckBlockTest(benchmark::State& state)
{
    CDataStream stream((const char*)block_bench::block413567,
            (const char*)&block_bench::block413567[sizeof(block_bench::block413567)],
            SER_NETWORK, PROTOCOL_VERSION);
    char a = '\0';
    stream.write(&a, 1); // Prevent compaction

    Consensus::Params params = Params(CBaseChainParams::MAIN).GetConsensus();

    while (state.KeepRunning()) {
        CBlock block; // Note that CBlock caches its checked state, so we need to recreate it here
        stream >> block;
        assert(stream.Rewind(sizeof(block_bench::block413567)));

        CValidationState validationState;
        assert(CheckBlock(block, validationState, params));
    }
}

BENCHMARK(DeserializeBlockTest);
BENCHMARK(DeserializeAndCheckBlockTest);
<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// schema.cpp
//
// Identification: src/catalog/schema.cpp
//
// Copyright (c) 2015-16, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include <algorithm>
#include <sstream>
#include <iostream>

#include "catalog/schema.h"
#include "common/macros.h"

namespace peloton {
namespace catalog {

// Helper function for creating TupleSchema
void Schema::CreateTupleSchema(const std::vector<ValueType> &column_types,
                               const std::vector<oid_t> &column_lengths,
                               const std::vector<std::string> &column_names,
                               const std::vector<bool> &is_inlined) {
  bool tup_is_inlined = true;
  oid_t num_columns = column_types.size();
  oid_t column_offset = 0;

  for (oid_t column_itr = 0; column_itr < num_columns; column_itr++) {
    Column column(column_types[column_itr], column_lengths[column_itr],
                  column_names[column_itr], is_inlined[column_itr],
                  column_offset);

    column_offset += column.fixed_length;

    columns.push_back(std::move(column));

    if (is_inlined[column_itr] == false) {
      tup_is_inlined = false;
      uninlined_columns.push_back(column_itr);
    }
  }

  length = column_offset;
  tuple_is_inlined = tup_is_inlined;

  column_count = columns.size();
  uninlined_column_count = uninlined_columns.size();
}

// Construct schema from vector of Column
Schema::Schema(const std::vector<Column> &columns)
    : length(0), tuple_is_inlined(false) {
  oid_t column_count = columns.size();

  std::vector<ValueType> column_types;
  std::vector<oid_t> column_lengths;
  std::vector<std::string> column_names;
  std::vector<bool> is_inlined;

  for (oid_t column_itr = 0; column_itr < column_count; column_itr++) {
    column_types.push_back(columns[column_itr].column_type);

    if (columns[column_itr].is_inlined)
      column_lengths.push_back(columns[column_itr].fixed_length);
    else
      column_lengths.push_back(columns[column_itr].variable_length);

    column_names.push_back(columns[column_itr].column_name);
    is_inlined.push_back(columns[column_itr].is_inlined);
  }

  CreateTupleSchema(column_types, column_lengths, column_names, is_inlined);

  // Add constraints
  for (oid_t column_itr = 0; column_itr < column_count; column_itr++) {
    for (auto constraint : columns[column_itr].constraints)
      AddConstraint(column_itr, constraint);
  }
}

// Copy schema
std::shared_ptr<const Schema> Schema::CopySchema(
    const std::shared_ptr<const Schema> &schema) {
  oid_t column_count = schema->GetColumnCount();
  std::vector<oid_t> set;

  for (oid_t column_itr = 0; column_itr < column_count; column_itr++)
    set.push_back(column_itr);

  return CopySchema(schema, set);
}

// Copy subset of columns in the given schema
std::shared_ptr<const Schema> Schema::CopySchema(
    const std::shared_ptr<const Schema> &schema,
    const std::vector<oid_t> &set) {
  oid_t column_count = schema->GetColumnCount();
  std::vector<Column> columns;

  for (oid_t column_itr = 0; column_itr < column_count; column_itr++) {
    // If column exists in set
    if (std::find(set.begin(), set.end(), column_itr) != set.end()) {
      columns.push_back(schema->columns[column_itr]);
    }
  }

  return std::shared_ptr<Schema>(new Schema(columns));
}

// Backward compatible for raw pointers
// Copy schema
Schema *Schema::CopySchema(const Schema *schema) {
  oid_t column_count = schema->GetColumnCount();
  std::vector<oid_t> set;

  for (oid_t column_itr = 0; column_itr < column_count; column_itr++)
    set.push_back(column_itr);

  return CopySchema(schema, set);
}

/*
 * CopySchema() - Copies the schema into a new schema object with index_list
 *                as indices to copy
 *
 * This function essentially does a "Gathering" operation, in a sense that it
 * collects columns indexed by elemenys inside index_list in the given order
 * and store them inside a newly created schema object
 *
 * If there are duplicates in index_list then the columns will be duplicated
 * (i.e. no dup checking will be done)
 *
 * If the indices inside index_list >= the size of the column list then behavior
 * is undefined (and is likely to crash)
 *
 * The returned schema is created by new operator, and the caller is responsible
 * for destroying it.
 */
Schema *Schema::CopySchema(const Schema *schema,
                           const std::vector<oid_t> &index_list) {
  std::vector<Column> column_list{};

  // Reserve some space to avoid multiple malloc() calls
  // But for future push_back() this is not optimized since the
  // memory chunk may not be properly sized and aligned
  column_list.reserve(index_list.size());

  // For each column index, push the column
  for(oid_t column_index : index_list) {
    column_list.push_back(schema->columns[column_index]);
  }

  Schema *ret_schema = new Schema(column_list);

  return ret_schema;
}

/*
 * FilterSchema() - Returns a filtered schema using the given base schema
 *                  and index array in the argument
 *
 * This function performs a "Filtering" operation on the schema given in the
 * argument using the index list into a newly created schema object. The
 * returned schema remains the order inside the base schema, no matter how
 * indices are arranged in the index list.
 *
 * If there are duplicated indices in the set, it is guaranteed that only
 * one column will be copied into the returned schema. This is achieved by
 * only traversing the underlying schema once and searches for the column
 * index inside the index list
 *
 * Please note that the new schame is created on the heap, and the caller
 * is responsible for destroying it.
 */
Schema *Schema::FilterSchema(const Schema *schema,
                             const std::vector<oid_t> &set) {
  oid_t column_count = schema->GetColumnCount();
  std::vector<Column> columns;

  // It could only be smaller but not larger, here we use
  // the size of the set (might have duplication) as an estimation
  columns.reserve(set.size());

  // For each column in the base schema, if the column id
  // appears inside the set then push it into the column list
  // for later construction of the new schema
  for (oid_t column_itr = 0; column_itr < column_count; column_itr++) {
    // If column exists in set
    if (std::find(set.begin(), set.end(), column_itr) != set.end()) {
      columns.push_back(schema->columns[column_itr]);
    }
  }

  Schema *ret_schema = new Schema(columns);

  return ret_schema;
}

// Append two schema objects
Schema *Schema::AppendSchema(Schema *first, Schema *second) {
  return AppendSchemaPtrList({first, second});
}

// Append subset of columns in the two given schemas
Schema *Schema::AppendSchema(Schema *first, std::vector<oid_t> &first_set,
                             Schema *second, std::vector<oid_t> &second_set) {
  const std::vector<Schema *> schema_list({first, second});
  const std::vector<std::vector<oid_t>> subsets({first_set, second_set});
  return AppendSchemaPtrList(schema_list, subsets);
}

// Append given schemas.
Schema *Schema::AppendSchemaList(std::vector<Schema> &schema_list) {
  // All we do here is convert vector<Schema> to vector<Schema *>.
  // This is a convenience function.
  std::vector<Schema *> schema_ptr_list;
  for (unsigned int i = 0; i < schema_list.size(); i++) {
    schema_ptr_list.push_back(&schema_list[i]);
  }
  return AppendSchemaPtrList(schema_ptr_list);
}

// Append given schemas.
Schema *Schema::AppendSchemaPtrList(const std::vector<Schema *> &schema_list) {
  std::vector<std::vector<oid_t>> subsets;

  for (unsigned int i = 0; i < schema_list.size(); i++) {
    unsigned int column_count = schema_list[i]->GetColumnCount();
    std::vector<oid_t> subset;
    for (oid_t column_itr = 0; column_itr < column_count; column_itr++) {
      subset.push_back(column_itr);
    }
    subsets.push_back(subset);
  }

  return AppendSchemaPtrList(schema_list, subsets);
}

// Append subsets of columns in the given schemas.
Schema *Schema::AppendSchemaPtrList(
    const std::vector<Schema *> &schema_list,
    const std::vector<std::vector<oid_t>> &subsets) {
  PL_ASSERT(schema_list.size() == subsets.size());

  std::vector<Column> columns;
  for (unsigned int i = 0; i < schema_list.size(); i++) {
    Schema *schema = schema_list[i];
    const std::vector<oid_t> &subset = subsets[i];
    unsigned int column_count = schema->GetColumnCount();

    for (oid_t column_itr = 0; column_itr < column_count; column_itr++) {
      // If column exists in set.
      if (std::find(subset.begin(), subset.end(), column_itr) != subset.end()) {
        columns.push_back(schema->columns[column_itr]);
      }
    }
  }

  Schema *ret_schema = new Schema(columns);

  return ret_schema;
}

const std::string Schema::GetInfo() const {
  std::ostringstream os;

  os << "\tSchema :: "
     << " column_count = " << column_count
     << " is_inlined = " << tuple_is_inlined << ","
     << " length = " << length << ","
     << " uninlined_column_count = " << uninlined_column_count << std::endl;

  for (oid_t column_itr = 0; column_itr < column_count; column_itr++) {
    os << "\t Column " << column_itr << " :: " << columns[column_itr];
  }

  return os.str();
}

// Compare two schemas
bool Schema::operator==(const Schema &other) const {
  if (other.GetColumnCount() != GetColumnCount() ||
      other.GetUninlinedColumnCount() != GetUninlinedColumnCount() ||
      other.IsInlined() != IsInlined()) {
    return false;
  }

  for (oid_t column_itr = 0; column_itr < other.GetColumnCount();
       column_itr++) {
    const Column &column_info = other.GetColumn(column_itr);
    const Column &other_column_info = GetColumn(column_itr);

    if (column_info != other_column_info) {
      return false;
    }
  }

  return true;
}

bool Schema::operator!=(const Schema &other) const { return !(*this == other); }

}  // End catalog namespace
}  // End peloton namespace
<commit_msg>Adding an assert() in Schema<commit_after>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// schema.cpp
//
// Identification: src/catalog/schema.cpp
//
// Copyright (c) 2015-16, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include <algorithm>
#include <sstream>
#include <iostream>

#include "catalog/schema.h"
#include "common/macros.h"

namespace peloton {
namespace catalog {

// Helper function for creating TupleSchema
void Schema::CreateTupleSchema(const std::vector<ValueType> &column_types,
                               const std::vector<oid_t> &column_lengths,
                               const std::vector<std::string> &column_names,
                               const std::vector<bool> &is_inlined) {
  bool tup_is_inlined = true;
  oid_t num_columns = column_types.size();
  oid_t column_offset = 0;

  for (oid_t column_itr = 0; column_itr < num_columns; column_itr++) {
    Column column(column_types[column_itr], column_lengths[column_itr],
                  column_names[column_itr], is_inlined[column_itr],
                  column_offset);

    column_offset += column.fixed_length;

    columns.push_back(std::move(column));

    if (is_inlined[column_itr] == false) {
      tup_is_inlined = false;
      uninlined_columns.push_back(column_itr);
    }
  }

  length = column_offset;
  tuple_is_inlined = tup_is_inlined;

  column_count = columns.size();
  uninlined_column_count = uninlined_columns.size();
}

// Construct schema from vector of Column
Schema::Schema(const std::vector<Column> &columns)
    : length(0), tuple_is_inlined(false) {
  oid_t column_count = columns.size();

  std::vector<ValueType> column_types;
  std::vector<oid_t> column_lengths;
  std::vector<std::string> column_names;
  std::vector<bool> is_inlined;

  for (oid_t column_itr = 0; column_itr < column_count; column_itr++) {
    column_types.push_back(columns[column_itr].column_type);

    if (columns[column_itr].is_inlined)
      column_lengths.push_back(columns[column_itr].fixed_length);
    else
      column_lengths.push_back(columns[column_itr].variable_length);

    column_names.push_back(columns[column_itr].column_name);
    is_inlined.push_back(columns[column_itr].is_inlined);
  }

  CreateTupleSchema(column_types, column_lengths, column_names, is_inlined);

  // Add constraints
  for (oid_t column_itr = 0; column_itr < column_count; column_itr++) {
    for (auto constraint : columns[column_itr].constraints)
      AddConstraint(column_itr, constraint);
  }
}

// Copy schema
std::shared_ptr<const Schema> Schema::CopySchema(
    const std::shared_ptr<const Schema> &schema) {
  oid_t column_count = schema->GetColumnCount();
  std::vector<oid_t> set;

  for (oid_t column_itr = 0; column_itr < column_count; column_itr++)
    set.push_back(column_itr);

  return CopySchema(schema, set);
}

// Copy subset of columns in the given schema
std::shared_ptr<const Schema> Schema::CopySchema(
    const std::shared_ptr<const Schema> &schema,
    const std::vector<oid_t> &set) {
  oid_t column_count = schema->GetColumnCount();
  std::vector<Column> columns;

  for (oid_t column_itr = 0; column_itr < column_count; column_itr++) {
    // If column exists in set
    if (std::find(set.begin(), set.end(), column_itr) != set.end()) {
      columns.push_back(schema->columns[column_itr]);
    }
  }

  return std::shared_ptr<Schema>(new Schema(columns));
}

// Backward compatible for raw pointers
// Copy schema
Schema *Schema::CopySchema(const Schema *schema) {
  oid_t column_count = schema->GetColumnCount();
  std::vector<oid_t> set;

  for (oid_t column_itr = 0; column_itr < column_count; column_itr++)
    set.push_back(column_itr);

  return CopySchema(schema, set);
}

/*
 * CopySchema() - Copies the schema into a new schema object with index_list
 *                as indices to copy
 *
 * This function essentially does a "Gathering" operation, in a sense that it
 * collects columns indexed by elemenys inside index_list in the given order
 * and store them inside a newly created schema object
 *
 * If there are duplicates in index_list then the columns will be duplicated
 * (i.e. no dup checking will be done)
 *
 * If the indices inside index_list >= the size of the column list then behavior
 * is undefined (and is likely to crash)
 *
 * The returned schema is created by new operator, and the caller is responsible
 * for destroying it.
 */
Schema *Schema::CopySchema(const Schema *schema,
                           const std::vector<oid_t> &index_list) {
  std::vector<Column> column_list{};

  // Reserve some space to avoid multiple malloc() calls
  // But for future push_back() this is not optimized since the
  // memory chunk may not be properly sized and aligned
  column_list.reserve(index_list.size());

  // For each column index, push the column
  for(oid_t column_index : index_list) {
    // Make sure the index does not refer to invalid element
    PL_ASSERT(column_index < schema->columns.size());

    column_list.push_back(schema->columns[column_index]);
  }

  Schema *ret_schema = new Schema(column_list);

  return ret_schema;
}

/*
 * FilterSchema() - Returns a filtered schema using the given base schema
 *                  and index array in the argument
 *
 * This function performs a "Filtering" operation on the schema given in the
 * argument using the index list into a newly created schema object. The
 * returned schema remains the order inside the base schema, no matter how
 * indices are arranged in the index list.
 *
 * If there are duplicated indices in the set, it is guaranteed that only
 * one column will be copied into the returned schema. This is achieved by
 * only traversing the underlying schema once and searches for the column
 * index inside the index list
 *
 * Please note that the new schame is created on the heap, and the caller
 * is responsible for destroying it.
 */
Schema *Schema::FilterSchema(const Schema *schema,
                             const std::vector<oid_t> &set) {
  oid_t column_count = schema->GetColumnCount();
  std::vector<Column> columns;

  // It could only be smaller but not larger, here we use
  // the size of the set (might have duplication) as an estimation
  columns.reserve(set.size());

  // For each column in the base schema, if the column id
  // appears inside the set then push it into the column list
  // for later construction of the new schema
  for (oid_t column_itr = 0; column_itr < column_count; column_itr++) {
    // If column exists in set
    if (std::find(set.begin(), set.end(), column_itr) != set.end()) {
      columns.push_back(schema->columns[column_itr]);
    }
  }

  Schema *ret_schema = new Schema(columns);

  return ret_schema;
}

// Append two schema objects
Schema *Schema::AppendSchema(Schema *first, Schema *second) {
  return AppendSchemaPtrList({first, second});
}

// Append subset of columns in the two given schemas
Schema *Schema::AppendSchema(Schema *first, std::vector<oid_t> &first_set,
                             Schema *second, std::vector<oid_t> &second_set) {
  const std::vector<Schema *> schema_list({first, second});
  const std::vector<std::vector<oid_t>> subsets({first_set, second_set});
  return AppendSchemaPtrList(schema_list, subsets);
}

// Append given schemas.
Schema *Schema::AppendSchemaList(std::vector<Schema> &schema_list) {
  // All we do here is convert vector<Schema> to vector<Schema *>.
  // This is a convenience function.
  std::vector<Schema *> schema_ptr_list;
  for (unsigned int i = 0; i < schema_list.size(); i++) {
    schema_ptr_list.push_back(&schema_list[i]);
  }
  return AppendSchemaPtrList(schema_ptr_list);
}

// Append given schemas.
Schema *Schema::AppendSchemaPtrList(const std::vector<Schema *> &schema_list) {
  std::vector<std::vector<oid_t>> subsets;

  for (unsigned int i = 0; i < schema_list.size(); i++) {
    unsigned int column_count = schema_list[i]->GetColumnCount();
    std::vector<oid_t> subset;
    for (oid_t column_itr = 0; column_itr < column_count; column_itr++) {
      subset.push_back(column_itr);
    }
    subsets.push_back(subset);
  }

  return AppendSchemaPtrList(schema_list, subsets);
}

// Append subsets of columns in the given schemas.
Schema *Schema::AppendSchemaPtrList(
    const std::vector<Schema *> &schema_list,
    const std::vector<std::vector<oid_t>> &subsets) {
  PL_ASSERT(schema_list.size() == subsets.size());

  std::vector<Column> columns;
  for (unsigned int i = 0; i < schema_list.size(); i++) {
    Schema *schema = schema_list[i];
    const std::vector<oid_t> &subset = subsets[i];
    unsigned int column_count = schema->GetColumnCount();

    for (oid_t column_itr = 0; column_itr < column_count; column_itr++) {
      // If column exists in set.
      if (std::find(subset.begin(), subset.end(), column_itr) != subset.end()) {
        columns.push_back(schema->columns[column_itr]);
      }
    }
  }

  Schema *ret_schema = new Schema(columns);

  return ret_schema;
}

const std::string Schema::GetInfo() const {
  std::ostringstream os;

  os << "\tSchema :: "
     << " column_count = " << column_count
     << " is_inlined = " << tuple_is_inlined << ","
     << " length = " << length << ","
     << " uninlined_column_count = " << uninlined_column_count << std::endl;

  for (oid_t column_itr = 0; column_itr < column_count; column_itr++) {
    os << "\t Column " << column_itr << " :: " << columns[column_itr];
  }

  return os.str();
}

// Compare two schemas
bool Schema::operator==(const Schema &other) const {
  if (other.GetColumnCount() != GetColumnCount() ||
      other.GetUninlinedColumnCount() != GetUninlinedColumnCount() ||
      other.IsInlined() != IsInlined()) {
    return false;
  }

  for (oid_t column_itr = 0; column_itr < other.GetColumnCount();
       column_itr++) {
    const Column &column_info = other.GetColumn(column_itr);
    const Column &other_column_info = GetColumn(column_itr);

    if (column_info != other_column_info) {
      return false;
    }
  }

  return true;
}

bool Schema::operator!=(const Schema &other) const { return !(*this == other); }

}  // End catalog namespace
}  // End peloton namespace
<|endoftext|>


<commit_before>#pragma once

#include <memory>
#include <vector>

#include "attribute.hpp"
#include "common.hpp"
#include "error/handler.hpp"
#include "filter.hpp"
#include "frontend.hpp"
#include "keyword.hpp"
#include "keyword/message.hpp"
#include "keyword/severity.hpp"
#include "keyword/timestamp.hpp"
#include "utils/unique.hpp"

namespace blackhole {

class logger_base_t {
    bool m_enabled;

protected:
    filter_t m_filter;
    log::exception_handler_t m_exception_handler;

    std::vector<std::unique_ptr<base_frontend_t>> m_frontends;

    log::attributes_t m_global_attributes;

public:
    logger_base_t() :
        m_enabled(true),
        m_filter(default_filter_t::instance()),
        m_exception_handler(log::default_exception_handler_t())
    {}

    // Blaming GCC 4.4 - it needs explicit move constructor definition,
    // cause it cannot define default move constructor for derived class.
    logger_base_t(logger_base_t&& other) {
        m_enabled = other.m_enabled;
        m_filter = std::move(other.m_filter);
        m_exception_handler = std::move(other.m_exception_handler);
        m_frontends = std::move(other.m_frontends);
        m_global_attributes = std::move(other.m_global_attributes);
    }

    bool enabled() const {
        return m_enabled;
    }

    void enable() {
        m_enabled = true;
    }

    void disable() {
        m_enabled = false;
    }

    void set_filter(filter_t&& filter) {
        m_filter = std::move(filter);
    }

    void add_attribute(const log::attribute_pair_t& attr) {
        m_global_attributes.insert(attr);
    }

    void add_frontend(std::unique_ptr<base_frontend_t> frontend) {
        m_frontends.push_back(std::move(frontend));
    }

    void set_exception_handler(log::exception_handler_t&& handler) {
        m_exception_handler = std::move(handler);
    }

    log::record_t open_record() const {
        return open_record(log::attributes_t());
    }

    log::record_t open_record(log::attribute_pair_t&& local_attribute) const {
        return open_record(log::attributes_t({ std::move(local_attribute) }));
    }

    log::record_t open_record(log::attributes_t&& local_attributes) const {
        if (enabled() && !m_frontends.empty()) {
            log::attributes_t attributes = merge({
                // universe_attributes          // Program global.
                // thread_attributes            // Thread local.
                m_global_attributes,            // Logger object specific.
                get_event_attributes(),         // Event specific, e.g. timestamp.
                std::move(local_attributes)     // Any user attributes.
            });

            if (m_filter(attributes)) {
                log::record_t record;
                record.attributes = std::move(attributes);
                return record;
            }
        }

        return log::record_t();
    }

    void push(log::record_t&& record) const {
        for (auto it = m_frontends.begin(); it != m_frontends.end(); ++it) {
            try {
                const std::unique_ptr<base_frontend_t>& frontend = *it;
                frontend->handle(record);
            } catch (...) {
                m_exception_handler();
            }
        }
    }

private:
    log::attributes_t get_event_attributes() const {
        log::attributes_t attributes = {
            keyword::timestamp() = std::time(nullptr)
        };
        return attributes;
    }
};

template<typename Level>
class verbose_logger_t : public logger_base_t {
    typedef Level level_type;

public:
    verbose_logger_t() :
        logger_base_t()
    {}

    // GCC4.4 doesn't create default copy/move constructor for derived classes. It's a bug.
    verbose_logger_t(verbose_logger_t&& other) :
        logger_base_t(std::move(other))
    {}

    log::record_t open_record(Level level) const {
        log::attributes_t attributes = { keyword::severity<Level>() = level };
        return logger_base_t::open_record(std::move(attributes));
    }
};

} // namespace blackhole
<commit_msg>Logger now automatically assigns thread attributes.<commit_after>#pragma once

#include <memory>
#include <vector>

#include "attribute.hpp"
#include "common.hpp"
#include "error/handler.hpp"
#include "filter.hpp"
#include "frontend.hpp"
#include "keyword.hpp"
#include "keyword/message.hpp"
#include "keyword/severity.hpp"
#include "keyword/timestamp.hpp"
#include "keyword/thread.hpp"
#include "utils/unique.hpp"

namespace blackhole {

class logger_base_t {
    bool m_enabled;

protected:
    filter_t m_filter;
    log::exception_handler_t m_exception_handler;

    std::vector<std::unique_ptr<base_frontend_t>> m_frontends;

    log::attributes_t m_global_attributes;

public:
    logger_base_t() :
        m_enabled(true),
        m_filter(default_filter_t::instance()),
        m_exception_handler(log::default_exception_handler_t())
    {}

    // Blaming GCC 4.4 - it needs explicit move constructor definition,
    // cause it cannot define default move constructor for derived class.
    logger_base_t(logger_base_t&& other) {
        m_enabled = other.m_enabled;
        m_filter = std::move(other.m_filter);
        m_exception_handler = std::move(other.m_exception_handler);
        m_frontends = std::move(other.m_frontends);
        m_global_attributes = std::move(other.m_global_attributes);
    }

    bool enabled() const {
        return m_enabled;
    }

    void enable() {
        m_enabled = true;
    }

    void disable() {
        m_enabled = false;
    }

    void set_filter(filter_t&& filter) {
        m_filter = std::move(filter);
    }

    void add_attribute(const log::attribute_pair_t& attr) {
        m_global_attributes.insert(attr);
    }

    void add_frontend(std::unique_ptr<base_frontend_t> frontend) {
        m_frontends.push_back(std::move(frontend));
    }

    void set_exception_handler(log::exception_handler_t&& handler) {
        m_exception_handler = std::move(handler);
    }

    log::record_t open_record() const {
        return open_record(log::attributes_t());
    }

    log::record_t open_record(log::attribute_pair_t&& local_attribute) const {
        return open_record(log::attributes_t({ std::move(local_attribute) }));
    }

    log::record_t open_record(log::attributes_t&& local_attributes) const {
        if (enabled() && !m_frontends.empty()) {
            log::attributes_t attributes = merge({
                // universe_attributes          // Program global.
                get_thread_attributes(),        // Thread local.
                m_global_attributes,            // Logger object specific.
                get_event_attributes(),         // Event specific, e.g. timestamp.
                std::move(local_attributes)     // Any user attributes.
            });

            if (m_filter(attributes)) {
                log::record_t record;
                record.attributes = std::move(attributes);
                return record;
            }
        }

        return log::record_t();
    }

    void push(log::record_t&& record) const {
        for (auto it = m_frontends.begin(); it != m_frontends.end(); ++it) {
            try {
                const std::unique_ptr<base_frontend_t>& frontend = *it;
                frontend->handle(record);
            } catch (...) {
                m_exception_handler();
            }
        }
    }

private:
    log::attributes_t get_event_attributes() const {
        log::attributes_t attributes = {
            keyword::timestamp() = std::time(nullptr)
        };
        return attributes;
    }

    log::attributes_t get_thread_attributes() const {
        log::attributes_t attributes = {
            keyword::tid() = this_thread::get_id<std::string>()
        };
        return attributes;
    }
};

template<typename Level>
class verbose_logger_t : public logger_base_t {
    typedef Level level_type;

public:
    verbose_logger_t() :
        logger_base_t()
    {}

    // GCC4.4 doesn't create default copy/move constructor for derived classes. It's a bug.
    verbose_logger_t(verbose_logger_t&& other) :
        logger_base_t(std::move(other))
    {}

    log::record_t open_record(Level level) const {
        log::attributes_t attributes = { keyword::severity<Level>() = level };
        return logger_base_t::open_record(std::move(attributes));
    }
};

} // namespace blackhole
<|endoftext|>