<commit_before>#ifndef DUNE_STUFF_GRID_PROVIDER_CUBE_HH
#define DUNE_STUFF_GRID_PROVIDER_CUBE_HH

// dune-common
#include <dune/common/parametertree.hh>
#include <dune/common/shared_ptr.hh>
#include <dune/common/exceptions.hh>
#include <dune/common/fvector.hh>

// dune-grid
#include <dune/grid/utility/structuredgridfactory.hh>
#include <dune/grid/yaspgrid.hh>
#include <dune/grid/alugrid.hh>
#include <dune/grid/sgrid.hh>
#include <dune/grid/common/mcmgmapper.hh>
#include <dune/grid/io/file/vtk/vtkwriter.hh>

namespace Dune
{

namespace Stuff
{

namespace Grid
{

namespace Provider
{

/**
  \brief  Creates a grid of a cube in various dimensions.

          Default implementation using the Dune::StructuredGridFactory to create a grid of a cube in 1, 2 or 3
          dimensions. Tested with

 \c YASPGRID, \c variant 1, dim = 1, 2, 3,

 \c SGRID, \c variant 1, dim = 1, 2, 3,

 \c ALUGRID_SIMPLEX, \c variant 2, dim = 2, 3,

 \c ALUGRID_CONFORM, \c variant 2, dim = 2, 2 and

 \c ALUGRID_CUBE, \c variant 1, dim = 2, 3.

  \tparam GridImp
          Type of the underlying grid.
  \tparam variant
          Type of the codim 0 elements:

\c 1: cubes

2: simplices

  **/
template< typename GridImp, int variant >
class GenericCube
{
public:
  //! Type of the provided grid.
  typedef GridImp GridType;

  //! Dimension of the provided grid.
  static const int dim = GridType::dimension;

  //! Type of the grids coordinates.
  typedef Dune::FieldVector< typename GridType::ctype, dim > CoordinateType;

  //! Unique identifier: \c stuff.grid.provider.cube
  static const std::string id;

  /**
    \brief      Creates a cube.
    \param[in]  paramTree
                A Dune::ParameterTree containing

 the following keys directly or

 a subtree named Cube::id, containing the following keys.

                The actual keys are:

 \c lowerLeft: \a double that is used as a lower left corner in each dimension.

 \c upperRight: \a double that is used as a upper right corner in each dimension.

    **/
  GenericCube(const Dune::ParameterTree& paramTree)
  {
    // get correct parameters
    Dune::ParameterTree* paramsP = const_cast< Dune::ParameterTree* >(&paramTree);
    if (paramsP->hasSub(id))
      paramsP = &(paramsP->sub(id));
    const Dune::ParameterTree& params = const_cast< const Dune::ParameterTree& >(*paramsP);
    const double lowerLeft = params.get("lowerLeft", 0.0);
    const double upperRight = params.get("upperRight", 1.0);
    const int level = params.get("level", 1);
    buildGrid(CoordinateType(lowerLeft), CoordinateType(upperRight), level);
  } // Cube(const Dune::ParameterTree& paramTree)

  /**
    \brief      Creates a cube.
    \param[in]  lowerLeft
                A vector that is used as a lower left corner.
    \param[in]  upperRight
                A vector that is used as a upper right corner.
    **/
  GenericCube(const CoordinateType& lowerLeft, const CoordinateType& upperRight, const int level = 1)
  {
    buildGrid(lowerLeft, upperRight, level);
  }

  /**
    \brief      Creates a cube.
    \param[in]  lowerLeft
                A double that is used as a lower left corner in each dimension.
    \param[in]  upperRight
                A double that is used as a upper right corner in each dimension.
    **/
  GenericCube(double lowerLeft, double upperRight, const int level = 1)
  {
    buildGrid(CoordinateType(lowerLeft), CoordinateType(upperRight), level);
  }

  /**
    \brief  Provides access to the created grid.
    \return Reference to the grid.
    **/
  GridType& grid()
  {
    return *grid_;
  }

  const GridType& grid() const
  {
    return *grid_;
  }

private:
  template< int dim >
  struct P0Layout
  {
    bool contains(Dune::GeometryType& geometry)
    {
      if (geometry.dim() == dim)
        return true;
      return false;
    }
  }; // layout class for codim 0 mapper

  /**
    \brief      Visualizes the grid using Dune::VTKWriter.
    \param[in]  paramTree
                A Dune::ParameterTree containing

 the following keys directly or

 a subtree named Cube::id, containing the following keys, or

 a subtree named Cube::id + \c .visualize, containing the following keys.

                The actual keys are:

 \c grid: if specified, filename of the vtk file in which the grid which can be obtained via
                  grid() is visualized (\a if \a not \a specified: \a no \a visualization).

 \c mdGrid: if specified, filename of the vtk file in which the multidomain grid which can be
                  obtained via mdGrid() is visualized (\a if \a not \a specified: \a no \a visualization).

    **/
public:
  void visualize(Dune::ParameterTree& paramTree)
  {
    const std::string localId = "visualize";
    // get correct parameters
    Dune::ParameterTree* paramsP = &paramTree;
    if (paramsP->hasSub(id))
      paramsP = &(paramsP->sub(id));
    if (paramsP->hasSub(localId))
      paramsP = &(paramsP->sub(localId));
    Dune::ParameterTree& params = *paramsP;
    // check for grid visualization
    if (params.hasKey("grid")) {
      const std::string filenameGrid = params.get("grid", id + ".grid");
      // grid view
      typedef GridImp GridType;
      GridType& grid = this->grid();
      typedef typename GridType::LeafGridView GridView;
      GridView gridView = grid.leafView();
      // mapper
      Dune::LeafMultipleCodimMultipleGeomTypeMapper< GridType, P0Layout > mapper(grid);
      std::vector< double > data(mapper.size());
      // walk the grid
      typedef typename GridView::template Codim<0>::Iterator ElementIterator;
      typedef typename GridView::template Codim<0>::Entity ElementType;
      typedef typename ElementType::LeafIntersectionIterator FacetIteratorType;
      for (ElementIterator it = gridView.template begin<0>(); it != gridView.template end<0>(); ++it)
      {
        ElementType& element = *it;
        data[mapper.map(element)] = 0.0;
        int numberOfBoundarySegments = 0;
        bool isOnBoundary = false;
        for (FacetIteratorType facet = element.ileafbegin();
             facet != element.ileafend();
             ++facet) {
          if (!facet->neighbor() && facet->boundary()){
            isOnBoundary = true;
            numberOfBoundarySegments += 1;
            data[mapper.map(element)] += double(facet->boundaryId());
          }
        }
        if (isOnBoundary) {
          data[mapper.map(element)] /= double(numberOfBoundarySegments);
        }
      } // walk the grid
      // write to vtk
      Dune::VTKWriter< GridView > vtkwriter(gridView);
      vtkwriter.addCellData(data, "boundaryId");
      vtkwriter.write(filenameGrid, Dune::VTK::ascii);
    } // check for grid visualization
  } // void visualize(Dune::ParameterTree& paramTree)

private:
  void buildGrid(const CoordinateType& lowerLeft, const CoordinateType& upperRight, const int level)
  {
    Dune::array< unsigned int, dim > numElements;
    std::fill(numElements.begin(), numElements.end(), 1);
    switch (variant) {
      case 1:
        grid_ = Dune::StructuredGridFactory< GridType >::createCubeGrid(lowerLeft, upperRight, numElements);
        break;
      case 2:
        grid_ = Dune::StructuredGridFactory< GridType >::createSimplexGrid(lowerLeft, upperRight, numElements);
        break;
      default:
        DUNE_THROW(Dune::NotImplemented, "Variant " << variant << " of cube not implemented.");
    }
    grid_->globalRefine(level);
    return;
  } // void buildGrid(const CoordinateType& lowerLeft, const CoordinateType& upperRight)

  Dune::shared_ptr< GridType > grid_;
}; // class GenericCube

template< typename GridImp, int variant >
const std::string GenericCube< GridImp, variant >::id = "stuff.grid.provider.cube";

// default implementation of a cube for any grid
// tested for
// dim = 2
//  ALUGRID_SIMPLEX, variant 2
//  ALUGRID_CONFORM, variant 2
// dim = 3
//  ALUGRID_SIMPLEX, variant 2
template< typename GridType >
class Cube
  : public GenericCube< GridType, 2 >
{
private:
  typedef GenericCube< GridType, 2 > BaseType;

public:
  typedef typename BaseType::CoordinateType CoordinateType;

  Cube(Dune::ParameterTree& paramTree)
    : BaseType(paramTree)
  {}

  Cube(const CoordinateType& lowerLeft, const CoordinateType& upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}

  Cube(const double lowerLeft, const double upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}
}; // class Cube

// specialization of Cube for YaspGrid
// tested for dim = 1, 2, 3
template< int dim >
class Cube< Dune::YaspGrid< dim > >
  : public GenericCube< Dune::YaspGrid< dim >, 1 >
{
private:
  typedef GenericCube< Dune::YaspGrid< dim >, 1 > BaseType;

public:
  typedef typename BaseType::CoordinateType CoordinateType;

  Cube(Dune::ParameterTree& paramTree)
    : BaseType(paramTree)
  {}

  Cube(const CoordinateType& lowerLeft, const CoordinateType& upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}

  Cube(const double lowerLeft, const double upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}
}; // class Cube< Dune::YaspGrid< dim > >

// specialization of Cube for SGrid
// tested for dim = 1, 2, 3
template< int dim >
class Cube< Dune::SGrid< dim, dim > >
  : public GenericCube< Dune::SGrid< dim, dim >, 1 >
{
private:
  typedef GenericCube< Dune::SGrid< dim, dim >, 1 > BaseType;

public:
  typedef typename BaseType::CoordinateType CoordinateType;

  Cube(Dune::ParameterTree& paramTree)
    : BaseType(paramTree)
  {}

  Cube(const CoordinateType& lowerLeft, const CoordinateType& upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}

  Cube(const double lowerLeft, const double upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}
}; // class Cube< Dune::SGrid< dim, dim > >

// specialization of Cube for ALUCubeGrid
// tested for dim = 2, 3
template< int dim >
class Cube< Dune::ALUCubeGrid< dim, dim > >
  : public GenericCube< Dune::ALUCubeGrid< dim, dim >, 1 >
{
private:
  typedef GenericCube< Dune::ALUCubeGrid< dim, dim >, 1 > BaseType;

public:
  typedef typename BaseType::CoordinateType CoordinateType;

  Cube(Dune::ParameterTree& paramTree)
    : BaseType(paramTree)
  {}

  Cube(const CoordinateType& lowerLeft, const CoordinateType& upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}

  Cube(const double lowerLeft, const double upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}
}; // class Cube< Dune::ALUCubeGrid< dim, dim > >

template< typename GridType >
class UnitCube
  : public Cube< GridType >
{
private:
  typedef Cube< GridType > BaseType;

public:
  UnitCube(Dune::ParameterTree& paramTree)
    : BaseType(0.0, 1.0, paramTree.get("level", 1))
  {}

  UnitCube(const int level = 1)
    : BaseType(0.0, 1.0, level)
  {}
}; // class UnitCube

} // namespace Provider

} // namespace Grid

} // namespace Stuff

} // namespace Dune

#endif // DUNE_STUFF_GRID_PROVIDER_CUBE_HH
<commit_msg>[grid.provider.cube] some changes<commit_after>#ifndef DUNE_STUFF_GRID_PROVIDER_CUBE_HH
#define DUNE_STUFF_GRID_PROVIDER_CUBE_HH

// dune-common
#include <dune/common/parametertree.hh>
#include <dune/common/shared_ptr.hh>
#include <dune/common/exceptions.hh>
#include <dune/common/fvector.hh>

// dune-grid
#include <dune/grid/utility/structuredgridfactory.hh>
#include <dune/grid/yaspgrid.hh>
#include <dune/grid/alugrid.hh>
#include <dune/grid/sgrid.hh>
#include <dune/grid/common/mcmgmapper.hh>
#include <dune/grid/io/file/vtk/vtkwriter.hh>

namespace Dune
{

namespace Stuff
{

namespace Grid
{

namespace Provider
{

/**
  \brief  Creates a grid of a cube in various dimensions.

          Default implementation using the Dune::StructuredGridFactory to create a grid of a cube in 1, 2 or 3
          dimensions. Tested with

 \c YASPGRID, \c variant 1, dim = 1, 2, 3,

 \c SGRID, \c variant 1, dim = 1, 2, 3,

 \c ALUGRID_SIMPLEX, \c variant 2, dim = 2, 3,

 \c ALUGRID_CONFORM, \c variant 2, dim = 2, 2 and

 \c ALUGRID_CUBE, \c variant 1, dim = 2, 3.

  \tparam GridImp
          Type of the underlying grid.
  \tparam variant
          Type of the codim 0 elements:

\c 1: cubes

2: simplices

  **/
template< typename GridImp, int variant >
class GenericCube
{
public:
  //! Type of the provided grid.
  typedef GridImp GridType;

  //! Dimension of the provided grid.
  static const int dim = GridType::dimension;

  //! Type of the grids coordinates.
  typedef Dune::FieldVector< typename GridType::ctype, dim > CoordinateType;

  //! Unique identifier: \c stuff.grid.provider.cube
  static const std::string id;

  /**
    \brief      Creates a cube.
    \param[in]  paramTree
                A Dune::ParameterTree containing

 the following keys directly or

 a subtree named Cube::id, containing the following keys.

                The actual keys are:

 \c lowerLeft: \a double that is used as a lower left corner in each dimension.

 \c upperRight: \a double that is used as a upper right corner in each dimension.

    **/
  GenericCube(const Dune::ParameterTree& paramTree)
    : lowerLeft_(0.0),
      upperRight_(0.0)
  {
    // check for parameters
    const double lowerLeft = paramTree.get("lowerLeft", 0.0);
    const double upperRight = paramTree.get("upperRight", 1.0);
    assert(lowerLeft < upperRight);
    const int level = paramTree.get("level", 1);
    lowerLeft_ = lowerLeft;
    upperRight_ = upperRight;
    buildGrid(lowerLeft_, upperRight_, level);
  } // Cube(const Dune::ParameterTree& paramTree)

  /**
    \brief      Creates a cube.
    \param[in]  lowerLeft
                A vector that is used as a lower left corner.
    \param[in]  upperRight
                A vector that is used as a upper right corner.
    **/
  GenericCube(const CoordinateType& lowerLeft, const CoordinateType& upperRight, const int level = 1)
    : lowerLeft_(lowerLeft),
      upperRight_(upperRight)
  {
    buildGrid(lowerLeft_, upperRight_, level);
  }

  /**
    \brief      Creates a cube.
    \param[in]  lowerLeft
                A double that is used as a lower left corner in each dimension.
    \param[in]  upperRight
                A double that is used as a upper right corner in each dimension.
    **/
  GenericCube(const double lowerLeft, const double upperRight, const int level = 1)
    : lowerLeft_(lowerLeft),
      upperRight_(upperRight)
  {
    buildGrid(lowerLeft_, upperRight_, level);
  }

  /**
    \brief  Provides access to the created grid.
    \return Reference to the grid.
    **/
  GridType& grid()
  {
    return *grid_;
  }

  const GridType& grid() const
  {
    return *grid_;
  }

private:
  template< int dim >
  struct P0Layout
  {
    bool contains(Dune::GeometryType& geometry)
    {
      if (geometry.dim() == dim)
        return true;
      return false;
    }
  }; // layout class for codim 0 mapper

  /**
    \brief      Visualizes the grid using Dune::VTKWriter.
    \param[in]  paramTree
                A Dune::ParameterTree containing

 the following keys directly or

 a subtree named Cube::id, containing the following keys, or

 a subtree named Cube::id + \c .visualize, containing the following keys.

                The actual keys are:

 \c grid: if specified, filename of the vtk file in which the grid which can be obtained via
                  grid() is visualized (\a if \a not \a specified: \a no \a visualization).

 \c mdGrid: if specified, filename of the vtk file in which the multidomain grid which can be
                  obtained via mdGrid() is visualized (\a if \a not \a specified: \a no \a visualization).

    **/
public:
  void visualize(Dune::ParameterTree& paramTree) const
  {
    const std::string localId = "visualize";
    // get correct parameters
    Dune::ParameterTree* paramsP = &paramTree;
    if (paramsP->hasSub(id))
      paramsP = &(paramsP->sub(id));
    if (paramsP->hasSub(localId))
      paramsP = &(paramsP->sub(localId));
    Dune::ParameterTree& params = *paramsP;
    // check for grid visualization
    if (params.hasKey("grid")) {
      const std::string filenameGrid = params.get("grid", id + ".grid");
      // grid view
      typedef GridImp GridType;
      GridType& grid = this->grid();
      typedef typename GridType::LeafGridView GridView;
      GridView gridView = grid.leafView();
      // mapper
      Dune::LeafMultipleCodimMultipleGeomTypeMapper< GridType, P0Layout > mapper(grid);
      std::vector< double > data(mapper.size());
      // walk the grid
      typedef typename GridView::template Codim<0>::Iterator ElementIterator;
      typedef typename GridView::template Codim<0>::Entity ElementType;
      typedef typename ElementType::LeafIntersectionIterator FacetIteratorType;
      for (ElementIterator it = gridView.template begin<0>(); it != gridView.template end<0>(); ++it)
      {
        ElementType& element = *it;
        data[mapper.map(element)] = 0.0;
        int numberOfBoundarySegments = 0;
        bool isOnBoundary = false;
        for (FacetIteratorType facet = element.ileafbegin();
             facet != element.ileafend();
             ++facet) {
          if (!facet->neighbor() && facet->boundary()){
            isOnBoundary = true;
            numberOfBoundarySegments += 1;
            data[mapper.map(element)] += double(facet->boundaryId());
          }
        }
        if (isOnBoundary) {
          data[mapper.map(element)] /= double(numberOfBoundarySegments);
        }
      } // walk the grid
      // write to vtk
      Dune::VTKWriter< GridView > vtkwriter(gridView);
      vtkwriter.addCellData(data, "boundaryId");
      vtkwriter.write(filenameGrid, Dune::VTK::ascii);
    } // check for grid visualization
  } // void visualize(Dune::ParameterTree& paramTree)

private:
  void buildGrid(const CoordinateType& lowerLeft, const CoordinateType& upperRight, const int level)
  {
    Dune::array< unsigned int, dim > numElements;
    std::fill(numElements.begin(), numElements.end(), 1);
    switch (variant) {
      case 1:
        grid_ = Dune::StructuredGridFactory< GridType >::createCubeGrid(lowerLeft, upperRight, numElements);
        break;
      case 2:
        grid_ = Dune::StructuredGridFactory< GridType >::createSimplexGrid(lowerLeft, upperRight, numElements);
        break;
      default:
        DUNE_THROW(Dune::NotImplemented, "Variant " << variant << " of cube not implemented.");
    }
    grid_->globalRefine(level);
    return;
  } // void buildGrid(const CoordinateType& lowerLeft, const CoordinateType& upperRight)

protected:
  CoordinateType lowerLeft_;
  CoordinateType upperRight_;

private:
  Dune::shared_ptr< GridType > grid_;
}; // class GenericCube

template< typename GridImp, int variant >
const std::string GenericCube< GridImp, variant >::id = "stuff.grid.provider.cube";

// default implementation of a cube for any grid
// tested for
// dim = 2
//  ALUGRID_SIMPLEX, variant 2
//  ALUGRID_CONFORM, variant 2
// dim = 3
//  ALUGRID_SIMPLEX, variant 2
template< typename GridType >
class Cube
  : public GenericCube< GridType, 2 >
{
private:
  typedef GenericCube< GridType, 2 > BaseType;

public:
  typedef typename BaseType::CoordinateType CoordinateType;

  Cube(const Dune::ParameterTree& paramTree)
    : BaseType(paramTree)
  {}

  Cube(const CoordinateType& lowerLeft, const CoordinateType& upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}

  Cube(const double lowerLeft, const double upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}
}; // class Cube

// specialization of Cube for YaspGrid
// tested for dim = 1, 2, 3
template< int dim >
class Cube< Dune::YaspGrid< dim > >
  : public GenericCube< Dune::YaspGrid< dim >, 1 >
{
private:
  typedef GenericCube< Dune::YaspGrid< dim >, 1 > BaseType;

public:
  typedef typename BaseType::CoordinateType CoordinateType;

  Cube(const Dune::ParameterTree& paramTree)
    : BaseType(paramTree)
  {}

  Cube(const CoordinateType& lowerLeft, const CoordinateType& upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}

  Cube(const double lowerLeft, const double upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}
}; // class Cube< Dune::YaspGrid< dim > >

// specialization of Cube for SGrid
// tested for dim = 1, 2, 3
template< int dim >
class Cube< Dune::SGrid< dim, dim > >
  : public GenericCube< Dune::SGrid< dim, dim >, 1 >
{
private:
  typedef GenericCube< Dune::SGrid< dim, dim >, 1 > BaseType;

public:
  typedef typename BaseType::CoordinateType CoordinateType;

  Cube(const Dune::ParameterTree& paramTree)
    : BaseType(paramTree)
  {}

  Cube(const CoordinateType& lowerLeft, const CoordinateType& upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}

  Cube(const double lowerLeft, const double upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}
}; // class Cube< Dune::SGrid< dim, dim > >

// specialization of Cube for ALUCubeGrid
// tested for dim = 2, 3
template< int dim >
class Cube< Dune::ALUCubeGrid< dim, dim > >
  : public GenericCube< Dune::ALUCubeGrid< dim, dim >, 1 >
{
private:
  typedef GenericCube< Dune::ALUCubeGrid< dim, dim >, 1 > BaseType;

public:
  typedef typename BaseType::CoordinateType CoordinateType;

  Cube(const Dune::ParameterTree& paramTree)
    : BaseType(paramTree)
  {}

  Cube(const CoordinateType& lowerLeft, const CoordinateType& upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}

  Cube(const double lowerLeft, const double upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}
}; // class Cube< Dune::ALUCubeGrid< dim, dim > >

template< typename GridType >
class UnitCube
  : public Cube< GridType >
{
private:
  typedef Cube< GridType > BaseType;

public:
  UnitCube(const Dune::ParameterTree& paramTree)
    : BaseType(0.0, 1.0, paramTree.get("level", 1))
  {}

  UnitCube(const int level = 1)
    : BaseType(0.0, 1.0, level)
  {}
}; // class UnitCube

} // namespace Provider

} // namespace Grid

} // namespace Stuff

} // namespace Dune

#endif // DUNE_STUFF_GRID_PROVIDER_CUBE_HH
<|endoftext|>


<commit_before>// Copyright (c) 2019 Matthew J. Smith and Overkit contributors
// License: MIT (http://opensource.org/licenses/MIT)

#ifndef OVK_CORE_DISTRIBUTED_REGION_HASH_HPP_INCLUDED
#define OVK_CORE_DISTRIBUTED_REGION_HASH_HPP_INCLUDED

#include <ovk/core/Array.hpp>
#include <ovk/core/ArrayView.hpp>
#include <ovk/core/Box.hpp>
#include <ovk/core/Comm.hpp>
#include <ovk/core/DataType.hpp>
#include <ovk/core/Elem.hpp>
#include <ovk/core/Field.hpp>
#include <ovk/core/Global.hpp>
#include <ovk/core/Interval.hpp>
#include <ovk/core/Map.hpp>
#include <ovk/core/Range.hpp>
#include <ovk/core/Requires.hpp>
#include <ovk/core/RegionTraits.hpp>
#include <ovk/core/Tuple.hpp>

#include <mpi.h>

#include <cstring>
#include <type_traits>

namespace ovk {
namespace core {

template <typename CoordType> class distributed_region_hash;

template <typename CoordType> class distributed_region_data {

public:

  using region_type = typename std::conditional<std::is_same<CoordType, double>::value, box,
    range>::type;

  const region_type &Region() const { return Region_; }

  int Rank() const { return Rank_; }

  template <typename T> const T &AuxData() const {
    return *reinterpret_cast<const T *>(AuxData_.Data());
  }

private:

  region_type Region_;
  int Rank_;
  array<byte> AuxData_;

  friend class distributed_region_hash<CoordType>;

};

template <typename CoordType> class distributed_region_hash_retrieved_bins {

public:

  using region_data = distributed_region_data<CoordType>;

  const region_data &RegionData(int iRegion) const { return RegionData_(iRegion); }

  array_view<const int> BinRegionIndices(int iBin) const {
    const interval<long long> &Interval = BinRegionIndicesIntervals_(iBin);
    return {BinRegionIndices_.Data(Interval.Begin()), Interval};
  }

private:

  array<region_data> RegionData_;
  map<int,interval<long long>> BinRegionIndicesIntervals_;
  array<int> BinRegionIndices_;

  friend class distributed_region_hash<CoordType>;

};

template <typename CoordType> class distributed_region_hash {

public:

  static_assert(std::is_same<CoordType, int>::value || std::is_same<CoordType, double>::value,
    "Coord type must be int or double.");

  using coord_type = CoordType;
  using region_type = typename std::conditional<std::is_same<coord_type, double>::value, box,
    range>::type;
  using traits = region_traits<region_type>;

  using region_data = distributed_region_data<coord_type>;
  using retrieved_bins = distributed_region_hash_retrieved_bins<coord_type>;

  distributed_region_hash(int NumDims, comm_view Comm);
  distributed_region_hash(int NumDims, comm_view Comm, int NumLocalRegions, array_view<const
    region_type> LocalRegions);
  template <typename ArrayType, OVK_FUNCDECL_REQUIRES(std::is_trivially_copyable<array_value_type<
    ArrayType>>::value && std::is_trivially_destructible<array_value_type<ArrayType>>::value)>
    distributed_region_hash(int NumDims, comm_view Comm, int NumLocalRegions, array_view<const
    region_type> LocalRegions, const ArrayType &LocalRegionAuxData, MPI_Datatype
    AuxDataMPIType=GetMPIDataType<array_value_type<ArrayType>>());

  // Can't define these here due to issues with GCC < 6.3 and Intel < 17
//   distributed_region_hash(const distributed_region_hash &Other) = delete;
//   distributed_region_hash(distributed_region_hash &&Other) noexcept = default;

//   distributed_region_hash &operator=(const distributed_region_hash &Other) = delete;
//   distributed_region_hash &operator=(distributed_region_hash &&Other) noexcept = default;

  elem<int,2> MapToBin(const tuple<coord_type> &Point) const;

  map<int,retrieved_bins> RetrieveBins(array_view<const elem<int,2>> BinIDs) const;

private:

  int NumDims_;

  comm_view Comm_;

  region_type GlobalExtents_;

  range ProcRange_;
  range_indexer<int> ProcIndexer_;
  tuple<coord_type> ProcSize_;

  array<int> ProcToBinMultipliers_;

  long long AuxDataNumBytes_;
  MPI_Datatype AuxDataMPIType_;

  array<region_data> RegionData_;
  range BinRange_;
  field<int> NumRegionsPerBin_;
  field<long long> BinRegionIndicesStarts_;
  array<int> BinRegionIndices_;

  distributed_region_hash(int NumDims, comm_view Comm, int NumLocalRegions, array_view<const
    region_type> LocalRegions, const array<const byte *> &LocalRegionAuxData, long long
    AuxDataNumBytes, MPI_Datatype AuxDataMPIType);

  template <typename ArrayType> static array<const byte *> GetBytePointers_(const ArrayType &Array);

  static tuple<int> BinDecomp_(int NumDims, const region_type &GlobalExtents, int MaxBins);

  static tuple<int> GetBinSize_(const range &GlobalExtents, const tuple<int> &NumBins);
  static tuple<double> GetBinSize_(const box &GlobalExtents, const tuple<int> &NumBins);

  static tuple<int> MapToUniformCell_(int NumDims, const tuple<int> &Origin, const tuple<int>
    &CellSize, const tuple<int> &Point);
  static tuple<int> MapToUniformCell_(int NumDims, const tuple<double> &Origin, const tuple<double>
    &CellSize, const tuple<double> &Point);

};

template <typename CoordType> template <typename ArrayType, OVK_FUNCDEF_REQUIRES(
  std::is_trivially_copyable<array_value_type<ArrayType>>::value && std::is_trivially_destructible<
  array_value_type<ArrayType>>::value)> distributed_region_hash<CoordType>::distributed_region_hash(
  int NumDims, comm_view Comm, int NumLocalRegions, array_view<const region_type> LocalRegions,
  const ArrayType &LocalRegionAuxData, MPI_Datatype AuxDataMPIType):
  distributed_region_hash(NumDims, Comm, NumLocalRegions, LocalRegions, GetBytePointers_(
    LocalRegionAuxData), sizeof(array_value_type<ArrayType>), AuxDataMPIType)
{}

template <typename CoordType> template <typename ArrayType> array<const byte *>
  distributed_region_hash<CoordType>::GetBytePointers_(const ArrayType &Array) {

  array<const byte *> BytePointers({Array.Count()});

  for (int iValue = 0; iValue < Array.Count(); ++iValue) {
    BytePointers(iValue) = reinterpret_cast<const byte *>(ArrayData(Array)+iValue);
  }

  return BytePointers;

}

extern template class distributed_region_hash<int>;
extern template class distributed_region_hash<double>;

}}

#endif
<commit_msg>std::is_trivially_copyable isn't supported on target Intel compiler version<commit_after>// Copyright (c) 2019 Matthew J. Smith and Overkit contributors
// License: MIT (http://opensource.org/licenses/MIT)

#ifndef OVK_CORE_DISTRIBUTED_REGION_HASH_HPP_INCLUDED
#define OVK_CORE_DISTRIBUTED_REGION_HASH_HPP_INCLUDED

#include <ovk/core/Array.hpp>
#include <ovk/core/ArrayView.hpp>
#include <ovk/core/Box.hpp>
#include <ovk/core/Comm.hpp>
#include <ovk/core/DataType.hpp>
#include <ovk/core/Elem.hpp>
#include <ovk/core/Field.hpp>
#include <ovk/core/Global.hpp>
#include <ovk/core/Interval.hpp>
#include <ovk/core/Map.hpp>
#include <ovk/core/Range.hpp>
#include <ovk/core/Requires.hpp>
#include <ovk/core/RegionTraits.hpp>
#include <ovk/core/Tuple.hpp>

#include <mpi.h>

#include <cstring>
#include <type_traits>

namespace ovk {
namespace core {

template <typename CoordType> class distributed_region_hash;

template <typename CoordType> class distributed_region_data {

public:

  using region_type = typename std::conditional<std::is_same<CoordType, double>::value, box,
    range>::type;

  const region_type &Region() const { return Region_; }

  int Rank() const { return Rank_; }

  template <typename T> const T &AuxData() const {
    return *reinterpret_cast<const T *>(AuxData_.Data());
  }

private:

  region_type Region_;
  int Rank_;
  array<byte> AuxData_;

  friend class distributed_region_hash<CoordType>;

};

template <typename CoordType> class distributed_region_hash_retrieved_bins {

public:

  using region_data = distributed_region_data<CoordType>;

  const region_data &RegionData(int iRegion) const { return RegionData_(iRegion); }

  array_view<const int> BinRegionIndices(int iBin) const {
    const interval<long long> &Interval = BinRegionIndicesIntervals_(iBin);
    return {BinRegionIndices_.Data(Interval.Begin()), Interval};
  }

private:

  array<region_data> RegionData_;
  map<int,interval<long long>> BinRegionIndicesIntervals_;
  array<int> BinRegionIndices_;

  friend class distributed_region_hash<CoordType>;

};

template <typename CoordType> class distributed_region_hash {

public:

  static_assert(std::is_same<CoordType, int>::value || std::is_same<CoordType, double>::value,
    "Coord type must be int or double.");

  using coord_type = CoordType;
  using region_type = typename std::conditional<std::is_same<coord_type, double>::value, box,
    range>::type;
  using traits = region_traits<region_type>;

  using region_data = distributed_region_data<coord_type>;
  using retrieved_bins = distributed_region_hash_retrieved_bins<coord_type>;

  distributed_region_hash(int NumDims, comm_view Comm);
  distributed_region_hash(int NumDims, comm_view Comm, int NumLocalRegions, array_view<const
    region_type> LocalRegions);
  // is_trivially_copyable not yet supported on Intel 17
//   template <typename ArrayType, OVK_FUNCDECL_REQUIRES(std::is_trivially_copyable<array_value_type<
//     ArrayType>>::value && std::is_trivially_destructible<array_value_type<ArrayType>>::value)>
  template <typename ArrayType, OVK_FUNCDECL_REQUIRES(std::is_trivially_destructible<
    array_value_type<ArrayType>>::value)> distributed_region_hash(int NumDims, comm_view Comm, int
    NumLocalRegions, array_view<const region_type> LocalRegions, const ArrayType
    &LocalRegionAuxData, MPI_Datatype AuxDataMPIType=GetMPIDataType<array_value_type<ArrayType>>());

  // Can't define these here due to issues with GCC < 6.3 and Intel < 17
//   distributed_region_hash(const distributed_region_hash &Other) = delete;
//   distributed_region_hash(distributed_region_hash &&Other) noexcept = default;

//   distributed_region_hash &operator=(const distributed_region_hash &Other) = delete;
//   distributed_region_hash &operator=(distributed_region_hash &&Other) noexcept = default;

  elem<int,2> MapToBin(const tuple<coord_type> &Point) const;

  map<int,retrieved_bins> RetrieveBins(array_view<const elem<int,2>> BinIDs) const;

private:

  int NumDims_;

  comm_view Comm_;

  region_type GlobalExtents_;

  range ProcRange_;
  range_indexer<int> ProcIndexer_;
  tuple<coord_type> ProcSize_;

  array<int> ProcToBinMultipliers_;

  long long AuxDataNumBytes_;
  MPI_Datatype AuxDataMPIType_;

  array<region_data> RegionData_;
  range BinRange_;
  field<int> NumRegionsPerBin_;
  field<long long> BinRegionIndicesStarts_;
  array<int> BinRegionIndices_;

  distributed_region_hash(int NumDims, comm_view Comm, int NumLocalRegions, array_view<const
    region_type> LocalRegions, const array<const byte *> &LocalRegionAuxData, long long
    AuxDataNumBytes, MPI_Datatype AuxDataMPIType);

  template <typename ArrayType> static array<const byte *> GetBytePointers_(const ArrayType &Array);

  static tuple<int> BinDecomp_(int NumDims, const region_type &GlobalExtents, int MaxBins);

  static tuple<int> GetBinSize_(const range &GlobalExtents, const tuple<int> &NumBins);
  static tuple<double> GetBinSize_(const box &GlobalExtents, const tuple<int> &NumBins);

  static tuple<int> MapToUniformCell_(int NumDims, const tuple<int> &Origin, const tuple<int>
    &CellSize, const tuple<int> &Point);
  static tuple<int> MapToUniformCell_(int NumDims, const tuple<double> &Origin, const tuple<double>
    &CellSize, const tuple<double> &Point);

};

// is_trivially_copyable not yet supported on Intel 17
// template <typename CoordType> template <typename ArrayType, OVK_FUNCDEF_REQUIRES(
//   std::is_trivially_copyable<array_value_type<ArrayType>>::value && std::is_trivially_destructible<
//   array_value_type<ArrayType>>::value)> distributed_region_hash<CoordType>::distributed_region_hash(
template <typename CoordType> template <typename ArrayType, OVK_FUNCDEF_REQUIRES(
  std::is_trivially_destructible<array_value_type<ArrayType>>::value)> distributed_region_hash<
  CoordType>::distributed_region_hash(int NumDims, comm_view Comm, int NumLocalRegions,
  array_view<const region_type> LocalRegions, const ArrayType &LocalRegionAuxData, MPI_Datatype
  AuxDataMPIType):
  distributed_region_hash(NumDims, Comm, NumLocalRegions, LocalRegions, GetBytePointers_(
    LocalRegionAuxData), sizeof(array_value_type<ArrayType>), AuxDataMPIType)
{}

template <typename CoordType> template <typename ArrayType> array<const byte *>
  distributed_region_hash<CoordType>::GetBytePointers_(const ArrayType &Array) {

  array<const byte *> BytePointers({Array.Count()});

  for (int iValue = 0; iValue < Array.Count(); ++iValue) {
    BytePointers(iValue) = reinterpret_cast<const byte *>(ArrayData(Array)+iValue);
  }

  return BytePointers;

}

extern template class distributed_region_hash<int>;
extern template class distributed_region_hash<double>;

}}

#endif
<|endoftext|>


<commit_before>/* This file is part of VoltDB.
 * Copyright (C) 2008-2012 VoltDB Inc.
 *
 * This file contains original code and/or modifications of original code.
 * Any modifications made by VoltDB Inc. are licensed under the following
 * terms and conditions:
 *
 * VoltDB is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * VoltDB is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with VoltDB.  If not, see <http://www.gnu.org/licenses/>.
 */
/* Copyright (C) 2008 by H-Store Project
 * Brown University
 * Massachusetts Institute of Technology
 * Yale University
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#include "limitexecutor.h"
#include "common/debuglog.h"
#include "common/common.h"
#include "common/tabletuple.h"
#include "plannodes/limitnode.h"
#include "storage/table.h"
#include "storage/temptable.h"
#include "storage/tableiterator.h"
#include "storage/tablefactory.h"

using namespace voltdb;

bool
LimitExecutor::p_init(AbstractPlanNode* abstract_node,
                      TempTableLimits* limits)
{
    VOLT_TRACE("init limit Executor");

    LimitPlanNode* node = dynamic_cast<LimitPlanNode*>(abstract_node);
    assert(node);

    //
    // Skip if we are inline
    //
    if (!node->isInline())
    {
        //
        // Just copy the table schema of our input table
        //
        assert(node->getInputTables().size() == 1);
        node->
            setOutputTable(TableFactory::
                           getCopiedTempTable(node->databaseId(),
                                              node->getInputTables()[0]->name(),
                                              node->getInputTables()[0],
                                              limits));
    }
    return true;
}

bool
LimitExecutor::p_execute(const NValueArray &params)
{
    LimitPlanNode* node = dynamic_cast<LimitPlanNode*>(m_abstractNode);
    assert(node);
    Table* output_table = node->getOutputTable();
    assert(output_table);
    Table* input_table = node->getInputTables()[0];
    assert(input_table);

    //
    // Grab the iterator for our input table, and loop through until
    // we have copy enough tuples for the limit specified by the node
    //
    TableTuple tuple(input_table->schema());
    TableIterator iterator = input_table->iterator();

    int tuple_ctr = 0;
    int tuples_skipped = 0;
    int limit = -1;
    int offset = -1;
    node->getLimitAndOffsetByReference(params, limit, offset);

    while ((limit == -1 || tuple_ctr < limit) && iterator.next(tuple))
    {
        // TODO: need a way to skip / iterate N items.
        if (tuples_skipped < offset)
        {
            tuples_skipped++;
            continue;
        }
        tuple_ctr++;

        if (!output_table->insertTuple(tuple))
        {
            VOLT_ERROR("Failed to insert tuple from input table '%s' into"
                       " output table '%s'",
                       input_table->name().c_str(),
                       output_table->name().c_str());
            return false;
        }
    }

    return true;
}
<commit_msg>Licensecheck fixup.<commit_after>/* This file is part of VoltDB.
 * Copyright (C) 2008-2012 VoltDB Inc.
 *
 * This file contains original code and/or modifications of original code.
 * Any modifications made by VoltDB Inc. are licensed under the following
 * terms and conditions:
 *
 * VoltDB is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * VoltDB is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with VoltDB.  If not, see <http://www.gnu.org/licenses/>.
 */
/* Copyright (C) 2008 by H-Store Project
 * Brown University
 * Massachusetts Institute of Technology
 * Yale University
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#include "limitexecutor.h"
#include "common/debuglog.h"
#include "common/common.h"
#include "common/tabletuple.h"
#include "plannodes/limitnode.h"
#include "storage/table.h"
#include "storage/temptable.h"
#include "storage/tableiterator.h"
#include "storage/tablefactory.h"

using namespace voltdb;

bool
LimitExecutor::p_init(AbstractPlanNode* abstract_node,
                      TempTableLimits* limits)
{
    VOLT_TRACE("init limit Executor");

    LimitPlanNode* node = dynamic_cast<LimitPlanNode*>(abstract_node);
    assert(node);

    //
    // Skip if we are inline
    //
    if (!node->isInline())
    {
        //
        // Just copy the table schema of our input table
        //
        assert(node->getInputTables().size() == 1);
        node->
            setOutputTable(TableFactory::
                           getCopiedTempTable(node->databaseId(),
                                              node->getInputTables()[0]->name(),
                                              node->getInputTables()[0],
                                              limits));
    }
    return true;
}

bool
LimitExecutor::p_execute(const NValueArray &params)
{
    LimitPlanNode* node = dynamic_cast<LimitPlanNode*>(m_abstractNode);
    assert(node);
    Table* output_table = node->getOutputTable();
    assert(output_table);
    Table* input_table = node->getInputTables()[0];
    assert(input_table);

    //
    // Grab the iterator for our input table, and loop through until
    // we have copy enough tuples for the limit specified by the node
    //
    TableTuple tuple(input_table->schema());
    TableIterator iterator = input_table->iterator();

    int tuple_ctr = 0;
    int tuples_skipped = 0;
    int limit = -1;
    int offset = -1;
    node->getLimitAndOffsetByReference(params, limit, offset);

    while ((limit == -1 || tuple_ctr < limit) && iterator.next(tuple))
    {
        // TODO: need a way to skip / iterate N items.
        if (tuples_skipped < offset)
        {
            tuples_skipped++;
            continue;
        }
        tuple_ctr++;

        if (!output_table->insertTuple(tuple))
        {
            VOLT_ERROR("Failed to insert tuple from input table '%s' into"
                       " output table '%s'",
                       input_table->name().c_str(),
                       output_table->name().c_str());
            return false;
        }
    }

    return true;
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////
//
// The MIT License (MIT)
//
// Copyright (c) 2014 stevehalliwell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
////////////////////////////////////////////////////////////

#include <ResourceManager/ResourceManager.hpp>
#include <ResourceManager/BaseResource.hpp>
#include <ResourceManager/LuaParser.hpp>
#include <string>
#include<vector>
namespace rm
{

////////////////////////////////////////////////////////////
/// Initialise static members
////////////////////////////////////////////////////////////
ResourceLookup ResourceManager::resources = {};
ResourceLookup ResourceManager::errorResources = {};
ResourceQueue ResourceManager::loadingQueue = {};
ResourceQueue ResourceManager::unloadQueue = {};
ResourceQueue ResourceManager::reloadQueue = {};
bool ResourceManager::useNullForErrorRes = true;

LoadCompleteCallback ResourceManager::loadCompleteCallback = nullptr;

enum class LoadMode
{
    Queue,
    Block,
};
////////////////////////////////////////////////////////////
/// Function definitions
////////////////////////////////////////////////////////////

void ResourceManager::unloadResource(const std::string& name, LoadMode mode)
{
     // Checking if resource exists in resources
   if (resources.find(name) != resources.end())
   {
       // Assigns a new pointer to the key for the resource
       ResourcePtr pointer = resources.find(name)->second;

       // If the resource has to be removed immediately
       if(mode == LoadMode::Block)
       {
           // Change the status of the BaseResource
           pointer->setIsLoaded(false);
           // Unload the BaseResource
           pointer->unload;
       }
       else
       {
           // Change the status of the BaseResource
           pointer->setIsLoaded(false);
           // Send to unloadQueue list
           unloadQueue.push(pointer);
       }
       return;
    }
    return;

}

void ResourceManager::reloadResource(const std::string& name)
{
    ResourcePtr res = nullptr;

    // Check if resource exists in resource map
    if (resources.find(name) != resources.end())
    {
		// Set resource pointer
        res = resources[name];
    }
    else
    {
        Logger::logMessage("Reload resource warning: Resource not already loaded");

        // Create new resource anyway
        //loadingQueue.push(res);
        // Not quire sure how to handle this/if we're allowing them to load anyway
    }

    // Send to reloadQueue
    reloadQueue.push(res);

    // Must appropriately set isLoaded in resource
    // Should it even change the state of isLoaded, since it will be loaded until it hits the queue?
}

void ResourceManager::initPack(const std::string& path)
{
    //How do you check if a string is a valid file path? Does this even need to be checked?
    /*
    if(path is not a valid filepath)
    {
        return error?
    }
    */

    //Get a list of data from the resource pack lua table
    ResourceDataList list = LuaParser::parsePack(path);

    //iterate through the list and create a new resource if one does not already exist.
    for(ResourceDataList::iterator iter = list.begin(); iter != list.end(); iter++)
    {
        //is this supposed to call initResource()? It seems like initResource() will not set an alias as it only takes a path, whereas this function can set the alias and type returned from the luaparser.
        //initResource(list[iter].path);

        //If it does not call initResource()
        bool exists = false;
        for(ResourceLookup::iterator iter2 = resources.begin(); iter2 != resources.end(); iter2++)
        {
            if(iter2->second->getFilePath() == path)
            {
                exists = true;
            }
        }

        if(!exists)
        {
            ResourcePtr res = ResourceFactory::createResource(iter->path, iter->type);
            res->setAlias(iter->alias);
            resources.insert({iter->alias, res});

            //return success?
        }
        else
        {
            //return error (already exists)?
        }
    }
}

void ResourceManager::loadPack(const std::string& path, LoadMode mode)
{
    // Create a list from the parsePack
    ResourceDataList list = LuaParser::parsePack(path);

    // Iterate through the list
    for (ResourceDataList::iterator var = list.begin; var != list.end; ++var)
    {
        // Checking if resource exists in resources
        if (resources.find(var->alias) != resources.end())
        {
            // Assigns a new pointer to the key for the resource
            ResourcePtr pointer = resources.find(var->alias)->second;

            // Checking if the resource is not loaded
            if (pointer->isLoaded == false)
            {
                // If the resource has to be loaded immediately
                if (mode == LoadMode::Block)
                {
                    // Change the status of the BaseResource
                    pointer->setIsLoaded(true);
                    // Unload the BaseResource
                    pointer->load;
                }
                else
                {

                    // Send to unloadQueue list
                    loadingQueue.push(pointer);
                }
            }
        }

    }

    return;
}

void ResourceManager::unloadPack(const std::string& path, LoadMode mode)
{
    // Create a list from the parsePack
    ResourceDataList list = LuaParser::parsePack(path);

    // Iterate through the list
    for (ResourceDataList::iterator var = list.begin; var != list.end; ++var)
    {
        // Checking if resource exists in resources
        if (resources.find(var->alias) != resources.end())
        {
            // Assigns a new pointer to the key for the resource
            ResourcePtr pointer = resources.find(var->alias)->second;

            // Checking if the resource is loaded
            if (pointer->isLoaded == true)
            {
                // If the resource has to be unloaded immediately
                if (mode == LoadMode::Block)
                {
                    // Change the status of the BaseResource
                    pointer->setIsLoaded(false);
                    // Unload the BaseResource
                    pointer->unload;
                }
                else
                {
                   // Send to unloadQueue list
                    unloadQueue.push(pointer);
                }
            }
        }

    }

    return;

}

void ResourceManager::reloadPack(const std::string& path)
{

    // Create a list from the parsePack
    ResourceDataList list = LuaParser::parsePack(path);

    // Iterate through the list
    for (ResourceDataList::iterator var = list.begin; var != list.end; ++var)
    {
        // Assign the alias to a throw away string
        std::string name = var->alias;

        // Checking if resource exists in resource map
        if (resources.find(name) != resources.end())
        {
            // Assigns a new pointer to the key for the resource
            ResourcePtr res = resources.find(name)->second;

            // Send to reloadQueue
            reloadQueue.push(res);
        }
        else
        {
            Logger::logMessage("Reload resource warning: Resource not already loaded");

            // Create new resource anyway
            //loadingQueue.push(res);
            // Not quire sure how to handle this/if we're allowing them to load anyway
        }
    }
}

void ResourceManager::switchPack(const std::string& fromPath, const std::string& toPath)
{
    // Create a list from the parsePack for the current pack
    ResourceDataList from = LuaParser::parsePack(fromPath);

    // Create a list from the parsePack for the future Pack
    ResourceDataList tolist = LuaParser::parsePack(toPath);

    // Create a string vector to hold the common resources
    std::vector<std::string> common;

    // Load the future pack
    for (ResourceDataList::iterator var = tolist.begin; var != tolist.end; ++var)
    {

        // Checking if resource exists in resources
        if (resources.find(var->alias) != resources.end())
        {
            // Assigns a new pointer to the key for the resource
            ResourcePtr pointer = resources.find(var->alias)->second;

            // Checking if the resource is not loaded
            if (pointer->isLoaded == false)
            {
                // Change the status of the BaseResource
                pointer->setIsLoaded(true);
                // Send to unloadQueue list
                loadingQueue.push(pointer);
            }
            else
            {
                // Add the name to the vector
                common.push_back(var->alias);
            }
        }
    }

    // Iterate through the old Pack and remove the Resources that are not common to the pack and the vector
    for (ResourceDataList::iterator var = from.begin; var != from.end; ++var)
    {

        // Checking if resource is common to the string vector
        if (resources.find(var->alias) != resources.end())
        {

            if (std::find(common.begin(), common.end(), resources.find(var->alias) != common.end))
            {
                // The two entries are common - do nothing
            }
            else
            {
                // The two entries do not match - unload the old entry

                // Assigns a new pointer to the key for the resource
                ResourcePtr pointer = resources.find(var->alias)->second;

                // Send to unloadQueue list
                loadingQueue.push(pointer);
            }

        }
    }

}

void ResourceManager::init(bool _useNullForErrorRes)
{
    useNullForErrorRes = _useNullForErrorRes;

    if(!useNullForErrorRes)
    {
        // initPack("ResMan_DefaultError_Resources\ErrorResource_LuaFile.txt");
    }
}

void ResourceManager::update()
{
    loadFromQueue();
    unloadFromQueue();
    reloadFromQueue();
}

void ResourceManager::cleanupUnused()
{
    // Fetch a list of all resources
    ResourceList cleanup = listAll();

    // run for each resource in list
    for(ResourcePtr r : cleanup)
    {
        // if the resource pointer is unique
        if(r.unique())
        {
            // Get alias of resource
            std::string name = r->getAlias();

            // Log what resources were unloaded
            Logger::logMessage("Unloading Unused Resource: ", name);

            // Change resource status to false
            r->setIsLoaded(false);

            // unload resource
            r->unload();
        }
    }
}

bool ResourceManager::isLoading()
{
    return getNumToLoad() > 0;
}

size_t ResourceManager::getNumToLoad()//ResourceManager::getNumToLoad()
{
    return loadingQueue.size();
}

ResourceList ResourceManager::listAll()
{
    // create a temp list to add pointers
    ResourceList temp;

    // iterate through and add each pointer to the temp list
    for (ResourceLookup::iterator it = resources.begin; it != resources.end; ++it)
    {
        temp.push_back(it->second);
    }

    return temp;
}

size_t ResourceManager::getMemUsage()
{

    throw("Not implemented");
}

size_t ResourceManager::getNumResources()
{
    return resources.size();
}

void ResourceManager::setLoadCompleteCallback(LoadCompleteCallback callback)
{
    loadCompleteCallback = callback;
}

void ResourceManager::loadFromQueue()
{
    while (loadingQueue.size() > 0)
    {
        // Check First res in the queue
        auto frontRes = loadingQueue.front();

        // Check to see if the resource is already loaded.
        if (frontRes->isLoaded)
        {
            // If its loaded delete from queue
            // Allow for another resource to be loaded if there are stil l more in the queue.
            loadingQueue.pop();
        }
        else
        {
            // Load the first resource and check if any errors
            if (frontRes->load())
            {
                // Set resource to is loaded
                frontRes->setIsLoaded(true);
                // Remove from loading queue
                loadingQueue.pop();
            }
            else
            {
                // Log Error
                Logger::logMessage("Load Resource Failed: ", frontRes->getAlias);
            }
            // Send load complete call back once the last item is loaded.
            if (loadingQueue.size() == 0)
            {
                loadCompleteCallback();
            }
            // break from loop so only one resource is loaded at a time.
            break;
        }
    }
}

void ResourceManager::unloadFromQueue()
{
    // Only run when queue is > 0
    while (unloadQueue.size() > 0)
    {
        // Check First res in the queue
        auto frontRes = unloadQueue.front();

        // Check to see if the resource is already unloaded.
        if (!frontRes->isLoaded)
        {
            // If its unloaded delete from queue
            // Allow for another resource to be unloaded if there are stil l more in the queue.
            unloadQueue.pop();
        }
        else
        {
            // Load the first resource and check if any errors
            if (frontRes->unload())
            {
                // Set resource to is unloaded
                frontRes->setIsLoaded(false);
                // Remove from unloadeding queue
                unloadQueue.pop();
            }
            else
            {
                // Log Error
                Logger::logMessage("Unload Resource Failed: ", frontRes->getAlias);
            }
            // break from loop so only one resource is unloaded at a time.
            break;
        }
    }
}

void ResourceManager::reloadFromQueue()
{
    if (reloadQueue.size() > 0)
    {
        // Check First res in the queue
        auto frontRes = reloadQueue.front();

        // Load the first resource and check if any errors
        if (frontRes->reload())
        {
            // Remove from reloading Queue
            reloadQueue.pop();
        }
        else
        {
            // Log Error
            Logger::logMessage("Reload Resource Failed: ", frontRes->getAlias);
        }
    }
}

} // rm
<commit_msg>Fixed cleanup + Removed getMemUsage<commit_after>////////////////////////////////////////////////////////////
//
// The MIT License (MIT)
//
// Copyright (c) 2014 stevehalliwell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
////////////////////////////////////////////////////////////

#include <ResourceManager/ResourceManager.hpp>
#include <ResourceManager/BaseResource.hpp>
#include <ResourceManager/LuaParser.hpp>
#include <string>
#include<vector>
namespace rm
{

////////////////////////////////////////////////////////////
/// Initialise static members
////////////////////////////////////////////////////////////
ResourceLookup ResourceManager::resources = {};
ResourceLookup ResourceManager::errorResources = {};
ResourceQueue ResourceManager::loadingQueue = {};
ResourceQueue ResourceManager::unloadQueue = {};
ResourceQueue ResourceManager::reloadQueue = {};
bool ResourceManager::useNullForErrorRes = true;

LoadCompleteCallback ResourceManager::loadCompleteCallback = nullptr;

enum class LoadMode
{
    Queue,
    Block,
};
////////////////////////////////////////////////////////////
/// Function definitions
////////////////////////////////////////////////////////////

void ResourceManager::unloadResource(const std::string& name, LoadMode mode)
{
     // Checking if resource exists in resources
   if (resources.find(name) != resources.end())
   {
       // Assigns a new pointer to the key for the resource
       ResourcePtr pointer = resources.find(name)->second;

       // If the resource has to be removed immediately
       if(mode == LoadMode::Block)
       {
           // Change the status of the BaseResource
           pointer->setIsLoaded(false);
           // Unload the BaseResource
           pointer->unload;
       }
       else
       {
           // Change the status of the BaseResource
           pointer->setIsLoaded(false);
           // Send to unloadQueue list
           unloadQueue.push(pointer);
       }
       return;
    }
    return;

}

void ResourceManager::reloadResource(const std::string& name)
{
    ResourcePtr res = nullptr;

    // Check if resource exists in resource map
    if (resources.find(name) != resources.end())
    {
		// Set resource pointer
        res = resources[name];
    }
    else
    {
        Logger::logMessage("Reload resource warning: Resource not already loaded");

        // Create new resource anyway
        //loadingQueue.push(res);
        // Not quire sure how to handle this/if we're allowing them to load anyway
    }

    // Send to reloadQueue
    reloadQueue.push(res);

    // Must appropriately set isLoaded in resource
    // Should it even change the state of isLoaded, since it will be loaded until it hits the queue?
}

void ResourceManager::initPack(const std::string& path)
{
    //How do you check if a string is a valid file path? Does this even need to be checked?
    /*
    if(path is not a valid filepath)
    {
        return error?
    }
    */

    //Get a list of data from the resource pack lua table
    ResourceDataList list = LuaParser::parsePack(path);

    //iterate through the list and create a new resource if one does not already exist.
    for(ResourceDataList::iterator iter = list.begin(); iter != list.end(); iter++)
    {
        //is this supposed to call initResource()? It seems like initResource() will not set an alias as it only takes a path, whereas this function can set the alias and type returned from the luaparser.
        //initResource(list[iter].path);

        //If it does not call initResource()
        bool exists = false;
        for(ResourceLookup::iterator iter2 = resources.begin(); iter2 != resources.end(); iter2++)
        {
            if(iter2->second->getFilePath() == path)
            {
                exists = true;
            }
        }

        if(!exists)
        {
            ResourcePtr res = ResourceFactory::createResource(iter->path, iter->type);
            res->setAlias(iter->alias);
            resources.insert({iter->alias, res});

            //return success?
        }
        else
        {
            //return error (already exists)?
        }
    }
}

void ResourceManager::loadPack(const std::string& path, LoadMode mode)
{
    // Create a list from the parsePack
    ResourceDataList list = LuaParser::parsePack(path);

    // Iterate through the list
    for (ResourceDataList::iterator var = list.begin; var != list.end; ++var)
    {
        // Checking if resource exists in resources
        if (resources.find(var->alias) != resources.end())
        {
            // Assigns a new pointer to the key for the resource
            ResourcePtr pointer = resources.find(var->alias)->second;

            // Checking if the resource is not loaded
            if (pointer->isLoaded == false)
            {
                // If the resource has to be loaded immediately
                if (mode == LoadMode::Block)
                {
                    // Change the status of the BaseResource
                    pointer->setIsLoaded(true);
                    // Unload the BaseResource
                    pointer->load;
                }
                else
                {

                    // Send to unloadQueue list
                    loadingQueue.push(pointer);
                }
            }
        }

    }

    return;
}

void ResourceManager::unloadPack(const std::string& path, LoadMode mode)
{
    // Create a list from the parsePack
    ResourceDataList list = LuaParser::parsePack(path);

    // Iterate through the list
    for (ResourceDataList::iterator var = list.begin; var != list.end; ++var)
    {
        // Checking if resource exists in resources
        if (resources.find(var->alias) != resources.end())
        {
            // Assigns a new pointer to the key for the resource
            ResourcePtr pointer = resources.find(var->alias)->second;

            // Checking if the resource is loaded
            if (pointer->isLoaded == true)
            {
                // If the resource has to be unloaded immediately
                if (mode == LoadMode::Block)
                {
                    // Change the status of the BaseResource
                    pointer->setIsLoaded(false);
                    // Unload the BaseResource
                    pointer->unload;
                }
                else
                {
                   // Send to unloadQueue list
                    unloadQueue.push(pointer);
                }
            }
        }

    }

    return;

}

void ResourceManager::reloadPack(const std::string& path)
{

    // Create a list from the parsePack
    ResourceDataList list = LuaParser::parsePack(path);

    // Iterate through the list
    for (ResourceDataList::iterator var = list.begin; var != list.end; ++var)
    {
        // Assign the alias to a throw away string
        std::string name = var->alias;

        // Checking if resource exists in resource map
        if (resources.find(name) != resources.end())
        {
            // Assigns a new pointer to the key for the resource
            ResourcePtr res = resources.find(name)->second;

            // Send to reloadQueue
            reloadQueue.push(res);
        }
        else
        {
            Logger::logMessage("Reload resource warning: Resource not already loaded");

            // Create new resource anyway
            //loadingQueue.push(res);
            // Not quire sure how to handle this/if we're allowing them to load anyway
        }
    }
}

void ResourceManager::switchPack(const std::string& fromPath, const std::string& toPath)
{
    // Create a list from the parsePack for the current pack
    ResourceDataList from = LuaParser::parsePack(fromPath);

    // Create a list from the parsePack for the future Pack
    ResourceDataList tolist = LuaParser::parsePack(toPath);

    // Create a string vector to hold the common resources
    std::vector<std::string> common;

    // Load the future pack
    for (ResourceDataList::iterator var = tolist.begin; var != tolist.end; ++var)
    {

        // Checking if resource exists in resources
        if (resources.find(var->alias) != resources.end())
        {
            // Assigns a new pointer to the key for the resource
            ResourcePtr pointer = resources.find(var->alias)->second;

            // Checking if the resource is not loaded
            if (pointer->isLoaded == false)
            {
                // Change the status of the BaseResource
                pointer->setIsLoaded(true);
                // Send to unloadQueue list
                loadingQueue.push(pointer);
            }
            else
            {
                // Add the name to the vector
                common.push_back(var->alias);
            }
        }
    }

    // Iterate through the old Pack and remove the Resources that are not common to the pack and the vector
    for (ResourceDataList::iterator var = from.begin; var != from.end; ++var)
    {

        // Checking if resource is common to the string vector
        if (resources.find(var->alias) != resources.end())
        {

            if (std::find(common.begin(), common.end(), resources.find(var->alias) != common.end))
            {
                // The two entries are common - do nothing
            }
            else
            {
                // The two entries do not match - unload the old entry

                // Assigns a new pointer to the key for the resource
                ResourcePtr pointer = resources.find(var->alias)->second;

                // Send to unloadQueue list
                loadingQueue.push(pointer);
            }

        }
    }

}

void ResourceManager::init(bool _useNullForErrorRes)
{
    useNullForErrorRes = _useNullForErrorRes;

    if(!useNullForErrorRes)
    {
        // initPack("ResMan_DefaultError_Resources\ErrorResource_LuaFile.txt");
    }
}

void ResourceManager::update()
{
    loadFromQueue();
    unloadFromQueue();
    reloadFromQueue();
}

void ResourceManager::cleanupUnused()
{
    // run for each resource in list
    for(auto r : resources)
    {
        // if the resource pointer is unique
        if(r->second.unique())
        {
            // Log what resources were unloaded
            Logger::logMessage("Unloading Unused Resource: ", r->first);

            // Change resource status to false
            r->second->setIsLoaded(false);

            // unload resource
            r->second->unload();
        }
    }
}

bool ResourceManager::isLoading()
{
    return getNumToLoad() > 0;
}

size_t ResourceManager::getNumToLoad()//ResourceManager::getNumToLoad()
{
    return loadingQueue.size();
}

ResourceList ResourceManager::listAll()
{
    // create a temp list to add pointers
    ResourceList temp;

    // iterate through and add each pointer to the temp list
    for (ResourceLookup::iterator it = resources.begin; it != resources.end; ++it)
    {
        temp.push_back(it->second);
    }

    return temp;
}

size_t ResourceManager::getNumResources()
{
    return resources.size();
}

void ResourceManager::setLoadCompleteCallback(LoadCompleteCallback callback)
{
    loadCompleteCallback = callback;
}

void ResourceManager::loadFromQueue()
{
    while (loadingQueue.size() > 0)
    {
        // Check First res in the queue
        auto frontRes = loadingQueue.front();

        // Check to see if the resource is already loaded.
        if (frontRes->isLoaded)
        {
            // If its loaded delete from queue
            // Allow for another resource to be loaded if there are stil l more in the queue.
            loadingQueue.pop();
        }
        else
        {
            // Load the first resource and check if any errors
            if (frontRes->load())
            {
                // Set resource to is loaded
                frontRes->setIsLoaded(true);
                // Remove from loading queue
                loadingQueue.pop();
            }
            else
            {
                // Log Error
                Logger::logMessage("Load Resource Failed: ", frontRes->getAlias);
            }
            // Send load complete call back once the last item is loaded.
            if (loadingQueue.size() == 0)
            {
                loadCompleteCallback();
            }
            // break from loop so only one resource is loaded at a time.
            break;
        }
    }
}

void ResourceManager::unloadFromQueue()
{
    // Only run when queue is > 0
    while (unloadQueue.size() > 0)
    {
        // Check First res in the queue
        auto frontRes = unloadQueue.front();

        // Check to see if the resource is already unloaded.
        if (!frontRes->isLoaded)
        {
            // If its unloaded delete from queue
            // Allow for another resource to be unloaded if there are stil l more in the queue.
            unloadQueue.pop();
        }
        else
        {
            // Load the first resource and check if any errors
            if (frontRes->unload())
            {
                // Set resource to is unloaded
                frontRes->setIsLoaded(false);
                // Remove from unloadeding queue
                unloadQueue.pop();
            }
            else
            {
                // Log Error
                Logger::logMessage("Unload Resource Failed: ", frontRes->getAlias);
            }
            // break from loop so only one resource is unloaded at a time.
            break;
        }
    }
}

void ResourceManager::reloadFromQueue()
{
    if (reloadQueue.size() > 0)
    {
        // Check First res in the queue
        auto frontRes = reloadQueue.front();

        // Load the first resource and check if any errors
        if (frontRes->reload())
        {
            // Remove from reloading Queue
            reloadQueue.pop();
        }
        else
        {
            // Log Error
            Logger::logMessage("Reload Resource Failed: ", frontRes->getAlias);
        }
    }
}

} // rm
<|endoftext|>


<commit_before>// -*- c-basic-offset: 2; related-file-name: "duplicateConservative.h" -*-
/*
 * @(#)$Id$
 *
 * This file is distributed under the terms in the attached INTEL-LICENSE file.
 * If you do not find these files, copies can be found by writing to:
 * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300,
 * Berkeley, CA, 94704.  Attention:  Intel License Inquiry.
 *
 */

#include "duplicateConservative.h"

DuplicateConservative::DuplicateConservative(str name, int outputs)
  : Element(name, 1, outputs),
    _push_cb(cbv_null),
    _block_flags(),
    _block_flag_count(0)
{
  // Clean out the block flags
  _block_flags.zsetsize(noutputs());
}

void DuplicateConservative::unblock(int output)
{
  assert((output >= 0) &&
         (output <= noutputs()));

  // Unset a blocked output
  if (_block_flags[output]) {
    log(LoggerI::INFO, -1, strbuf("unblock ") << output);

    _block_flags[output] = false;
    _block_flag_count--;
    assert(_block_flag_count >= 0);
  }

  // If I have no more blocked outputs, unblock my pusher
  if (_block_flag_count == 0) {
    //assert(_push_cb != cbv_null);
    log(LoggerI::INFO, -1, "unblock: propagating aggregate unblock");
    _push_cb();
    _push_cb = cbv_null;
  }
}

int DuplicateConservative::push(int port, TupleRef p, cbv cb)
{
  assert(p != 0);
  assert(port == 0);

  // Can I take more?
  if (_block_flag_count > 0) {
    // I'm still blocked
    assert(_push_cb != cbv_null);
    log(LoggerI::WARN, -1, "push: Overrun");
    return 0;
  }

  // We're free and clear
  assert(_block_flag_count == 0);
  assert(_push_cb == cbv_null);

  // For every output
  for (int i = 0;
       i < noutputs();
       i++) {
    // Send it with the appropriate callback
    int result = output(i)->push(p, wrap(this, &DuplicateConservative::unblock, i));

    assert(_block_flags[i] == false);

    // If it can take no more
    if (result == 0) {
      // update the flags
      _block_flags[i] = true;
      _block_flag_count++;
    }
  }

  // If I just blocked any of my outputs, push back my input
  if (_block_flag_count > 0) {
    _push_cb = cb;
    log(LoggerI::WARN, -1, "push: Blocking input");
    return 0;
  } else {
    return 1;
  }
}

<commit_msg>dupconservative<commit_after>// -*- c-basic-offset: 2; related-file-name: "duplicateConservative.h" -*-
/*
 * @(#)$Id$
 *
 * This file is distributed under the terms in the attached INTEL-LICENSE file.
 * If you do not find these files, copies can be found by writing to:
 * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300,
 * Berkeley, CA, 94704.  Attention:  Intel License Inquiry.
 *
 */

#include "duplicateConservative.h"

DuplicateConservative::DuplicateConservative(str name, int outputs)
  : Element(name, 1, outputs),
    _push_cb(cbv_null),
    _block_flags(),
    _block_flag_count(0)
{
  // Clean out the block flags
  _block_flags.zsetsize(noutputs());
}

void DuplicateConservative::unblock(int output)
{
  assert((output >= 0) &&
         (output <= noutputs()));

  // Unset a blocked output
  if (_block_flags[output]) {
    log(LoggerI::INFO, -1, strbuf("unblock ") << output);

    _block_flags[output] = false;
    _block_flag_count--;
    assert(_block_flag_count >= 0);
  }

  // If I have no more blocked outputs, unblock my pusher
  if (_block_flag_count == 0) {
   log(LoggerI::INFO, -1, str(strbuf() << "unblock: propagating aggregate unblock " << output));
   //assert(_push_cb != cbv_null);
     _push_cb();
    _push_cb = cbv_null;
  }
}

int DuplicateConservative::push(int port, TupleRef p, cbv cb)
{
  assert(p != 0);
  assert(port == 0);

  // Can I take more?
  if (_block_flag_count > 0) {
    // I'm still blocked
    assert(_push_cb != cbv_null);
    log(LoggerI::WARN, -1, "push: Overrun");
    return 0;
  }

  // We're free and clear
  assert(_block_flag_count == 0);
  assert(_push_cb == cbv_null);

  // For every output
  for (int i = 0;
       i < noutputs();
       i++) {
    // Send it with the appropriate callback
    int result = output(i)->push(p, wrap(this, &DuplicateConservative::unblock, i));

    assert(_block_flags[i] == false);

    // If it can take no more
    if (result == 0) {
      // update the flags
      _block_flags[i] = true;
      _block_flag_count++;
    }
  }

  // If I just blocked any of my outputs, push back my input
  if (_block_flag_count > 0) {
    _push_cb = cb;
    log(LoggerI::WARN, -1, "push: Blocking input");
    return 0;
  } else {
    return 1;
  }
}

<|endoftext|>


<commit_before>/************************************************************
COSC 501
Elliott Plack
19 NOV 2013                                   Due 25 NOV 2013
Problem: Create a 1-dimensional array with n elements; get
	the size of the array as user input (validate!), max size
	should be 10 (declared as class constant). Perform a
	variety of functions with the array.
Algorithm: Get array size from user, validate, get values,
	perform functions.
************************************************************/
#include <iostream>
#include <iomanip>
using namespace std;

// various array handling functions
float average(float numbers[], int arraySize);
void even(float numbers[], int arraySize);
void odd(float numbers[], int arraySize);
float evenSum(float numbers[], int arraySize);
float oddSum(float numbers[], int arraySize);

int main()
{
	// intro

	cout << "This program does a variety of calculations on an array.\n";

	// do loop around entire program

	char continueQuestion = 'Y'; // check if user wants to run or repeat
	cout << "Do you want to start? (Y/N): ";
	cin >> continueQuestion;
	while (continueQuestion == 'Y' || continueQuestion == 'y')
	{
		// variables

		int arraySize = 0; // size of the array
		const int maxArraySize = 10; // max size of the array
		float averageNum(0), evenSumNum(0), oddSumNum(0); // variables that returns will be stored in

		// array size determination

		cout << "\nEnter the size of the array up to 10.\n";
		while (!(cin >> arraySize) || arraySize < 1 || arraySize > maxArraySize) // validate
		{
			cin.clear();     // Clear the error flags
			cin.ignore(100, '\n');    // Remove unwanted characters from buffer
			cout << "\aEnter a positive integer, less than 10: ";   // Re-issue the prompt
		}
		cout << "\nNow enter the " << arraySize << " values.\n";

		// set up array

		float *numbers;
		numbers = new float[arraySize]; // declare numbers array with 'elements' (n) positions

		// loop to fill array

		for (int i = 0; i < arraySize; i++)
		{
			cout << (i + 1) << ": "; // display the iterator + 1 since it begins as 0
			while ((!(cin >> numbers[i]))) //detects errors in input
			{
				cin.clear();     // Clear the error flags
				cin.ignore(100, '\n');    // Remove unwanted characters from buffer
				cout << "\aInput Error. Please enter a number only.\n"; // if error, sound the alarm
				cout << (i + 1) << ": ";
			}
		}

		// display array

		cout << "\nThe array elements are:\n";
		cout << "   "; // indent separator for clarity
		for (int i = 0; i < arraySize; i++) // test loop to output variables in positions
		{
			cout << numbers[i] << "   "; // space separated
		}

		cout << endl; // break in output

		// output average

		averageNum = average(numbers, arraySize);
		cout << "\nThe average value =    " << averageNum << endl;

		// even subscripts

		even(numbers, arraySize);

		// even sum

		cout << "\nThe sum of the elements with even subscripts = " << evenSum(numbers, arraySize) << endl;

		// odd subscripts

		odd(numbers, arraySize);

		// odd sum

		cout << "\nThe sum of the elements with odd subscripts = " << oddSum(numbers, arraySize) << endl;

		// repeat?

		cout << "\nDo you want to continue? (Y/N):";
		cin >> continueQuestion;
	}

	return 0;
}

float average(float numbers[], int arraySize)
{
	float sum(0), average(0); // define variables
	for (int i = 0; i < arraySize; i++)
	{
		sum += numbers[i];
	}
	average = (sum / arraySize);
	return average;
}

void even(float numbers[], int arraySize) // display even values
{
	int temp = 0;

	// format output
	cout << "\nThe elements with even subscripts are:\n"
		 << "Index   Value\n"
		 << "=============\n";

	// even check subs
	for (int i = 0; i < arraySize; i++)
	{
		temp = (int)numbers[i] % 2; // if integer version of value in numbers array is even..
		if (temp == 0)
			cout << setw(5) << (i+1) << setw(8) << numbers[i] << endl; // output the value
	}
}
void odd(float numbers[], int arraySize) // display odd values
{
	int temp = 0;

	// format output
	cout << "\nThe elements with odd subscripts are:\n"
		<< "Index   Value\n"
		<< "=============\n";

	// even check subs
	for (int i = 0; i < arraySize; i++)
	{
		temp = (int)numbers[i] % 2; // if integer version of value in numbers array is odd..
		if (temp != 0)
			cout << setw(5) << (i+1) << setw(8) << numbers[i] << endl; // output the value
	}
}
float evenSum(float numbers[], int arraySize) // return even sums
{
	int temp = 0;
	float sum(0), average(0); // define variables
	for (int i = 0; i < arraySize; i++)
	{
		temp = (int)numbers[i] % 2; // find mod array index div by 2
		if (temp == 0)
			sum += numbers[i]; // if mod is zero (even) add to sum)
	}

	return sum;
}
float oddSum(float numbers[], int arraySize) // return odd sums
{
	int temp = 0;
	float sum(0), average(0); // define variables
	for (int i = 0; i < arraySize; i++)
	{
		temp = (int)numbers[i] % 2; // find mod array index div by 2
		if (temp != 0)
			sum += numbers[i]; // if mod is not zero (odd) add to sum)
	}

	return sum;
}<commit_msg>built in xCode<commit_after>/************************************************************
COSC 501
Elliott Plack
19 NOV 2013                                   Due 25 NOV 2013
Problem: Create a 1-dimensional array with n elements; get
	the size of the array as user input (validate!), max size
	should be 10 (declared as class constant). Perform a
	variety of functions with the array.
Algorithm: Get array size from user, validate, get values,
	perform functions.
************************************************************/
#include <iostream>
#include <iomanip>
using namespace std;

// various array handling functions
float average(float numbers[], int arraySize);
void even(float numbers[], int arraySize);
void odd(float numbers[], int arraySize);
float evenSum(float numbers[], int arraySize);
float oddSum(float numbers[], int arraySize);

int main()
{
	// intro

	cout << "This program does a variety of calculations on an array.\n";

	// do loop around entire program

	char continueQuestion = 'Y'; // check if user wants to run or repeat
	cout << "Do you want to start? (Y/N): ";
	cin >> continueQuestion;
	while (continueQuestion == 'Y' || continueQuestion == 'y')
	{
		// variables

		int arraySize = 0; // size of the array
		const int maxArraySize = 10; // max size of the array
		float averageNum(0); // variables that returns will be stored in

		// array size determination

		cout << "\nEnter the size of the array up to 10.\n";
		while (!(cin >> arraySize) || arraySize < 1 || arraySize > maxArraySize) // validate
		{
			cin.clear();     // Clear the error flags
			cin.ignore(100, '\n');    // Remove unwanted characters from buffer
			cout << "\aEnter a positive integer, less than 10: ";   // Re-issue the prompt
		}
		cout << "\nNow enter the " << arraySize << " values.\n";

		// set up array

		float *numbers;
		numbers = new float[arraySize]; // declare numbers array with 'elements' (n) positions

		// loop to fill array

		for (int i = 0; i < arraySize; i++)
		{
			cout << (i + 1) << ": "; // display the iterator + 1 since it begins as 0
			while ((!(cin >> numbers[i]))) //detects errors in input
			{
				cin.clear();     // Clear the error flags
				cin.ignore(100, '\n');    // Remove unwanted characters from buffer
				cout << "\aInput Error. Please enter a number only.\n"; // if error, sound the alarm
				cout << (i + 1) << ": ";
			}
		}

		// display array

		cout << "\nThe array elements are:\n";
		cout << "   "; // indent separator for clarity
		for (int i = 0; i < arraySize; i++) // test loop to output variables in positions
		{
			cout << numbers[i] << "   "; // space separated
		}

		cout << endl; // break in output

		// output average

		averageNum = average(numbers, arraySize);
		cout << "\nThe average value =    " << averageNum << endl;

		// even subscripts

		even(numbers, arraySize);

		// even sum

		cout << "\nThe sum of the elements with even subscripts = " << evenSum(numbers, arraySize) << endl;

		// odd subscripts

		odd(numbers, arraySize);

		// odd sum

		cout << "\nThe sum of the elements with odd subscripts = " << oddSum(numbers, arraySize) << endl;

		// repeat?

		cout << "\nDo you want to continue? (Y/N):";
		cin >> continueQuestion;
	}

	return 0;
}

float average(float numbers[], int arraySize)
{
	float sum(0), average(0); // define variables
	for (int i = 0; i < arraySize; i++)
	{
		sum += numbers[i];
	}
	average = (sum / arraySize);
	return average;
}

void even(float numbers[], int arraySize) // display even values
{
	int temp = 0;

	// format output
	cout << "\nThe elements with even subscripts are:\n"
		 << "Index   Value\n"
		 << "=============\n";

	// even check subs
	for (int i = 0; i < arraySize; i++)
	{
		temp = (int)numbers[i] % 2; // if integer version of value in numbers array is even..
		if (temp == 0)
			cout << setw(5) << (i+1) << setw(8) << numbers[i] << endl; // output the value
	}
}
void odd(float numbers[], int arraySize) // display odd values
{
	int temp = 0;

	// format output
	cout << "\nThe elements with odd subscripts are:\n"
		<< "Index   Value\n"
		<< "=============\n";

	// even check subs
	for (int i = 0; i < arraySize; i++)
	{
		temp = (int)numbers[i] % 2; // if integer version of value in numbers array is odd..
		if (temp != 0)
			cout << setw(5) << (i+1) << setw(8) << numbers[i] << endl; // output the value
	}
}
float evenSum(float numbers[], int arraySize) // return even sums
{
	int temp = 0;
	float sum(0); // define variables
	for (int i = 0; i < arraySize; i++)
	{
		temp = (int)numbers[i] % 2; // find mod array index div by 2
		if (temp == 0)
			sum += numbers[i]; // if mod is zero (even) add to sum)
	}

	return sum;
}
float oddSum(float numbers[], int arraySize) // return odd sums
{
	int temp = 0;
	float sum(0); // define variables
	for (int i = 0; i < arraySize; i++)
	{
		temp = (int)numbers[i] % 2; // find mod array index div by 2
		if (temp != 0)
			sum += numbers[i]; // if mod is not zero (odd) add to sum)
	}

	return sum;
}<|endoftext|>


<commit_before>class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> res;
        multimap<int,int> nums_map;
        for(unsigned int i=0; i < nums.size();++i)
        {
            nums_map.insert(make_pair(nums.at(i),i));
        }
        for(unsigned int i = 0; i < nums.size(); ++i)
        {
            int other = target-nums.at(i), pos = -1;
            auto check = nums_map.equal_range(other);
            for(auto j = check.first; j != check.second; ++j)
            {
                if((*j).second != i)
                    pos = j->second;
            }
            if(pos != -1)
            {
                res.push_back(i+1);
                res.push_back(pos+1);
                break;
            }
        }
        return res;
    }
};
<commit_msg>Update 1.cpp<commit_after>class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> res;
        multimap<int,int> nums_map;
        for(unsigned int i=0; i < nums.size();++i)
        {
            nums_map.insert(make_pair(nums.at(i),i));
        }
        for(unsigned int i = 0; i < nums.size(); ++i)
        {
            int other = target-nums.at(i), pos = -1;
            auto check = nums_map.equal_range(other);
            for(auto j = check.first; j != check.second; ++j)
            {
                if((*j).second != i)
                    pos = j->second;
            }
            if(pos != -1)
            {
                res.push_back(i+1);
                res.push_back(pos+1);
                break;
            }
        }
        return res;
    }
};

<|endoftext|>


<commit_before>/**
 * Zillians MMO
 * Copyright (C) 2007-2011 Zillians.com, Inc.
 * For more information see http://www.zillians.com
 *
 * Zillians MMO is the library and runtime for massive multiplayer online game
 * development in utility computing model, which runs as a service for every
 * developer to build their virtual world running on our GPU-assisted machines.
 *
 * This is a close source library intended to be used solely within Zillians.com
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "language/stage/serialization/detail/ASTSerializationHelper.h"
#include "language/stage/serialization/visitor/ASTDeserializationStageVisitor.h"
#include "language/stage/serialization/visitor/ASTSerializationStageVisitor.h"

namespace zillians { namespace language { namespace stage {

bool ASTSerializationHelper::serialize(const std::string& filename, tree::ASTNode* node)
{
    std::ofstream ofs(filename);
    if(!ofs.good()) return false;

    // serialize through boost archive
    boost::archive::text_oarchive oa(ofs);
    tree::ASTNode* to_serialize = node;
    oa << to_serialize;

	// de-serialize all objects attached to ContextHub
	// see ASTSerializationStageVisitor::FullDeserializer, which defines the context object types needed to be serialized
    visitor::ASTSerializationStageVisitor<boost::archive::text_oarchive> serialzer(oa);
    serialzer.visit(*to_serialize);
}

tree::ASTNode* ASTSerializationHelper::deserialize(const std::string& filename)
{
	std::ifstream ifs(filename);
	if(!ifs.good()) return NULL;

	// de-serialize through boost archive
	boost::archive::text_iarchive ia(ifs);
	tree::ASTNode* from_serialize = NULL;
	ia >> from_serialize;

	// de-serialize all objects attached to ContextHub
	// see ASTDeserializationStageVisitor::FullDeserializer, which defines the context object types needed to be de-serialized
	visitor::ASTDeserializationStageVisitor<boost::archive::text_iarchive> deserialzer(ia);
	deserialzer.visit(*from_serialize);

	return from_serialize;
}

} } }
<commit_msg>fix serialization bug<commit_after>/**
 * Zillians MMO
 * Copyright (C) 2007-2011 Zillians.com, Inc.
 * For more information see http://www.zillians.com
 *
 * Zillians MMO is the library and runtime for massive multiplayer online game
 * development in utility computing model, which runs as a service for every
 * developer to build their virtual world running on our GPU-assisted machines.
 *
 * This is a close source library intended to be used solely within Zillians.com
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include <boost/serialization/export.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include "language/stage/serialization/detail/ASTSerializationHelper.h"
#include "language/stage/serialization/visitor/ASTDeserializationStageVisitor.h"
#include "language/stage/serialization/visitor/ASTSerializationStageVisitor.h"

BOOST_CLASS_EXPORT_GUID(zillians::language::tree::ASTNode               , "ASTNode")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::Annotation            , "Annotation")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::Annotations           , "Annotations")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::Internal              , "Internal")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::Program               , "Program")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::Package               , "Package")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::Import                , "Import")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::Block                 , "Block")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::Identifier            , "Identifier")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::SimpleIdentifier      , "SimpleIdentifier")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::NestedIdentifier      , "NestedIdentifier")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::TemplatedIdentifier   , "TemplatedIdent")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::Literal               , "Literal")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::NumericLiteral        , "NumericLiteral")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::StringLiteral         , "StringLiteral")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::ObjectLiteral         , "ObjectLiteral")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::TypeSpecifier         , "TypeSpecifier")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::FunctionType          , "FunctionType")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::Declaration           , "Declaration")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::ClassDecl             , "ClassDecl")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::EnumDecl              , "EnumDecl")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::InterfaceDecl         , "InterfaceDecl")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::TypedefDecl           , "TypedefDecl")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::FunctionDecl          , "FunctionDecl")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::VariableDecl          , "VariableDecl")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::Statement             , "Statement")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::DeclarativeStmt       , "DeclarativeStm")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::ExpressionStmt        , "ExpressionStmt")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::IterativeStmt         , "IterativeStmt")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::ForStmt               , "ForStmt")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::ForeachStmt           , "ForeachStmt")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::WhileStmt             , "WhileStmt")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::SelectionStmt         , "SelectionStmt")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::IfElseStmt            , "IfElseStmt")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::SwitchStmt            , "SwitchStmt")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::BranchStmt            , "BranchStmt")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::Expression            , "Expression")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::PrimaryExpr           , "PrimaryExpr")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::UnaryExpr             , "UnaryExpr")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::BinaryExpr            , "BinaryExpr")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::TernaryExpr           , "TernaryExpr")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::MemberExpr            , "MemberExpr")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::CallExpr              , "CallExpr")
BOOST_CLASS_EXPORT_GUID(zillians::language::tree::CastExpr              , "CastExpr")

namespace zillians { namespace language { namespace stage {

bool ASTSerializationHelper::serialize(const std::string& filename, tree::ASTNode* node)
{
    std::ofstream ofs(filename);
    if(!ofs.good()) return false;

    // serialize through boost archive
    boost::archive::text_oarchive oa(ofs);
    tree::ASTNode* to_serialize = node;
    oa << to_serialize;

	// de-serialize all objects attached to ContextHub
	// see ASTSerializationStageVisitor::FullDeserializer, which defines the context object types needed to be serialized
    visitor::ASTSerializationStageVisitor<boost::archive::text_oarchive> serialzer(oa);
    serialzer.visit(*to_serialize);
}

tree::ASTNode* ASTSerializationHelper::deserialize(const std::string& filename)
{
	std::ifstream ifs(filename);
	if(!ifs.good()) return NULL;

	// de-serialize through boost archive
	boost::archive::text_iarchive ia(ifs);
	tree::ASTNode* from_serialize = NULL;
	ia >> from_serialize;

	// de-serialize all objects attached to ContextHub
	// see ASTDeserializationStageVisitor::FullDeserializer, which defines the context object types needed to be de-serialized
	visitor::ASTDeserializationStageVisitor<boost::archive::text_iarchive> deserialzer(ia);
	deserialzer.visit(*from_serialize);

	return from_serialize;
}

} } }
<|endoftext|>


<commit_before><commit_msg>editeng: Avoid calling expensive getLineBreak() if possible<commit_after><|endoftext|>