<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkBandedPolyDataContourFilter.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-2001 Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

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

=========================================================================*/
#include "vtkBandedPolyDataContourFilter.h"
#include "vtkEdgeTable.h"
#include "vtkFloatArray.h"
#include "vtkObjectFactory.h"

//-------------------------------------------------------------------------
vtkBandedPolyDataContourFilter* vtkBandedPolyDataContourFilter::New()
{
  // First try to create the object from the vtkObjectFactory
  vtkObject* ret = vtkObjectFactory::CreateInstance("vtkBandedPolyDataContourFilter");
  if(ret)
    {
    return (vtkBandedPolyDataContourFilter*)ret;
    }
  // If the factory was unable to create the object, then create it here.
  return new vtkBandedPolyDataContourFilter;
}

// Construct object.
vtkBandedPolyDataContourFilter::vtkBandedPolyDataContourFilter()
{
  this->ContourValues = vtkContourValues::New();
}

vtkBandedPolyDataContourFilter::~vtkBandedPolyDataContourFilter()
{
  this->ContourValues->Delete();
}

int vtkBandedPolyDataContourFilter::ComputeScalarIndex(float val)
{
  for (int i=0; i < (this->NumberOfClipValues-1); i++)
    {
    if ( val >= this->ClipValues[i] && val < this->ClipValues[i+1]  )
      {
      return i;
      }
    }
  return 0;
}

int vtkBandedPolyDataContourFilter::ClipEdge(int v1, int v2,
                                             vtkPoints *newPts,
                                             vtkDataArray *scalars,
                                             vtkPointData *inPD,
                                             vtkPointData *outPD)
{
  float x[3];
  int ptId;

  float s1 = scalars->GetTuple(v1)[0];
  float s2 = scalars->GetTuple(v2)[0];

  int idx1 = this->ComputeScalarIndex(s1);
  int idx2 = this->ComputeScalarIndex(s2);

  float *x1 = newPts->GetPoint(v1);
  float *x2 = newPts->GetPoint(v2);

  this->PtIds[0] = v1;
  this->PtIds[idx2-idx1+1] = v2;
  this->T[0] = 0.0;
  this->T[idx2-idx1+1] = 1.0;

  for (int i=1; i < (idx2-idx1); i++)
    {
    this->T[i] = (this->ClipValues[idx1+i] - s1) / (s2 - s1);
    x[0] = x1[0] + this->T[i]*(x2[0]-x1[0]);
    x[1] = x1[1] + this->T[i]*(x2[1]-x1[1]);
    x[2] = x1[2] + this->T[i]*(x2[2]-x1[2]);
    ptId = this->PtIds[i] = newPts->InsertNextPoint(x);
    outPD->InterpolateEdge(inPD,ptId,v1,v2,this->T[i]);
    }

  return (idx2-idx1+1);
}

extern "C" {
int vtkCompareContourValues(const void *val1, const void *val2)
{
  if ( *((float*)val1) < *((float*)val2) ) {return (-1);}
  else if ( *((float*)val1) > *((float*)val2) ) {return (1);}
  else {return (0);}
}
}

// Create filled contours for polydata
void vtkBandedPolyDataContourFilter::Execute()
{
  vtkPolyData *input = this->GetInput();
  vtkPointData *pd = input->GetPointData();
  vtkCellData *cd = input->GetCellData();
  vtkPolyData *output = this->GetOutput();
  vtkPointData *outPD = input->GetPointData();
  vtkCellData *outCD = input->GetCellData();
  vtkPoints *inPts = input->GetPoints();
  vtkDataArray *inScalars = pd->GetScalars();
  int numPts, numCells;
  int cellNum, abort;
  vtkEdgeTable *edgeTable;
  vtkPoints *newPts;
  vtkCellArray *newLines, *newPolys;
  int i, j, idx, npts, cellId=0, ptId=0;
  vtkIdType *pts;
  int cellScalar;

  vtkDebugMacro(<<"Executing edge extractor");

  //  Check input
  //
  numPts = inPts->GetNumberOfPoints();
  numCells = input->GetNumberOfCells();
  if ( numCells < 1 || numPts < 1 )
    {
    vtkErrorMacro(<<"No input data!");
    return;
    }

  // Set up supplemental data structures for processing edge/generating
  // intersections. First we sort the contour values into an ascending
  // list of clip values including the extreme min/max values.
  this->NumberOfClipValues = this->ContourValues->GetNumberOfContours() + 2;
  this->ClipValues = new float[this->NumberOfClipValues];
  float range[2], tol;
  inScalars->GetRange(range); tol = (range[1]-range[0])/100.0;
  this->ClipValues[0] = range[0];
  this->ClipValues[1] = range[1];
  for ( i=2; i<this->NumberOfClipValues; i++)
    {
    this->ClipValues[i] = this->ContourValues->GetValue(i-2);
    }
  qsort((void *)this->ClipValues, this->NumberOfClipValues, sizeof(float),
        vtkCompareContourValues);
  for ( i=0; i<(this->NumberOfClipValues-1); i++)
    {
    if ( (this->ClipValues[i]+tol) >= this->ClipValues[i+1] )
      {
      for (j=i+1; j<(this->NumberOfClipValues-2); j++)
        {
        this->ClipValues[i+1] = this->ClipValues[i+2];
        }
      this->NumberOfClipValues--;
      }
    }

  //used for edge clipping
  this->PtIds = new int[this->NumberOfClipValues];
  this->T = new float[this->NumberOfClipValues];
  this->CellScalars = new int[this->NumberOfClipValues];

  // The original set of points and point data are copied. Later on
  // intersection points due to clipping will be created.
  newPts = vtkPoints::New();
  newPts->Allocate(3*numPts);
  outPD->CopyAllocate(pd,3*numPts,numPts);
  for (i=0; i<numPts; i++)
    {
    newPts->InsertPoint(i,inPts->GetPoint(i));
    outPD->CopyData(pd, i, i);
    }

  // These are the new cell scalars
  vtkFloatArray *newScalars = vtkFloatArray::New();
  newScalars->Allocate(numCells*5,numCells);

  // All vertices are filled and passed through; poly-vertices are broken
  // into single vertices. Cell data per vertex is set.
  //
  if ( input->GetVerts()->GetNumberOfCells() > 0 )
    {
    int newId;
    vtkCellArray *verts = input->GetVerts();
    vtkCellArray *newVerts = vtkCellArray::New();
    newVerts->Allocate(verts->GetSize());
    for ( verts->InitTraversal(); verts->GetNextCell(npts,pts); )
      {
      for (i=0; i<npts; i++)
        {
        newId = newVerts->InsertNextCell(1,pts+i);
        idx = this->ComputeScalarIndex(inScalars->GetTuple(pts[i])[0]);
        newScalars->InsertTuple1(newId,idx);
        }
      }
    output->SetVerts(newVerts);
    newVerts->Delete();
    }

  // Lines are chopped into line segments.
  //
  if ( input->GetLines()->GetNumberOfCells() > 0 )
    {
    int numSegments;
    int newId, newIds[2];
    vtkCellArray *lines = input->GetLines();
    vtkCellArray *newLines = vtkCellArray::New();
    newLines->Allocate(lines->GetSize());
    for ( lines->InitTraversal(); lines->GetNextCell(npts,pts); )
      {
      for (i=0; i<(npts-1); i++)
        {
        if ( pts[i] < pts[i+1] )
          {
          numSegments = this->ClipEdge(pts[i],pts[i+1],newPts,inScalars,
                                       pd,outPD);
          }
        else
          {
          numSegments = this->ClipEdge(pts[i+1],pts[i],newPts,inScalars,
                                       pd,outPD);
          }
        for (j=0; j<numSegments; j++)
          {
          newId = newLines->InsertNextCell(2,this->PtIds+j);
          newScalars->InsertTuple1(newId,this->CellScalars[j]);
          }
        }
      }
    }

  // Polygons are assumed convex and chopped into filled, convex polygons.
  //
  if ( input->GetLines()->GetNumberOfCells() > 0 )
    {

    // Set up processing. We are going to store an ordered list of
    // intersections along each edge (ordered from smallest point id
    // to largest). These will later be connected into convex polygons
    // which represent a filled region in the cell.
    //
    edgeTable = vtkEdgeTable::New();
    edgeTable->InitEdgeInsertion(numPts,1); //store attributes on

    }

  // Triangle are assumed convex and chopped into filled, convex polygons.
  //
  if ( input->GetLines()->GetNumberOfCells() > 0 )
    {
    }

  newLines = vtkCellArray::New();
  newLines->EstimateSize(numPts*4,2);

  pd = input->GetPointData();
  outPD = output->GetPointData();
  outPD->CopyAllocate(pd,numPts);

  cd = input->GetCellData();
  outCD = output->GetCellData();
  outCD->CopyAllocate(cd,numCells);

  vtkDebugMacro(<<"Created " << newLines->GetNumberOfCells() << " edges");

  //  Update ourselves.
  //
  edgeTable->Delete();
  output->Squeeze();
}

unsigned long int vtkBandedPolyDataContourFilter::GetMTime()
{
  unsigned long mTime=this-> vtkPolyDataToPolyDataFilter::GetMTime();
  unsigned long time;

  time = this->ContourValues->GetMTime();
  mTime = ( time > mTime ? time : mTime );

  return mTime;
}

void vtkBandedPolyDataContourFilter::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkPolyDataToPolyDataFilter::PrintSelf(os,indent);

  this->ContourValues->PrintSelf(os,indent);
}

<commit_msg>ENH:Another snapshot for Jeff<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkBandedPolyDataContourFilter.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-2001 Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

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

=========================================================================*/
#include "vtkBandedPolyDataContourFilter.h"
#include "vtkEdgeTable.h"
#include "vtkFloatArray.h"
#include "vtkObjectFactory.h"

//-------------------------------------------------------------------------
vtkBandedPolyDataContourFilter* vtkBandedPolyDataContourFilter::New()
{
  // First try to create the object from the vtkObjectFactory
  vtkObject* ret = vtkObjectFactory::CreateInstance("vtkBandedPolyDataContourFilter");
  if(ret)
    {
    return (vtkBandedPolyDataContourFilter*)ret;
    }
  // If the factory was unable to create the object, then create it here.
  return new vtkBandedPolyDataContourFilter;
}

// Construct object.
vtkBandedPolyDataContourFilter::vtkBandedPolyDataContourFilter()
{
  this->ContourValues = vtkContourValues::New();
}

vtkBandedPolyDataContourFilter::~vtkBandedPolyDataContourFilter()
{
  this->ContourValues->Delete();
}

int vtkBandedPolyDataContourFilter::ComputeScalarIndex(float val)
{
  for (int i=0; i < (this->NumberOfClipValues-1); i++)
    {
    if ( val >= this->ClipValues[i] && val < this->ClipValues[i+1]  )
      {
      return i;
      }
    }
  return (this->NumberOfClipValues - 2); //on the end point
}

int vtkBandedPolyDataContourFilter::ClipEdge(int v1, int v2,
                                             vtkPoints *newPts,
                                             vtkDataArray *scalars,
                                             vtkPointData *inPD,
                                             vtkPointData *outPD)
{
  float x[3];
  int ptId;

  float s1 = scalars->GetTuple(v1)[0];
  float s2 = scalars->GetTuple(v2)[0];

  int idx1 = this->ComputeScalarIndex(s1);
  int idx2 = this->ComputeScalarIndex(s2);

  float *x1 = newPts->GetPoint(v1);
  float *x2 = newPts->GetPoint(v2);

  this->PtIds[0] = v1;
  this->PtIds[idx2-idx1+1] = v2;
  this->T[0] = 0.0;
  this->T[idx2-idx1+1] = 1.0;
  this->CellScalars[0] = idx1;

  for (int i=1; i < (idx2-idx1); i++)
    {
    this->T[i] = (this->ClipValues[idx1+i] - s1) / (s2 - s1);
    x[0] = x1[0] + this->T[i]*(x2[0]-x1[0]);
    x[1] = x1[1] + this->T[i]*(x2[1]-x1[1]);
    x[2] = x1[2] + this->T[i]*(x2[2]-x1[2]);
    ptId = this->PtIds[i] = newPts->InsertNextPoint(x);
    outPD->InterpolateEdge(inPD,ptId,v1,v2,this->T[i]);
    this->CellScalars[i] = idx1 + i;
    }

  return (idx2-idx1+1);
}

extern "C" {
int vtkCompareContourValues(const void *val1, const void *val2)
{
  if ( *((float*)val1) < *((float*)val2) )
    {
    return (-1);
    }
  else if ( *((float*)val1) > *((float*)val2) )
    {
    return (1);
    }
  else
    {
    return (0);
    }
}
}

// Create filled contours for polydata
void vtkBandedPolyDataContourFilter::Execute()
{
  vtkPolyData *input = this->GetInput();
  vtkPointData *pd = input->GetPointData();
  vtkCellData *cd = input->GetCellData();
  vtkPolyData *output = this->GetOutput();
  vtkPointData *outPD = input->GetPointData();
  vtkCellData *outCD = output->GetCellData();
  vtkPoints *inPts = input->GetPoints();
  vtkDataArray *inScalars = pd->GetScalars();
  int numPts, numCells;
  int cellNum, abort;
  vtkPoints *newPts;
  vtkCellArray *newLines, *newPolys;
  int i, j, idx, npts, cellId=0, ptId=0;
  vtkIdType *pts;
  int cellScalar;

  vtkDebugMacro(<<"Executing edge extractor");

  //  Check input
  //
  numPts = inPts->GetNumberOfPoints();
  numCells = input->GetNumberOfCells();
  if ( numCells < 1 || numPts < 1 )
    {
    vtkErrorMacro(<<"No input data!");
    return;
    }

  // Set up supplemental data structures for processing edge/generating
  // intersections. First we sort the contour values into an ascending
  // list of clip values including the extreme min/max values.
  this->NumberOfClipValues = this->ContourValues->GetNumberOfContours() + 2;
  this->ClipValues = new float[this->NumberOfClipValues];
  float range[2], tol;
  inScalars->GetRange(range); tol = (range[1]-range[0])/100.0;
  this->ClipValues[0] = range[0];
  this->ClipValues[1] = range[1];
  for ( i=2; i<this->NumberOfClipValues; i++)
    {
    this->ClipValues[i] = this->ContourValues->GetValue(i-2);
    }
  qsort((void *)this->ClipValues, this->NumberOfClipValues, sizeof(float),
        vtkCompareContourValues);
  for ( i=0; i<(this->NumberOfClipValues-1); i++)
    {
    if ( (this->ClipValues[i]+tol) >= this->ClipValues[i+1] )
      {
      for (j=i+1; j<(this->NumberOfClipValues-2); j++)
        {
        this->ClipValues[i+1] = this->ClipValues[i+2];
        }
      this->NumberOfClipValues--;
      }
    }

  //used for edge clipping
  this->PtIds = new int[this->NumberOfClipValues];
  this->T = new float[this->NumberOfClipValues];
  this->CellScalars = new int[this->NumberOfClipValues];

  // The original set of points and point data are copied. Later on
  // intersection points due to clipping will be created.
  newPts = vtkPoints::New();
  newPts->Allocate(3*numPts);
  outPD->CopyAllocate(pd,3*numPts,numPts);
  for (i=0; i<numPts; i++)
    {
    newPts->InsertPoint(i,inPts->GetPoint(i));
    outPD->CopyData(pd, i, i);
    }

  // These are the new cell scalars
  vtkFloatArray *newScalars = vtkFloatArray::New();
  newScalars->Allocate(numCells*5,numCells);

  // All vertices are filled and passed through; poly-vertices are broken
  // into single vertices. Cell data per vertex is set.
  //
  if ( input->GetVerts()->GetNumberOfCells() > 0 )
    {
    int newId;
    vtkCellArray *verts = input->GetVerts();
    vtkCellArray *newVerts = vtkCellArray::New();
    newVerts->Allocate(verts->GetSize());
    for ( verts->InitTraversal(); verts->GetNextCell(npts,pts); )
      {
      for (i=0; i<npts; i++)
        {
        newId = newVerts->InsertNextCell(1,pts+i);
        idx = this->ComputeScalarIndex(inScalars->GetTuple(pts[i])[0]);
        newScalars->InsertTuple1(newId,idx);
        }
      }
    output->SetVerts(newVerts);
    newVerts->Delete();
    }

  // Lines are chopped into line segments.
  //
  if ( input->GetLines()->GetNumberOfCells() > 0 )
    {
    int numSegments;
    int newId, newIds[2];
    vtkCellArray *lines = input->GetLines();
    vtkCellArray *newLines = vtkCellArray::New();
    newLines->Allocate(lines->GetSize());
    for ( lines->InitTraversal(); lines->GetNextCell(npts,pts); )
      {
      for (i=0; i<(npts-1); i++)
        {
        if ( pts[i] < pts[i+1] )
          {
          numSegments = this->ClipEdge(pts[i],pts[i+1],newPts,inScalars,
                                       pd,outPD);
          }
        else
          {
          numSegments = this->ClipEdge(pts[i+1],pts[i],newPts,inScalars,
                                       pd,outPD);
          }
        for (j=0; j<numSegments; j++)
          {
          newId = newLines->InsertNextCell(2,this->PtIds+j);
          newScalars->InsertTuple1(newId,this->CellScalars[j]);
          }
        }
      }
    }

  // Polygons are assumed convex and chopped into filled, convex polygons.
  // Triangle strips are treated similarly.
  //
  if ( input->GetPolys()->GetNumberOfCells() > 0 ||
       input->GetStrips()->GetNumberOfCells() > 0 )
    {

    // Set up processing. We are going to store an ordered list of
    // intersections along each edge (ordered from smallest point id
    // to largest). These will later be connected into convex polygons
    // which represent a filled region in the cell.
    //
    vtkEdgeTable *edgeTable;
    edgeTable = vtkEdgeTable::New();
    edgeTable->InitEdgeInsertion(numPts,1); //store attributes on

    edgeTable->Delete();
    }

  vtkDebugMacro(<<"Created " << output->GetVerts()->GetNumberOfCells()
                << " verts\n");
  vtkDebugMacro(<<"Created " << output->GetLines()->GetNumberOfCells()
                << " lines\n");
  vtkDebugMacro(<<"Created " << output->GetPolys()->GetNumberOfCells()
                << " polys\n");
  vtkDebugMacro(<<"Created " << output->GetStrips()->GetNumberOfCells()
                << " strips\n");

  //  Update ourselves and release temporary memory
  //
  delete [] this->PtIds;
  delete [] this->T;
  delete [] this->CellScalars;

  output->SetPoints(newPts);
  newPts->Delete();

  outCD->SetScalars(newScalars);
  newScalars->Delete();

  output->Squeeze();
}

unsigned long int vtkBandedPolyDataContourFilter::GetMTime()
{
  unsigned long mTime=this-> vtkPolyDataToPolyDataFilter::GetMTime();
  unsigned long time;

  time = this->ContourValues->GetMTime();
  mTime = ( time > mTime ? time : mTime );

  return mTime;
}

void vtkBandedPolyDataContourFilter::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkPolyDataToPolyDataFilter::PrintSelf(os,indent);

  this->ContourValues->PrintSelf(os,indent);
}

<|endoftext|>


<commit_before>#ifdef _RPI_
#include "components/VideoPlayerComponent.h"
#include <boost/algorithm/string/predicate.hpp>
#include "AudioManager.h"
#include "Renderer.h"
#include "ThemeData.h"
#include "Settings.h"
#include "Util.h"
#include <signal.h>
#include <wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <math.h>

class VolumeControl
{
public:
	static std::shared_ptr<VolumeControl> & getInstance();
	int getVolume() const;
};

VideoPlayerComponent::VideoPlayerComponent(Window* window, std::string path) :
	VideoComponent(window),
	mPlayerPid(-1),
	subtitlePath(path)
{
}

VideoPlayerComponent::~VideoPlayerComponent()
{
	stopVideo();
}

void VideoPlayerComponent::render(const Eigen::Affine3f& parentTrans)
{
	VideoComponent::render(parentTrans);

	if (!mIsPlaying || mPlayerPid == -1)
		VideoComponent::renderSnapshot(parentTrans);
}

void VideoPlayerComponent::setResize(float width, float height)
{
	setSize(width, height);
	mTargetSize << width, height;
	mTargetIsMax = false;
	mStaticImage.setSize(width, height);
	onSizeChanged();
}

void VideoPlayerComponent::setMaxSize(float width, float height)
{
	setSize(width, height);
	mTargetSize << width, height;
	mTargetIsMax = true;
	mStaticImage.setMaxSize(width, height);
	onSizeChanged();
}

void VideoPlayerComponent::startVideo()
{
	if (!mIsPlaying)
	{
		mVideoWidth = 0;
		mVideoHeight = 0;

		std::string path(mVideoPath.c_str());

		// Make sure we have a video path
		if ((path.size() > 0) && (mPlayerPid == -1))
		{
			// Set the video that we are going to be playing so we don't attempt to restart it
			mPlayingVideoPath = mVideoPath;

			// Disable AudioManager so video can play, in case we're requesting ALSA
			if (boost::starts_with(Settings::getInstance()->getString("OMXAudioDev").c_str(), "alsa"))
			{
				AudioManager::getInstance()->deinit();
			}

			// Start the player process
			pid_t pid = fork();
			if (pid == -1)
			{
				// Failed
				mPlayingVideoPath = "";
			}
			else if (pid > 0)
			{
				mPlayerPid = pid;
				// Update the playing state
				signal(SIGCHLD, catch_child);
				mIsPlaying = true;
				mFadeIn = 0.0f;
			}
			else
			{

				// Find out the pixel position of the video view and build a command line for
				// omxplayer to position it in the right place
				char buf[32];
				float x = mPosition.x() - (mOrigin.x() * mSize.x());
				float y = mPosition.y() - (mOrigin.y() * mSize.y());
				sprintf(buf, "%d,%d,%d,%d", (int)x, (int)y, (int)(x + mSize.x()), (int)(y + mSize.y()));
				// We need to specify the layer of 10000 or above to ensure the video is displayed on top
				// of our SDL display

				const char* argv[] = { "", "--layer", "10010", "--loop", "--no-osd", "--aspect-mode", "letterbox", "--vol", "0", "-o", "both","--win", buf, "--no-ghost-box", "", "", "", "", NULL };

				// check if we want to mute the audio
				if (!Settings::getInstance()->getBool("VideoAudio") || (float)VolumeControl::getInstance()->getVolume() == 0)
				{
					argv[8] = "-1000000";
				}
				else
				{
					float percentVolume = (float)VolumeControl::getInstance()->getVolume();
					int OMXVolume = (int)(log(percentVolume/100)*2000);
					argv[8] = std::to_string(OMXVolume).c_str();
				}

				// test if there's a path for possible subtitles, meaning we're a screensaver video
				if (!subtitlePath.empty())
				{
					// if we are rendering a screensaver

					// check if we want to stretch the image
					if (Settings::getInstance()->getBool("StretchVideoOnScreenSaver"))
					{
						argv[6] = "stretch";
					}

					if (Settings::getInstance()->getString("ScreenSaverGameInfo") != "never")
					{
						// if we have chosen to render subtitles
						argv[13] = "--subtitles";
						argv[14] = subtitlePath.c_str();
						argv[15] = mPlayingVideoPath.c_str();
					}
					else
					{
						// if we have chosen NOT to render subtitles in the screensaver
						argv[13] = mPlayingVideoPath.c_str();
					}
				}
				else
				{
					// if we are rendering a video gamelist
					if (!mTargetIsMax)
					{
						argv[6] = "stretch";
					}
					argv[13] = mPlayingVideoPath.c_str();
				}

				argv[10] = Settings::getInstance()->getString("OMXAudioDev").c_str();

				//const char* argv[] = args;
				const char* env[] = { "LD_LIBRARY_PATH=/opt/vc/libs:/usr/lib/omxplayer", NULL };

				// Redirect stdout
				int fdin = open("/dev/null", O_RDONLY);
				int fdout = open("/dev/null", O_WRONLY);
				dup2(fdin, 0);
				dup2(fdout, 1);
				// Run the omxplayer binary
				execve("/usr/bin/omxplayer.bin", (char**)argv, (char**)env);

				_exit(EXIT_FAILURE);
			}
		}
	}
}

void catch_child(int sig_num)
{
    /* when we get here, we know there's a zombie child waiting */
    int child_status;
    wait(&child_status);
}

void VideoPlayerComponent::stopVideo()
{
	mIsPlaying = false;
	mStartDelayed = false;

	// Stop the player process
	if (mPlayerPid != -1)
	{
		int status;
		kill(mPlayerPid, SIGKILL);
		waitpid(mPlayerPid, &status, WNOHANG);
		// Restart AudioManager
		if (boost::starts_with(Settings::getInstance()->getString("OMXAudioDev").c_str(), "alsa"))
		{
			AudioManager::getInstance()->init();
		}
		mPlayerPid = -1;
	}
}

#endif

<commit_msg>Second stab at normalizing volume scale for OMX Player<commit_after>#ifdef _RPI_
#include "components/VideoPlayerComponent.h"
#include <boost/algorithm/string/predicate.hpp>
#include "AudioManager.h"
#include "Renderer.h"
#include "ThemeData.h"
#include "Settings.h"
#include "Util.h"
#include <signal.h>
#include <wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <math.h>

class VolumeControl
{
public:
	static std::shared_ptr<VolumeControl> & getInstance();
	int getVolume() const;
};

VideoPlayerComponent::VideoPlayerComponent(Window* window, std::string path) :
	VideoComponent(window),
	mPlayerPid(-1),
	subtitlePath(path)
{
}

VideoPlayerComponent::~VideoPlayerComponent()
{
	stopVideo();
}

void VideoPlayerComponent::render(const Eigen::Affine3f& parentTrans)
{
	VideoComponent::render(parentTrans);

	if (!mIsPlaying || mPlayerPid == -1)
		VideoComponent::renderSnapshot(parentTrans);
}

void VideoPlayerComponent::setResize(float width, float height)
{
	setSize(width, height);
	mTargetSize << width, height;
	mTargetIsMax = false;
	mStaticImage.setSize(width, height);
	onSizeChanged();
}

void VideoPlayerComponent::setMaxSize(float width, float height)
{
	setSize(width, height);
	mTargetSize << width, height;
	mTargetIsMax = true;
	mStaticImage.setMaxSize(width, height);
	onSizeChanged();
}

void VideoPlayerComponent::startVideo()
{
	if (!mIsPlaying)
	{
		mVideoWidth = 0;
		mVideoHeight = 0;

		std::string path(mVideoPath.c_str());

		// Make sure we have a video path
		if ((path.size() > 0) && (mPlayerPid == -1))
		{
			// Set the video that we are going to be playing so we don't attempt to restart it
			mPlayingVideoPath = mVideoPath;

			// Disable AudioManager so video can play, in case we're requesting ALSA
			if (boost::starts_with(Settings::getInstance()->getString("OMXAudioDev").c_str(), "alsa"))
			{
				AudioManager::getInstance()->deinit();
			}

			// Start the player process
			pid_t pid = fork();
			if (pid == -1)
			{
				// Failed
				mPlayingVideoPath = "";
			}
			else if (pid > 0)
			{
				mPlayerPid = pid;
				// Update the playing state
				signal(SIGCHLD, catch_child);
				mIsPlaying = true;
				mFadeIn = 0.0f;
			}
			else
			{

				// Find out the pixel position of the video view and build a command line for
				// omxplayer to position it in the right place
				char buf[32];
				float x = mPosition.x() - (mOrigin.x() * mSize.x());
				float y = mPosition.y() - (mOrigin.y() * mSize.y());
				sprintf(buf, "%d,%d,%d,%d", (int)x, (int)y, (int)(x + mSize.x()), (int)(y + mSize.y()));
				// We need to specify the layer of 10000 or above to ensure the video is displayed on top
				// of our SDL display

				const char* argv[] = { "", "--layer", "10010", "--loop", "--no-osd", "--aspect-mode", "letterbox", "--vol", "0", "-o", "both","--win", buf, "--no-ghost-box", "", "", "", "", NULL };

				// check if we want to mute the audio
				if (!Settings::getInstance()->getBool("VideoAudio") || (float)VolumeControl::getInstance()->getVolume() == 0)
				{
					argv[8] = "-1000000";
				}
				else
				{
					float percentVolume = (float)VolumeControl::getInstance()->getVolume();
					int OMXVolume = (int)((percentVolume-98)*105);
					argv[8] = std::to_string(OMXVolume).c_str();
				}

				// test if there's a path for possible subtitles, meaning we're a screensaver video
				if (!subtitlePath.empty())
				{
					// if we are rendering a screensaver

					// check if we want to stretch the image
					if (Settings::getInstance()->getBool("StretchVideoOnScreenSaver"))
					{
						argv[6] = "stretch";
					}

					if (Settings::getInstance()->getString("ScreenSaverGameInfo") != "never")
					{
						// if we have chosen to render subtitles
						argv[13] = "--subtitles";
						argv[14] = subtitlePath.c_str();
						argv[15] = mPlayingVideoPath.c_str();
					}
					else
					{
						// if we have chosen NOT to render subtitles in the screensaver
						argv[13] = mPlayingVideoPath.c_str();
					}
				}
				else
				{
					// if we are rendering a video gamelist
					if (!mTargetIsMax)
					{
						argv[6] = "stretch";
					}
					argv[13] = mPlayingVideoPath.c_str();
				}

				argv[10] = Settings::getInstance()->getString("OMXAudioDev").c_str();

				//const char* argv[] = args;
				const char* env[] = { "LD_LIBRARY_PATH=/opt/vc/libs:/usr/lib/omxplayer", NULL };

				// Redirect stdout
				int fdin = open("/dev/null", O_RDONLY);
				int fdout = open("/dev/null", O_WRONLY);
				dup2(fdin, 0);
				dup2(fdout, 1);
				// Run the omxplayer binary
				execve("/usr/bin/omxplayer.bin", (char**)argv, (char**)env);

				_exit(EXIT_FAILURE);
			}
		}
	}
}

void catch_child(int sig_num)
{
    /* when we get here, we know there's a zombie child waiting */
    int child_status;
    wait(&child_status);
}

void VideoPlayerComponent::stopVideo()
{
	mIsPlaying = false;
	mStartDelayed = false;

	// Stop the player process
	if (mPlayerPid != -1)
	{
		int status;
		kill(mPlayerPid, SIGKILL);
		waitpid(mPlayerPid, &status, WNOHANG);
		// Restart AudioManager
		if (boost::starts_with(Settings::getInstance()->getString("OMXAudioDev").c_str(), "alsa"))
		{
			AudioManager::getInstance()->init();
		}
		mPlayerPid = -1;
	}
}

#endif

<|endoftext|>


<commit_before>/* Copyright (c) 2018-present Advanced Micro Devices, Inc.

 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 <hip/hip_runtime.h>

#include "hip_internal.hpp"

namespace hip {

// ================================================================================================
amd::HostQueue* Device::NullStream(bool skip_alloc) {
  amd::HostQueue* null_queue = null_stream_.asHostQueue(skip_alloc);
  if (null_queue == nullptr) {
    return nullptr;
  }
  // Wait for all active streams before executing commands on the default
  iHipWaitActiveStreams(null_queue);
  return null_queue;
}

}

hipError_t hipDeviceGet(hipDevice_t *device, int deviceId) {
  HIP_INIT_API(hipDeviceGet, device, deviceId);

  if (device != nullptr) {
    *device = deviceId;
  } else {
    HIP_RETURN(hipErrorInvalidValue);
  }

  HIP_RETURN(hipSuccess);
};

hipError_t hipDeviceTotalMem (size_t *bytes, hipDevice_t device) {

  HIP_INIT_API(hipDeviceTotalMem, bytes, device);

  if (device < 0 || static_cast<size_t>(device) >= g_devices.size()) {
    HIP_RETURN(hipErrorInvalidDevice);
  }

  if (bytes == nullptr) {
    HIP_RETURN(hipErrorInvalidValue);
  }

  auto* deviceHandle = g_devices[device]->devices()[0];
  const auto& info = deviceHandle->info();

  *bytes = info.globalMemSize_;

  HIP_RETURN(hipSuccess);
}

hipError_t hipDeviceComputeCapability(int *major, int *minor, hipDevice_t device) {

  HIP_INIT_API(hipDeviceComputeCapability, major, minor, device);

  if (device < 0 || static_cast<size_t>(device) >= g_devices.size()) {
    HIP_RETURN(hipErrorInvalidDevice);
  }

  if (major == nullptr || minor == nullptr) {
    HIP_RETURN(hipErrorInvalidValue);
  }

  auto* deviceHandle = g_devices[device]->devices()[0];
  const auto& info = deviceHandle->info();
  *major = info.gfxipMajor_;
  *minor = info.gfxipMinor_;

  HIP_RETURN(hipSuccess);
}

hipError_t hipDeviceGetCount(int* count) {
  HIP_INIT_API(hipDeviceGetCount, count);

  HIP_RETURN(ihipDeviceGetCount(count));
}

hipError_t ihipDeviceGetCount(int* count) {
  if (count == nullptr) {
    return hipErrorInvalidValue;
  }

  // Get all available devices
  *count = g_devices.size();

  if (*count < 1) {
    return hipErrorNoDevice;
  }

  return hipSuccess;
}

hipError_t hipDeviceGetName(char *name, int len, hipDevice_t device) {

  HIP_INIT_API(hipDeviceGetName, (void*)name, len, device);

  if (device < 0 || static_cast<size_t>(device) >= g_devices.size()) {
    HIP_RETURN(hipErrorInvalidDevice);
  }

  if (name == nullptr || len <= 0) {
    HIP_RETURN(hipErrorInvalidValue);
  }

  auto* deviceHandle = g_devices[device]->devices()[0];
  const auto& info = deviceHandle->info();
  const auto nameLen = ::strlen(info.boardName_);

  // Make sure that the size of `dest` is big enough to hold `src` including
  // trailing zero byte
  if (nameLen > (cl_uint)(len - 1)) {
    HIP_RETURN(hipErrorInvalidValue);
  }

  ::strncpy(name, info.boardName_, (nameLen + 1));

  HIP_RETURN(hipSuccess);
}

hipError_t hipGetDeviceProperties ( hipDeviceProp_t* props, hipDevice_t device ) {
  HIP_INIT_API(hipGetDeviceProperties, props, device);

  if (props == nullptr) {
    HIP_RETURN(hipErrorInvalidValue);
  }

  if (unsigned(device) >= g_devices.size()) {
    HIP_RETURN(hipErrorInvalidDevice);
  }
  auto* deviceHandle = g_devices[device]->devices()[0];

  hipDeviceProp_t deviceProps = {0};

  const auto& info = deviceHandle->info();
  ::strncpy(deviceProps.name, info.boardName_, 128);
  deviceProps.totalGlobalMem = info.globalMemSize_;
  deviceProps.sharedMemPerBlock = info.localMemSizePerCU_;
  deviceProps.regsPerBlock = info.availableSGPRs_;
  deviceProps.warpSize = info.wavefrontWidth_;
  deviceProps.maxThreadsPerBlock = info.maxWorkGroupSize_;
  deviceProps.maxThreadsDim[0] = info.maxWorkItemSizes_[0];
  deviceProps.maxThreadsDim[1] = info.maxWorkItemSizes_[1];
  deviceProps.maxThreadsDim[2] = info.maxWorkItemSizes_[2];
  deviceProps.maxGridSize[0] = INT32_MAX;
  deviceProps.maxGridSize[1] = INT32_MAX;
  deviceProps.maxGridSize[2] = INT32_MAX;
  deviceProps.clockRate = info.maxEngineClockFrequency_ * 1000;
  deviceProps.memoryClockRate = info.maxMemoryClockFrequency_ * 1000;
  deviceProps.memoryBusWidth = info.globalMemChannels_;
  deviceProps.totalConstMem = info.maxConstantBufferSize_;
  deviceProps.major = info.gfxipMajor_;
  deviceProps.minor = info.gfxipMinor_;
  deviceProps.multiProcessorCount = info.maxComputeUnits_;
  deviceProps.l2CacheSize = info.l2CacheSize_;
  deviceProps.maxThreadsPerMultiProcessor = info.maxThreadsPerCU_;
  deviceProps.computeMode = 0;
  deviceProps.clockInstructionRate = info.timeStampFrequency_;
  deviceProps.arch.hasGlobalInt32Atomics       = 1;
  deviceProps.arch.hasGlobalFloatAtomicExch    = 1;
  deviceProps.arch.hasSharedInt32Atomics       = 1;
  deviceProps.arch.hasSharedFloatAtomicExch    = 1;
  deviceProps.arch.hasFloatAtomicAdd           = 1;
  deviceProps.arch.hasGlobalInt64Atomics       = 1;
  deviceProps.arch.hasSharedInt64Atomics       = 1;
  deviceProps.arch.hasDoubles                  = 1;
  deviceProps.arch.hasWarpVote                 = 1;
  deviceProps.arch.hasWarpBallot               = 1;
  deviceProps.arch.hasWarpShuffle              = 1;
  deviceProps.arch.hasFunnelShift              = 0;
  deviceProps.arch.hasThreadFenceSystem        = 1;
  deviceProps.arch.hasSyncThreadsExt           = 0;
  deviceProps.arch.hasSurfaceFuncs             = 0;
  deviceProps.arch.has3dGrid                   = 1;
  deviceProps.arch.hasDynamicParallelism       = 0;
  deviceProps.concurrentKernels = 1;
  deviceProps.pciDomainID = info.deviceTopology_.pcie.function;
  deviceProps.pciBusID = info.deviceTopology_.pcie.bus;
  deviceProps.pciDeviceID = info.deviceTopology_.pcie.device;
  deviceProps.maxSharedMemoryPerMultiProcessor = info.localMemSizePerCU_;
  //deviceProps.isMultiGpuBoard = info.;
  deviceProps.canMapHostMemory = 1;
  deviceProps.gcnArch = info.gfxipMajor_ * 100 + info.gfxipMinor_ * 10 + info.gfxipStepping_;
  sprintf(deviceProps.gcnArchName, "gfx%d%d%x", info.gfxipMajor_, info.gfxipMinor_, info.gfxipStepping_);
  deviceProps.cooperativeLaunch = info.cooperativeGroups_;
  deviceProps.cooperativeMultiDeviceLaunch = info.cooperativeMultiDeviceGroups_;

  deviceProps.cooperativeMultiDeviceUnmatchedFunc = info.cooperativeMultiDeviceGroups_;
  deviceProps.cooperativeMultiDeviceUnmatchedGridDim = info.cooperativeMultiDeviceGroups_;
  deviceProps.cooperativeMultiDeviceUnmatchedBlockDim = info.cooperativeMultiDeviceGroups_;
  deviceProps.cooperativeMultiDeviceUnmatchedSharedMem = info.cooperativeMultiDeviceGroups_;

  deviceProps.maxTexture1D = info.imageMaxBufferSize_;
  deviceProps.maxTexture2D[0] = info.image2DMaxWidth_;
  deviceProps.maxTexture2D[1] = info.image2DMaxHeight_;
  deviceProps.maxTexture3D[0] = info.image3DMaxWidth_;
  deviceProps.maxTexture3D[1] = info.image3DMaxHeight_;
  deviceProps.maxTexture3D[2] = info.image3DMaxDepth_;
  deviceProps.hdpMemFlushCntl = nullptr;
  deviceProps.hdpRegFlushCntl = nullptr;

  deviceProps.memPitch = info.maxMemAllocSize_;
  deviceProps.textureAlignment = info.imageBaseAddressAlignment_;
  deviceProps.texturePitchAlignment = info.imagePitchAlignment_;
  deviceProps.kernelExecTimeoutEnabled = 0;
  deviceProps.ECCEnabled = info.errorCorrectionSupport_? 1:0;
  deviceProps.isLargeBar = info.largeBar_ ? 1 : 0;
  deviceProps.asicRevision = info.asicRevision_;

  *props = deviceProps;
  HIP_RETURN(hipSuccess);
}

hipError_t hipHccGetAccelerator(int deviceId, hc::accelerator* acc) {
  HIP_INIT_API(hipHccGetAccelerator, deviceId, acc);

  assert(0 && "Unimplemented");

  HIP_RETURN(hipErrorNotSupported);
}

hipError_t hipHccGetAcceleratorView(hipStream_t stream, hc::accelerator_view** av) {
  HIP_INIT_API(hipHccGetAcceleratorView, stream, av);

  assert(0 && "Unimplemented");

  HIP_RETURN(hipErrorNotSupported);
}
<commit_msg>Use availableRegistersPerCU_ to populate number of registers<commit_after>/* Copyright (c) 2018-present Advanced Micro Devices, Inc.

 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 <hip/hip_runtime.h>

#include "hip_internal.hpp"

namespace hip {

// ================================================================================================
amd::HostQueue* Device::NullStream(bool skip_alloc) {
  amd::HostQueue* null_queue = null_stream_.asHostQueue(skip_alloc);
  if (null_queue == nullptr) {
    return nullptr;
  }
  // Wait for all active streams before executing commands on the default
  iHipWaitActiveStreams(null_queue);
  return null_queue;
}

}

hipError_t hipDeviceGet(hipDevice_t *device, int deviceId) {
  HIP_INIT_API(hipDeviceGet, device, deviceId);

  if (device != nullptr) {
    *device = deviceId;
  } else {
    HIP_RETURN(hipErrorInvalidValue);
  }

  HIP_RETURN(hipSuccess);
};

hipError_t hipDeviceTotalMem (size_t *bytes, hipDevice_t device) {

  HIP_INIT_API(hipDeviceTotalMem, bytes, device);

  if (device < 0 || static_cast<size_t>(device) >= g_devices.size()) {
    HIP_RETURN(hipErrorInvalidDevice);
  }

  if (bytes == nullptr) {
    HIP_RETURN(hipErrorInvalidValue);
  }

  auto* deviceHandle = g_devices[device]->devices()[0];
  const auto& info = deviceHandle->info();

  *bytes = info.globalMemSize_;

  HIP_RETURN(hipSuccess);
}

hipError_t hipDeviceComputeCapability(int *major, int *minor, hipDevice_t device) {

  HIP_INIT_API(hipDeviceComputeCapability, major, minor, device);

  if (device < 0 || static_cast<size_t>(device) >= g_devices.size()) {
    HIP_RETURN(hipErrorInvalidDevice);
  }

  if (major == nullptr || minor == nullptr) {
    HIP_RETURN(hipErrorInvalidValue);
  }

  auto* deviceHandle = g_devices[device]->devices()[0];
  const auto& info = deviceHandle->info();
  *major = info.gfxipMajor_;
  *minor = info.gfxipMinor_;

  HIP_RETURN(hipSuccess);
}

hipError_t hipDeviceGetCount(int* count) {
  HIP_INIT_API(hipDeviceGetCount, count);

  HIP_RETURN(ihipDeviceGetCount(count));
}

hipError_t ihipDeviceGetCount(int* count) {
  if (count == nullptr) {
    return hipErrorInvalidValue;
  }

  // Get all available devices
  *count = g_devices.size();

  if (*count < 1) {
    return hipErrorNoDevice;
  }

  return hipSuccess;
}

hipError_t hipDeviceGetName(char *name, int len, hipDevice_t device) {

  HIP_INIT_API(hipDeviceGetName, (void*)name, len, device);

  if (device < 0 || static_cast<size_t>(device) >= g_devices.size()) {
    HIP_RETURN(hipErrorInvalidDevice);
  }

  if (name == nullptr || len <= 0) {
    HIP_RETURN(hipErrorInvalidValue);
  }

  auto* deviceHandle = g_devices[device]->devices()[0];
  const auto& info = deviceHandle->info();
  const auto nameLen = ::strlen(info.boardName_);

  // Make sure that the size of `dest` is big enough to hold `src` including
  // trailing zero byte
  if (nameLen > (cl_uint)(len - 1)) {
    HIP_RETURN(hipErrorInvalidValue);
  }

  ::strncpy(name, info.boardName_, (nameLen + 1));

  HIP_RETURN(hipSuccess);
}

hipError_t hipGetDeviceProperties ( hipDeviceProp_t* props, hipDevice_t device ) {
  HIP_INIT_API(hipGetDeviceProperties, props, device);

  if (props == nullptr) {
    HIP_RETURN(hipErrorInvalidValue);
  }

  if (unsigned(device) >= g_devices.size()) {
    HIP_RETURN(hipErrorInvalidDevice);
  }
  auto* deviceHandle = g_devices[device]->devices()[0];

  hipDeviceProp_t deviceProps = {0};

  const auto& info = deviceHandle->info();
  ::strncpy(deviceProps.name, info.boardName_, 128);
  deviceProps.totalGlobalMem = info.globalMemSize_;
  deviceProps.sharedMemPerBlock = info.localMemSizePerCU_;
  deviceProps.regsPerBlock = info.availableRegistersPerCU_;
  deviceProps.warpSize = info.wavefrontWidth_;
  deviceProps.maxThreadsPerBlock = info.maxWorkGroupSize_;
  deviceProps.maxThreadsDim[0] = info.maxWorkItemSizes_[0];
  deviceProps.maxThreadsDim[1] = info.maxWorkItemSizes_[1];
  deviceProps.maxThreadsDim[2] = info.maxWorkItemSizes_[2];
  deviceProps.maxGridSize[0] = INT32_MAX;
  deviceProps.maxGridSize[1] = INT32_MAX;
  deviceProps.maxGridSize[2] = INT32_MAX;
  deviceProps.clockRate = info.maxEngineClockFrequency_ * 1000;
  deviceProps.memoryClockRate = info.maxMemoryClockFrequency_ * 1000;
  deviceProps.memoryBusWidth = info.globalMemChannels_;
  deviceProps.totalConstMem = info.maxConstantBufferSize_;
  deviceProps.major = info.gfxipMajor_;
  deviceProps.minor = info.gfxipMinor_;
  deviceProps.multiProcessorCount = info.maxComputeUnits_;
  deviceProps.l2CacheSize = info.l2CacheSize_;
  deviceProps.maxThreadsPerMultiProcessor = info.maxThreadsPerCU_;
  deviceProps.computeMode = 0;
  deviceProps.clockInstructionRate = info.timeStampFrequency_;
  deviceProps.arch.hasGlobalInt32Atomics       = 1;
  deviceProps.arch.hasGlobalFloatAtomicExch    = 1;
  deviceProps.arch.hasSharedInt32Atomics       = 1;
  deviceProps.arch.hasSharedFloatAtomicExch    = 1;
  deviceProps.arch.hasFloatAtomicAdd           = 1;
  deviceProps.arch.hasGlobalInt64Atomics       = 1;
  deviceProps.arch.hasSharedInt64Atomics       = 1;
  deviceProps.arch.hasDoubles                  = 1;
  deviceProps.arch.hasWarpVote                 = 1;
  deviceProps.arch.hasWarpBallot               = 1;
  deviceProps.arch.hasWarpShuffle              = 1;
  deviceProps.arch.hasFunnelShift              = 0;
  deviceProps.arch.hasThreadFenceSystem        = 1;
  deviceProps.arch.hasSyncThreadsExt           = 0;
  deviceProps.arch.hasSurfaceFuncs             = 0;
  deviceProps.arch.has3dGrid                   = 1;
  deviceProps.arch.hasDynamicParallelism       = 0;
  deviceProps.concurrentKernels = 1;
  deviceProps.pciDomainID = info.deviceTopology_.pcie.function;
  deviceProps.pciBusID = info.deviceTopology_.pcie.bus;
  deviceProps.pciDeviceID = info.deviceTopology_.pcie.device;
  deviceProps.maxSharedMemoryPerMultiProcessor = info.localMemSizePerCU_;
  //deviceProps.isMultiGpuBoard = info.;
  deviceProps.canMapHostMemory = 1;
  deviceProps.gcnArch = info.gfxipMajor_ * 100 + info.gfxipMinor_ * 10 + info.gfxipStepping_;
  sprintf(deviceProps.gcnArchName, "gfx%d%d%x", info.gfxipMajor_, info.gfxipMinor_, info.gfxipStepping_);
  deviceProps.cooperativeLaunch = info.cooperativeGroups_;
  deviceProps.cooperativeMultiDeviceLaunch = info.cooperativeMultiDeviceGroups_;

  deviceProps.cooperativeMultiDeviceUnmatchedFunc = info.cooperativeMultiDeviceGroups_;
  deviceProps.cooperativeMultiDeviceUnmatchedGridDim = info.cooperativeMultiDeviceGroups_;
  deviceProps.cooperativeMultiDeviceUnmatchedBlockDim = info.cooperativeMultiDeviceGroups_;
  deviceProps.cooperativeMultiDeviceUnmatchedSharedMem = info.cooperativeMultiDeviceGroups_;

  deviceProps.maxTexture1D = info.imageMaxBufferSize_;
  deviceProps.maxTexture2D[0] = info.image2DMaxWidth_;
  deviceProps.maxTexture2D[1] = info.image2DMaxHeight_;
  deviceProps.maxTexture3D[0] = info.image3DMaxWidth_;
  deviceProps.maxTexture3D[1] = info.image3DMaxHeight_;
  deviceProps.maxTexture3D[2] = info.image3DMaxDepth_;
  deviceProps.hdpMemFlushCntl = nullptr;
  deviceProps.hdpRegFlushCntl = nullptr;

  deviceProps.memPitch = info.maxMemAllocSize_;
  deviceProps.textureAlignment = info.imageBaseAddressAlignment_;
  deviceProps.texturePitchAlignment = info.imagePitchAlignment_;
  deviceProps.kernelExecTimeoutEnabled = 0;
  deviceProps.ECCEnabled = info.errorCorrectionSupport_? 1:0;
  deviceProps.isLargeBar = info.largeBar_ ? 1 : 0;
  deviceProps.asicRevision = info.asicRevision_;

  *props = deviceProps;
  HIP_RETURN(hipSuccess);
}

hipError_t hipHccGetAccelerator(int deviceId, hc::accelerator* acc) {
  HIP_INIT_API(hipHccGetAccelerator, deviceId, acc);

  assert(0 && "Unimplemented");

  HIP_RETURN(hipErrorNotSupported);
}

hipError_t hipHccGetAcceleratorView(hipStream_t stream, hc::accelerator_view** av) {
  HIP_INIT_API(hipHccGetAcceleratorView, stream, av);

  assert(0 && "Unimplemented");

  HIP_RETURN(hipErrorNotSupported);
}
<|endoftext|>


<commit_before>/*
Copyright (C) 2010-2014  Le Hoang Quyen (lehoangq@gmail.com)

This program is free software; you can redistribute it and/or
modify it under the terms of the MIT license.  See the file
COPYING.txt included with this distribution for more information.

*/

#include "HQDeviceGLPCH.h"

#include "HQDeviceGL.h"

/*--------------HQBufferGL-----------------*/
HQBufferGL::HQBufferGL(hq_uint32 size, GLenum targetName, GLenum usage)
{
	this->targetName = targetName;
	this->bufferName = 0;
	this->usage = usage;
	this->size = size;

	/*---------info for shader storage----------*/
	this->totalElements = 0;
	this->elementSize = 0;
}

HQBufferGL::~HQBufferGL()
{
	if (this->bufferName != 0)
	{
#if defined DEVICE_LOST_POSSIBLE
		if (!g_pOGLDev->IsDeviceLost())
#endif
			glDeleteBuffers(1, &this->bufferName);
	}
}

HQReturnVal CopyGLBufferContent(void *dest, size_t size, GLuint buffer, GLenum targetName, GLenum targetBindingPoint)
{
	//save current bound buffer
	GLint oldBoundBuffer;
	glGetIntegerv(targetBindingPoint, &oldBoundBuffer);

	//bind buffer
	glBindBuffer(targetName, buffer);

	void *mappedData = glMapBuffer(targetName, GL_READ_ONLY);

	HQReturnVal re = HQ_FAILED;
#ifdef HQ_OPENGLES
	if (mappedData != NULL)
	{
		memcpy(dest, mappedData, size);
		re = HQ_OK;
	}
#else
	glGetBufferSubData(targetName, 0, size, dest);
	re = HQ_OK;
#endif
	//restore old bound buffer
	glBindBuffer(targetName, oldBoundBuffer);

	return re;
}
<commit_msg>- fixed GL buffer copying function<commit_after>/*
Copyright (C) 2010-2014  Le Hoang Quyen (lehoangq@gmail.com)

This program is free software; you can redistribute it and/or
modify it under the terms of the MIT license.  See the file
COPYING.txt included with this distribution for more information.

*/

#include "HQDeviceGLPCH.h"

#include "HQDeviceGL.h"

/*--------------HQBufferGL-----------------*/
HQBufferGL::HQBufferGL(hq_uint32 size, GLenum targetName, GLenum usage)
{
	this->targetName = targetName;
	this->bufferName = 0;
	this->usage = usage;
	this->size = size;

	/*---------info for shader storage----------*/
	this->totalElements = 0;
	this->elementSize = 0;
}

HQBufferGL::~HQBufferGL()
{
	if (this->bufferName != 0)
	{
#if defined DEVICE_LOST_POSSIBLE
		if (!g_pOGLDev->IsDeviceLost())
#endif
			glDeleteBuffers(1, &this->bufferName);
	}
}

HQReturnVal CopyGLBufferContent(void *dest, size_t size, GLuint buffer, GLenum targetName, GLenum targetBindingPoint)
{
	//save current bound buffer
	GLint oldBoundBuffer;
	glGetIntegerv(targetBindingPoint, &oldBoundBuffer);

	//bind buffer
	glBindBuffer(targetName, buffer);

	HQReturnVal re = HQ_FAILED;
#ifdef HQ_OPENGLES
	void *mappedData = glMapBuffer(targetName, GL_READ_ONLY);
	if (mappedData != NULL)
	{
		memcpy(dest, mappedData, size);
		glUnmapBuffer(targetName);
		re = HQ_OK;
	}
#else
	glGetBufferSubData(targetName, 0, size, dest);
	re = HQ_OK;
#endif
	//restore old bound buffer
	glBindBuffer(targetName, oldBoundBuffer);

	return re;
}
<|endoftext|>


<commit_before>inline
cov_mat_kth::cov_mat_kth( const std::string in_path,
			  const std::string in_actionNames,
			  const int in_scale_factor,
			  const int in_shift,
			  const int in_scene, //only for kth
			  const int in_segment_length
)
:path(in_path), actionNames(in_actionNames), scale_factor(in_scale_factor), shift(in_shift), scene(in_scene), segment_length(in_segment_length)
{
  actions.load( actionNames );
}

inline
void
cov_mat_kth::calculate( field<string> in_all_people, int  in_dim  )
{
  all_people = in_all_people;
  dim = in_dim;
  int n_actions = actions.n_rows;
  int n_peo =  all_people.n_rows;
  //all_people.print("people");

  for (int sc = 1; sc<=1; ++sc) //scene
  {
    for (int pe = 0; pe< n_peo; ++pe)
    {
      for (int act=0; act<n_actions; ++act)
      {

	std::stringstream load_folder;
	std::stringstream load_feat_video_i;
	std::stringstream load_labels_video_i;

	//cout << "Loading.." << endl;
	load_folder << path << "/kth-features/sc" << sc << "/scale" << scale_factor << "-shift"<< shift ;
	load_feat_video_i << load_folder.str() << "/" << all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".h5";
	load_labels_video_i << load_folder.str() << "/lab_" << all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".h5";

	//For one Video
	cov_mat_kth::one_video(load_feat_video_i.str(),	 load_labels_video_i.str(), sc, pe, act );
	//getchar();

      }
    }
  }
}

inline
void
cov_mat_kth::one_video( std::string load_feat_video_i,	std::string load_labels_video_i, int sc, int pe, int act )
{
  cout << load_feat_video_i << endl;
  mat mat_features_video_i;
  vec lab_video_i;

  mat_features_video_i.load( load_feat_video_i, hdf5_binary );
  lab_video_i.load( load_labels_video_i, hdf5_binary );
  int n_vec = lab_video_i.n_elem;
  int last = lab_video_i( n_vec - 1 );
  //cout << last << endl;

  int s = 0;

  std::stringstream save_folder;
  save_folder << "./kth-cov-mat/sc" << sc << "/scale" << scale_factor << "-shift"<< shift ;

  for (int l=2; l<last-segment_length; l = l+4 )
  {
    running_stat_vec<rowvec> stat_seg(true);
    //int k =0;

    //cout << " " << l;

    for (int j=l; j< l + segment_length; ++j)
    {
      //k++;
      //cout << " " << j;
      uvec indices = find(lab_video_i == j);
      mat tmp_feat = mat_features_video_i.cols(indices);
      //cout << "row&col " << tmp_feat.n_rows << " & " << tmp_feat.n_cols << endl;
      for (int v=0; v < tmp_feat.n_cols; ++v)
      {
	vec sample = tmp_feat.col(v);
	stat_seg (sample);

      }

    }

    //cout << endl;
    //cout << " " << stat_seg.count();

    if (stat_seg.count()>100) // Cuando en el segmento hay mas de 100 vectores
    {
    std::stringstream save_cov_seg;
    save_cov_seg << save_folder.str() << "/cov_seg" << s << "_"<< all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".h5";

    double THRESH = 0.000001;
    mat cov_seg_i = stat_seg.cov();

    //Following Mehrtash suggestions as per email dated June26th 2014
    cov_seg_i = 0.5*(cov_seg_i + cov_seg_i.t());
    vec D;
    mat V;
    eig_sym(D, V, cov_seg_i);
    uvec q1 = find(D < THRESH);

    if (q1.n_elem>0)
    {
      for (uword pos = 0; pos < q1.n_elem; ++pos)
      {
	D( q1(pos) ) = THRESH;

      }

      cov_seg_i = V*diagmat(D)*V.t();

    }

    //end suggestion

    cov_seg_i.save( save_cov_seg.str(), hdf5_binary );

    s++;
    }
    else {
     //cout << " " << stat_seg.count();
     //getchar();

    }

  }

  std::stringstream save_seg;
  vec total_seg;
  total_seg.zeros(1);
  total_seg( 0 ) = s;
  save_seg << save_folder.str() << "/num_seg_"<< all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".dat";
  total_seg.save( save_seg.str(), raw_ascii );
  cout << "Total # of segments " << s << endl;
  //cout << "press a key " ;
  //getchar();

}

<commit_msg>Calculating LogM_cov<commit_after>inline
cov_mat_kth::cov_mat_kth( const std::string in_path,
			  const std::string in_actionNames,
			  const int in_scale_factor,
			  const int in_shift,
			  const int in_scene, //only for kth
			  const int in_segment_length
)
:path(in_path), actionNames(in_actionNames), scale_factor(in_scale_factor), shift(in_shift), scene(in_scene), segment_length(in_segment_length)
{
  actions.load( actionNames );
}

inline
void
cov_mat_kth::calculate( field<string> in_all_people, int  in_dim  )
{
  all_people = in_all_people;
  dim = in_dim;
  int n_actions = actions.n_rows;
  int n_peo =  all_people.n_rows;
  //all_people.print("people");

  for (int sc = 1; sc<=1; ++sc) //scene
  {
    for (int pe = 0; pe< n_peo; ++pe)
    {
      for (int act=0; act<n_actions; ++act)
      {

	std::stringstream load_folder;
	std::stringstream load_feat_video_i;
	std::stringstream load_labels_video_i;

	//cout << "Loading.." << endl;
	load_folder << path << "/kth-features/sc" << sc << "/scale" << scale_factor << "-shift"<< shift ;
	load_feat_video_i << load_folder.str() << "/" << all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".h5";
	load_labels_video_i << load_folder.str() << "/lab_" << all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".h5";

	//For one Video
	cov_mat_kth::one_video(load_feat_video_i.str(),	 load_labels_video_i.str(), sc, pe, act );
	//getchar();

      }
    }
  }
}

inline
void
cov_mat_kth::one_video( std::string load_feat_video_i,	std::string load_labels_video_i, int sc, int pe, int act )
{
  cout << load_feat_video_i << endl;
  mat mat_features_video_i;
  vec lab_video_i;

  mat_features_video_i.load( load_feat_video_i, hdf5_binary );
  lab_video_i.load( load_labels_video_i, hdf5_binary );
  int n_vec = lab_video_i.n_elem;
  int last = lab_video_i( n_vec - 1 );
  //cout << last << endl;

  int s = 0;

  std::stringstream save_folder;
  save_folder << "./kth-cov-mat/sc" << sc << "/scale" << scale_factor << "-shift"<< shift ;

  for (int l=2; l<last-segment_length; l = l+4 )
  {
    running_stat_vec<rowvec> stat_seg(true);
    //int k =0;

    //cout << " " << l;

    for (int j=l; j< l + segment_length; ++j)
    {
      //k++;
      //cout << " " << j;
      uvec indices = find(lab_video_i == j);
      mat tmp_feat = mat_features_video_i.cols(indices);
      //cout << "row&col " << tmp_feat.n_rows << " & " << tmp_feat.n_cols << endl;
      for (int v=0; v < tmp_feat.n_cols; ++v)
      {
	vec sample = tmp_feat.col(v);
	stat_seg (sample);

      }

    }

    //cout << endl;
    //cout << " " << stat_seg.count();

    if (stat_seg.count()>100) // Cuando en el segmento hay mas de 100 vectores
    {
    std::stringstream save_cov_seg;
    save_cov_seg << save_folder.str() << "/cov_seg" << s << "_"<< all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".h5";

    std::stringstream save_LogMcov_seg;
    save_LogMcov_seg << save_folder.str() << "/LogMcov_seg" << s << "_"<< all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".h5";

    double THRESH = 0.000001;
    mat cov_seg_i = stat_seg.cov();

    //Following Mehrtash suggestions as per email dated June26th 2014
    cov_seg_i = 0.5*(cov_seg_i + cov_seg_i.t());
    vec D;
    mat V;
    eig_sym(D, V, cov_seg_i);
    uvec q1 = find(D < THRESH);

    if (q1.n_elem>0)
    {
      for (uword pos = 0; pos < q1.n_elem; ++pos)
      {
	D( q1(pos) ) = THRESH;

      }

      cov_seg_i = V*diagmat(D)*V.t();

    }
    //end suggestion

     eig_sym(D, V, cov_seg_i);
     mat log_M = V*diagmat( log(D) )*V.t();
     cov_seg_i.save( save_cov_seg.str(), hdf5_binary );
     mat log_M.save( save_LogMcov_seg.str(), hdf5_binary );
     cov_seg_i.print("cov_seg_i");
     log_M.print("log_M");
     getchar();

    s++;
    }
    else {
     //cout << " " << stat_seg.count();
     //getchar();

    }

  }

  std::stringstream save_seg;
  vec total_seg;
  total_seg.zeros(1);
  total_seg( 0 ) = s;
  save_seg << save_folder.str() << "/num_seg_"<< all_people (pe) << "_" << actions(act) << "_dim" << dim  << ".dat";
  total_seg.save( save_seg.str(), raw_ascii );
  cout << "Total # of segments " << s << endl;
  //cout << "press a key " ;
  //getchar();

}

<|endoftext|>


<commit_before>#pragma once

/// <summary>
/// Implement a singleton  class without inheritance. Should be used in header file.
/// </summary>
#define ODLIB_IMPLEMENT_SINGLETON_HEADER(Class) \
public: \
    template<typename... Args> \
    static Class* Construct(Args&& ...args) \
    { \
        std::call_once(m_constructFlag, [&]() \
        { \
            m_instance.reset(new Class(std::forward<Args>(args)...)); \
        }); \
        return m_instance.get(); \
    } \
    static Class* GetInstance(); \
    static const bool IsReleased(); \
    static void Release(); \
private: \
    friend std::unique_ptr<Class>::deleter_type; \
    Class(Class const&) = delete; \
    Class& operator=(Class const&) = delete; \
    static std::unique_ptr<Class> m_instance; \
    static std::once_flag m_constructFlag; \
    static std::once_flag m_releaseFlag;

/// <summary>
/// Implement a singleton  class without inheritance. Should be used in source file.
/// </summary>
#define ODLIB_IMPLEMENT_SINGLETON_SOURCE(Class) \
std::unique_ptr<Class> Class::m_instance; \
std::once_flag Class::m_constructFlag; \
std::once_flag Class::m_releaseFlag; \
Class* Class::GetInstance() \
{ \
    if (IsReleased() == true) \
    { \
        return Construct(); \
    } \
    return m_instance.get(); \
} \
const bool Class::IsReleased() \
{ \
    return m_instance == nullptr; \
} \
void Class::Release() \
{ \
    if (IsReleased() == false) \
    { \
        std::call_once(m_releaseFlag, [&]() \
        { \
            m_instance.reset(nullptr); \
        }); \
    } \
}
<commit_msg>Mark move constructor and operator as deleted in singleton define<commit_after>#pragma once

/// <summary>
/// Implement a singleton  class without inheritance. Should be used in header file.
/// </summary>
#define ODLIB_IMPLEMENT_SINGLETON_HEADER(Class) \
public: \
    template<typename... Args> \
    static Class* Construct(Args&& ...args) \
    { \
        std::call_once(m_constructFlag, [&]() \
        { \
            m_instance.reset(new Class(std::forward<Args>(args)...)); \
        }); \
        return m_instance.get(); \
    } \
    static Class* GetInstance(); \
    static const bool IsReleased(); \
    static void Release(); \
private: \
    friend std::unique_ptr<Class>::deleter_type; \
    Class(const Class&) = delete; \
    Class(Class&&) = delete; \
    Class& operator=(const Class&) = delete; \
    Class& operator=(Class&&) = delete; \
    static std::unique_ptr<Class> m_instance; \
    static std::once_flag m_constructFlag; \
    static std::once_flag m_releaseFlag;

/// <summary>
/// Implement a singleton  class without inheritance. Should be used in source file.
/// </summary>
#define ODLIB_IMPLEMENT_SINGLETON_SOURCE(Class) \
std::unique_ptr<Class> Class::m_instance; \
std::once_flag Class::m_constructFlag; \
std::once_flag Class::m_releaseFlag; \
Class* Class::GetInstance() \
{ \
    if (IsReleased() == true) \
    { \
        return Construct(); \
    } \
    return m_instance.get(); \
} \
const bool Class::IsReleased() \
{ \
    return m_instance == nullptr; \
} \
void Class::Release() \
{ \
    if (IsReleased() == false) \
    { \
        std::call_once(m_releaseFlag, [&]() \
        { \
            m_instance.reset(nullptr); \
        }); \
    } \
}
<|endoftext|>


<commit_before>#if !defined(__CINT__) || defined(__MAKECINT__)
#include <TSystem.h>
#include <TMath.h>
#endif

//---------------------------------------
double radii2Turbo(double rMin,double rMid,double rMax, double sensW)
{
  // compute turbo angle from radii and sensor width
  return TMath::ASin((rMax*rMax-rMin*rMin)/(2*rMid*sensW))*TMath::RadToDeg();
}

double radii2Phi(double rMin,double rMid,double rMax, double sensW)
{
  // compute phi coverage
  return 2*TMath::ACos((rMax+rMin)*
		       (rMid*rMid+rMin*rMax-sensW*sensW/4.)/
		       (4.*rMid*rMax*rMin));
}

void CreateITSUv2ALP3()
{
  //
  gSystem->Load("libITSUpgradeBase");
  gSystem->Load("libITSUpgradeSim");
  //
  // build ITS upgrade detector
  // pALPIDE3 15x30 mm^2  (X,Z) with 26.88 x 29.24 micron pitch
  const double kSensThick = 18e-4;
  const double kPitchZ = 29.24e-4;
  const double kPitchX = 26.88e-4;
  const int    kNRow   = 512;
  const int    kNCol   = 1024;
  const double kSiThickIB = 50e-4;
  const double kSiThickOB = 50e-4;
  //  const double kSensThick = 120e-4;   // -> sensor Si thickness
  //
  const double kReadOutEdge = 0.12;   // width of the readout edge (passive bottom)
  const double kTopEdge = 37.44e-4;   // dead area on top
  const double kLeftRightEdge   = 29.12e-4; // width of passive area on left/right of the sensor
  //
  const int kNLr = 7;
  const int kNLrInner = 3;
  const int kBuildLevel = 0;
  enum {kRmn,kRmd,kRmx,kNModPerStave,kPhi0,kNStave,kNPar};
  // Radii are from last TDR (ALICE-TDR-017.pdf Tab. 1.1, rMid is mean value)
  const double tdr5dat[kNLr][kNPar] = {
    {2.24, 2.34, 2.67,  9., 16.42, 12}, // for each inner layer: rMin,rMid,rMax,NChip/Stave, phi0, nStaves
    {3.01, 3.15, 3.46,  9., 12.18, 16},
    {3.78, 3.93, 4.21,  9.,  9.55, 20},
    {-1,  19.6 ,   -1,  4.,  0.  , 24},  // for others: -, rMid, -, NMod/HStave, phi0, nStaves // 24 was 49
    {-1,  24.55, -1,    4.,  0.  , 30},  // 30 was 61
    {-1,  34.39, -1,    7.,  0.  , 42},  // 42 was 88
    {-1,  39.34, -1,    7.,  0.  , 48}   // 48 was 100
  };
  const int nChipsPerModule = 7; // For OB: how many chips in a row
  const double zChipGap = 0.01;  // For OB: gap in Z between chips
  const double zModuleGap = 0.01;// For OB: gap in Z between modules

  // create segmentations:
  AliITSMFTSegmentationPix* seg0 = new AliITSMFTSegmentationPix(0,        // segID (0:9)
							    1,  // chips per module
							    kNCol,    // ncols (total for module)
							    kNRow,    // nrows
							    kPitchX,  // default row pitch in cm
							    kPitchZ,  // default col pitch in cm
							    kSensThick,  // sensor thickness in cm
							    -1,     // no special left col between chips
							    -1,     // no special right col between chips
							    kLeftRightEdge, // left
							    kLeftRightEdge, // right
							    kTopEdge, // top
							    kReadOutEdge  // bottom
							    );    // see AliITSMFTSegmentationPix.h for extra options
  seg0->Store(AliITSUGeomTGeo::GetITSsegmentationFileName());
  //
  seg0->Print();
  //
  double dzLr,rLr,phi0,turbo;
  int nStaveLr,nModPerStaveLr,idLr;
  //
  AliITSUv2 *ITS  = new AliITSUv2("ITS Upgrade",kNLr);
  ITS->SetStaveModelIB(AliITSUv2::kIBModel4);
  ITS->SetStaveModelOB(AliITSUv2::kOBModel2);
  //
  const int kNWrapVol = 3;
  const double wrpRMin[kNWrapVol]  = { 2.1, 15.0, 32.0};
  const double wrpRMax[kNWrapVol]  = {14.0, 30.0, 46.0};
  const double wrpZSpan[kNWrapVol] = {70., 95., 200.};
  //
  ITS->SetNWrapVolumes(kNWrapVol); // define wrapper volumes for layers
  for (int iw=0;iw<kNWrapVol;iw++) ITS->DefineWrapVolume(iw,wrpRMin[iw],wrpRMax[iw],wrpZSpan[iw]);
  //
  for (int idLr=0;idLr<kNLr;idLr++) {
    rLr   = tdr5dat[idLr][kRmd];
    phi0  = tdr5dat[idLr][kPhi0];
    //
    nStaveLr = TMath::Nint(tdr5dat[idLr][kNStave]);
    nModPerStaveLr =  TMath::Nint(tdr5dat[idLr][kNModPerStave]);
    int nChipsPerStaveLr = nModPerStaveLr;
    //
    if (idLr>=kNLrInner) {
      double modlen = nChipsPerModule*seg0->Dz() + (nChipsPerModule-1)*zChipGap;
      double zlen = nModPerStaveLr*modlen + (nModPerStaveLr-1)*zModuleGap;
      ITS->DefineLayer(idLr, phi0, rLr, zlen, nStaveLr, nModPerStaveLr,
		       kSiThickOB, seg0->Dy(), seg0->GetChipTypeID(),kBuildLevel);
    } else {
      turbo = radii2Turbo(tdr5dat[idLr][kRmn],rLr,tdr5dat[idLr][kRmx],seg0->Dx());
      ITS->DefineLayerTurbo(idLr, phi0, rLr, nChipsPerStaveLr*seg0->Dz(), nStaveLr, nChipsPerStaveLr,
			    seg0->Dx(), turbo, kSiThickIB, seg0->Dy(), seg0->GetChipTypeID(),kBuildLevel);
    }

  }

}
<commit_msg>To fix errors when running Root6<commit_after>#if !defined(__CINT__) || defined(__MAKECINT__)
#include <TSystem.h>
#include <TMath.h>
#include "AliITSUv2.h"
#endif

//---------------------------------------
double radii2Turbo(double rMin,double rMid,double rMax, double sensW)
{
  // compute turbo angle from radii and sensor width
  return TMath::ASin((rMax*rMax-rMin*rMin)/(2*rMid*sensW))*TMath::RadToDeg();
}

double radii2Phi(double rMin,double rMid,double rMax, double sensW)
{
  // compute phi coverage
  return 2*TMath::ACos((rMax+rMin)*
		       (rMid*rMid+rMin*rMax-sensW*sensW/4.)/
		       (4.*rMid*rMax*rMin));
}

void CreateITSUv2ALP3()
{
  //
  //
  gSystem->Load("libITSUpgradeBase");
  gSystem->Load("libITSUpgradeSim");
  //
  // build ITS upgrade detector
  // pALPIDE3 15x30 mm^2  (X,Z) with 26.88 x 29.24 micron pitch
  const double kSensThick = 18e-4;
  const double kPitchZ = 29.24e-4;
  const double kPitchX = 26.88e-4;
  const int    kNRow   = 512;
  const int    kNCol   = 1024;
  const double kSiThickIB = 50e-4;
  const double kSiThickOB = 50e-4;
  //  const double kSensThick = 120e-4;   // -> sensor Si thickness
  //
  const double kReadOutEdge = 0.12;   // width of the readout edge (passive bottom)
  const double kTopEdge = 37.44e-4;   // dead area on top
  const double kLeftRightEdge   = 29.12e-4; // width of passive area on left/right of the sensor
  //
  const int kNLr = 7;
  const int kNLrInner = 3;
  const int kBuildLevel = 0;
  enum {kRmn,kRmd,kRmx,kNModPerStave,kPhi0,kNStave,kNPar};
  // Radii are from last TDR (ALICE-TDR-017.pdf Tab. 1.1, rMid is mean value)
  const double tdr5dat[kNLr][kNPar] = {
    {2.24, 2.34, 2.67,  9., 16.42, 12}, // for each inner layer: rMin,rMid,rMax,NChip/Stave, phi0, nStaves
    {3.01, 3.15, 3.46,  9., 12.18, 16},
    {3.78, 3.93, 4.21,  9.,  9.55, 20},
    {-1,  19.6 ,   -1,  4.,  0.  , 24},  // for others: -, rMid, -, NMod/HStave, phi0, nStaves // 24 was 49
    {-1,  24.55, -1,    4.,  0.  , 30},  // 30 was 61
    {-1,  34.39, -1,    7.,  0.  , 42},  // 42 was 88
    {-1,  39.34, -1,    7.,  0.  , 48}   // 48 was 100
  };
  const int nChipsPerModule = 7; // For OB: how many chips in a row
  const double zChipGap = 0.01;  // For OB: gap in Z between chips
  const double zModuleGap = 0.01;// For OB: gap in Z between modules

  // create segmentations

  AliITSMFTSegmentationPix* seg0 = new AliITSMFTSegmentationPix(0,        // segID (0:9)
							    1,  // chips per module
							    kNCol,    // ncols (total for module)
							    kNRow,    // nrows
							    kPitchX,  // default row pitch in cm
							    kPitchZ,  // default col pitch in cm
							    kSensThick,  // sensor thickness in cm
							    -1,     // no special left col between chips
							    -1,     // no special right col between chips
							    kLeftRightEdge, // left
							    kLeftRightEdge, // right
							    kTopEdge, // top
							    kReadOutEdge  // bottom
							    );    // see AliITSMFTSegmentationPix.h for extra options
  //
  //seg0->Store(AliITSUGeomTGeo::GetITSsegmentationFileName());
  seg0->Store("itsSegmentations.root");
  //
  seg0->Print();
  cout<<"<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>"<<endl;
  //
  double dzLr,rLr,phi0,turbo;
  int nStaveLr,nModPerStaveLr,idLr;
  //
  AliITSUv2 *ITS  = new AliITSUv2("ITS Upgrade",kNLr);
  ITS->SetStaveModelIB(AliITSUv2::kIBModel4);
  ITS->SetStaveModelOB(AliITSUv2::kOBModel2);
  //
  const int kNWrapVol = 3;
  const double wrpRMin[kNWrapVol]  = { 2.1, 15.0, 32.0};
  const double wrpRMax[kNWrapVol]  = {14.0, 30.0, 46.0};
  const double wrpZSpan[kNWrapVol] = {70., 95., 200.};
  //
  ITS->SetNWrapVolumes(kNWrapVol); // define wrapper volumes for layers
  for (int iw=0;iw<kNWrapVol;iw++) ITS->DefineWrapVolume(iw,wrpRMin[iw],wrpRMax[iw],wrpZSpan[iw]);
  //
  for (int idLr=0;idLr<kNLr;idLr++) {
    rLr   = tdr5dat[idLr][kRmd];
    phi0  = tdr5dat[idLr][kPhi0];
    //
    nStaveLr = TMath::Nint(tdr5dat[idLr][kNStave]);
    nModPerStaveLr =  TMath::Nint(tdr5dat[idLr][kNModPerStave]);
    int nChipsPerStaveLr = nModPerStaveLr;
    //
    if (idLr>=kNLrInner) {
      double modlen = nChipsPerModule*seg0->Dz() + (nChipsPerModule-1)*zChipGap;
      double zlen = nModPerStaveLr*modlen + (nModPerStaveLr-1)*zModuleGap;
      ITS->DefineLayer(idLr, phi0, rLr, zlen, nStaveLr, nModPerStaveLr,
		       kSiThickOB, seg0->Dy(), seg0->GetChipTypeID(),kBuildLevel);
    } else {
      turbo = radii2Turbo(tdr5dat[idLr][kRmn],rLr,tdr5dat[idLr][kRmx],seg0->Dx());
      ITS->DefineLayerTurbo(idLr, phi0, rLr, nChipsPerStaveLr*seg0->Dz(), nStaveLr, nChipsPerStaveLr,
			    seg0->Dx(), turbo, kSiThickIB, seg0->Dy(), seg0->GetChipTypeID(),kBuildLevel);
    }

  }

}
<|endoftext|>


<commit_before>/** \brief Utility for updating SQL schemata etc.
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2019-2020 Universitätsbibliothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program 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 Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <algorithm>
#include <iostream>
#include <utility>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include "Compiler.h"
#include "FileUtil.h"
#include "DbConnection.h"
#include "StringUtil.h"
#include "util.h"

namespace {

[[noreturn]] void Usage() {
    ::Usage("[--test] update_directory_path");
}

void SplitIntoDatabaseAndVersion(const std::string &update_filename, std::string * const database, unsigned * const version) {
    const auto first_dot_pos(update_filename.find('.'));
    if (first_dot_pos == std::string::npos or first_dot_pos == 0 or first_dot_pos == update_filename.length() - 1)
        LOG_ERROR("invalid update filename \"" + update_filename + "\"!");

    if (not StringUtil::ToUnsigned(update_filename.substr(first_dot_pos + 1), version))
        LOG_ERROR("bad or missing version in update filename \"" + update_filename + "\"!");

    *database = update_filename.substr(0, first_dot_pos);
}

// The filenames being compared are assumed to have the "structure database.version]*"
bool FileNameCompare(const std::string &filename1, const std::string &filename2) {
    std::string database1;
    unsigned version1;
    SplitIntoDatabaseAndVersion(filename1, &database1, &version1);

    std::string database2;
    unsigned version2;
    SplitIntoDatabaseAndVersion(filename2, &database2, &version2);

    // Compare database names:
    if (database1 < database2)
        return true;
    if (database1 > database2)
        return false;

    return version1 < version2;
}

void LoadAndSortUpdateFilenames(const bool test, const std::string &directory_path, std::vector<std::string> * const update_filenames) {
    FileUtil::Directory directory(directory_path, "[^.]+\\.\\d+");
    for (const auto &entry : directory)
        update_filenames->emplace_back(entry.getName());

    std::sort(update_filenames->begin(), update_filenames->end(), FileNameCompare);

    if (test) {
        std::cerr << "Sorted filenames:\n";
        for (const auto &filename : *update_filenames)
            std::cerr << filename << '\n';
        std::exit(0);
    }
}

void ApplyUpdate(DbConnection * const db_connection, const std::string &update_directory_path, const std::string &update_filename) {
    std::string database;
    unsigned update_version;
    SplitIntoDatabaseAndVersion(update_filename, &database, &update_version);

    if (not db_connection->mySQLDatabaseExists(database)) {
        LOG_INFO("database \"" + database + "\" does not exist, skipping file " + update_filename);
        return;
    }

    DbTransaction transaction(db_connection); // No new scape required as the transaction is supposed to last until the end
                                              // of this function anyway!

    unsigned current_version(0);
    db_connection->queryOrDie("SELECT version FROM ub_tools.database_versions WHERE database_name='"
                              + db_connection->escapeString(database) + "'");
    DbResultSet result_set(db_connection->getLastResultSet());
    if (result_set.empty()) {
        db_connection->queryOrDie("INSERT INTO ub_tools.database_versions (database_name,version) VALUES ('"
                                  + db_connection->escapeString(database) + "',0)");
            LOG_INFO("Created a new entry for database \"" + database + " in ub_tools.database_versions.");
    } else
        current_version = StringUtil::ToUnsigned(result_set.getNextRow()["version"]);
    if (update_version <= current_version)
        return;

    // Sanity check:
    if (unlikely(update_version != current_version + 1))
        LOG_ERROR("update version is " + std::to_string(update_version) + ", current version is "
                  + std::to_string(current_version) + " for database \"" + database + "\"!");

    LOG_INFO("applying update " + std::to_string(update_version) + " to database \"" + database + "\".");
    db_connection->queryFileOrDie(update_directory_path + "/" + update_filename);
    db_connection->queryOrDie("UPDATE ub_tools.database_versions SET version=" + std::to_string(update_version)
                              + " WHERE database_name='" + db_connection->escapeString(database) + "'");
}

} // unnamed namespace

int Main(int argc, char *argv[]) {
    if (argc != 2 and argc != 3)
        Usage();

    bool test(false);
    if (argc == 3) {
        if (std::strcmp(argv[1], "--test") != 0)
            Usage();
        test = true;
        --argc, ++argv;
    }

    std::vector<std::string> update_filenames;
    const std::string update_directory_path(argv[1]);
    LoadAndSortUpdateFilenames(test, update_directory_path, &update_filenames);

    DbConnection db_connection;
    const std::string system_table_name("database_versions");
    if (not db_connection.tableExists("ub_tools", system_table_name)) {
        db_connection.queryOrDie("CREATE TABLE ub_tools." + system_table_name + " (version INT UNSIGNED NOT NULL,"
                                 "database_name VARCHAR(64) NOT NULL,UNIQUE (database_name)) "
                                 "CHARACTER SET utf8mb4 COLLATE utf8mb4_bin");
        LOG_INFO("Created the ub_tools." + system_table_name + " table.");
    }

    for (const auto &update_filename : update_filenames)
        ApplyUpdate(&db_connection, update_directory_path, update_filename);

    return EXIT_SUCCESS;
}
<commit_msg>Fixed a typo.<commit_after>/** \brief Utility for updating SQL schemata etc.
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2019-2020 Universitätsbibliothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program 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 Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <algorithm>
#include <iostream>
#include <utility>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include "Compiler.h"
#include "FileUtil.h"
#include "DbConnection.h"
#include "StringUtil.h"
#include "util.h"

namespace {

[[noreturn]] void Usage() {
    ::Usage("[--test] update_directory_path");
}

void SplitIntoDatabaseAndVersion(const std::string &update_filename, std::string * const database, unsigned * const version) {
    const auto first_dot_pos(update_filename.find('.'));
    if (first_dot_pos == std::string::npos or first_dot_pos == 0 or first_dot_pos == update_filename.length() - 1)
        LOG_ERROR("invalid update filename \"" + update_filename + "\"!");

    if (not StringUtil::ToUnsigned(update_filename.substr(first_dot_pos + 1), version))
        LOG_ERROR("bad or missing version in update filename \"" + update_filename + "\"!");

    *database = update_filename.substr(0, first_dot_pos);
}

// The filenames being compared are assumed to have the "structure database.version]*"
bool FileNameCompare(const std::string &filename1, const std::string &filename2) {
    std::string database1;
    unsigned version1;
    SplitIntoDatabaseAndVersion(filename1, &database1, &version1);

    std::string database2;
    unsigned version2;
    SplitIntoDatabaseAndVersion(filename2, &database2, &version2);

    // Compare database names:
    if (database1 < database2)
        return true;
    if (database1 > database2)
        return false;

    return version1 < version2;
}

void LoadAndSortUpdateFilenames(const bool test, const std::string &directory_path, std::vector<std::string> * const update_filenames) {
    FileUtil::Directory directory(directory_path, "[^.]+\\.\\d+");
    for (const auto &entry : directory)
        update_filenames->emplace_back(entry.getName());

    std::sort(update_filenames->begin(), update_filenames->end(), FileNameCompare);

    if (test) {
        std::cerr << "Sorted filenames:\n";
        for (const auto &filename : *update_filenames)
            std::cerr << filename << '\n';
        std::exit(0);
    }
}

void ApplyUpdate(DbConnection * const db_connection, const std::string &update_directory_path, const std::string &update_filename) {
    std::string database;
    unsigned update_version;
    SplitIntoDatabaseAndVersion(update_filename, &database, &update_version);

    if (not db_connection->mySQLDatabaseExists(database)) {
        LOG_INFO("database \"" + database + "\" does not exist, skipping file " + update_filename);
        return;
    }

    DbTransaction transaction(db_connection); // No new scope required as the transaction is supposed to last until the end
                                              // of this function anyway!

    unsigned current_version(0);
    db_connection->queryOrDie("SELECT version FROM ub_tools.database_versions WHERE database_name='"
                              + db_connection->escapeString(database) + "'");
    DbResultSet result_set(db_connection->getLastResultSet());
    if (result_set.empty()) {
        db_connection->queryOrDie("INSERT INTO ub_tools.database_versions (database_name,version) VALUES ('"
                                  + db_connection->escapeString(database) + "',0)");
            LOG_INFO("Created a new entry for database \"" + database + " in ub_tools.database_versions.");
    } else
        current_version = StringUtil::ToUnsigned(result_set.getNextRow()["version"]);
    if (update_version <= current_version)
        return;

    // Sanity check:
    if (unlikely(update_version != current_version + 1))
        LOG_ERROR("update version is " + std::to_string(update_version) + ", current version is "
                  + std::to_string(current_version) + " for database \"" + database + "\"!");

    LOG_INFO("applying update " + std::to_string(update_version) + " to database \"" + database + "\".");
    db_connection->queryFileOrDie(update_directory_path + "/" + update_filename);
    db_connection->queryOrDie("UPDATE ub_tools.database_versions SET version=" + std::to_string(update_version)
                              + " WHERE database_name='" + db_connection->escapeString(database) + "'");
}

} // unnamed namespace

int Main(int argc, char *argv[]) {
    if (argc != 2 and argc != 3)
        Usage();

    bool test(false);
    if (argc == 3) {
        if (std::strcmp(argv[1], "--test") != 0)
            Usage();
        test = true;
        --argc, ++argv;
    }

    std::vector<std::string> update_filenames;
    const std::string update_directory_path(argv[1]);
    LoadAndSortUpdateFilenames(test, update_directory_path, &update_filenames);

    DbConnection db_connection;
    const std::string system_table_name("database_versions");
    if (not db_connection.tableExists("ub_tools", system_table_name)) {
        db_connection.queryOrDie("CREATE TABLE ub_tools." + system_table_name + " (version INT UNSIGNED NOT NULL,"
                                 "database_name VARCHAR(64) NOT NULL,UNIQUE (database_name)) "
                                 "CHARACTER SET utf8mb4 COLLATE utf8mb4_bin");
        LOG_INFO("Created the ub_tools." + system_table_name + " table.");
    }

    for (const auto &update_filename : update_filenames)
        ApplyUpdate(&db_connection, update_directory_path, update_filename);

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*
Copyright (C) 2016 iNuron NV

This file is part of Open vStorage Open Source Edition (OSE), as available from

    http://www.openvstorage.org and
    http://www.openvstorage.com.

This file is free software; you can redistribute it and/or modify it
under the terms of the GNU Affero General Public License v3 (GNU AGPLv3)
as published by the Free Software Foundation, in version 3 as it comes
in the <LICENSE.txt> file of the Open vStorage OSE distribution.

Open vStorage is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY of any kind.
*/

#include "manifest_cache.h"

namespace alba {
namespace proxy_client {

ManifestCache &ManifestCache::getInstance() {
  static ManifestCache instance;
  return instance;
}

static size_t _manifest_cache_capacity = 10000;
void ManifestCache::set_capacity(size_t capacity) {
  _manifest_cache_capacity = capacity;
}

void ManifestCache::add(std::string namespace_, std::string object_name,
                        std::shared_ptr<Manifest> mfp) {
  ALBA_LOG(DEBUG, "ManifestCache::add");

  std::shared_ptr<manifest_cache> mcp = nullptr;
  std::shared_ptr<std::mutex> mp = nullptr;
  {
    std::lock_guard<std::mutex> lock(_level1_mutex);
    auto it1 = _level1.find(namespace_);

    if (it1 == _level1.end()) {
      ALBA_LOG(INFO, "ManifestCache::add namespace:'"
                         << namespace_ << "' : new manifest cache");
      std::shared_ptr<manifest_cache> mc(new manifest_cache);
      std::shared_ptr<std::mutex> mm(new std::mutex);
      auto p = std::make_pair(mc, mm);
      _level1[namespace_] = std::move(p);
      it1 = _level1.find(namespace_);
    } else {
      ALBA_LOG(DEBUG, "ManifestCache::add namespace:'"
                          << namespace_ << "' : existing manifest cache");
    }
    const auto &v = it1->second;
    mcp = v.first;
    mp = v.second;
  }

  manifest_cache &manifest_cache = *mcp;
  std::mutex &m = *mp;
  {
    std::lock_guard<std::mutex> lock(m);
    auto it2 = manifest_cache.find(object_name);
    if (it2 != manifest_cache.end()) {
      manifest_cache.erase(it2);
    }

    if (manifest_cache.size() > _manifest_cache_capacity) {
      auto it_victim = manifest_cache.begin();
      int size = manifest_cache.size();
      if (size > 0) {
        std::advance(it_victim, rand() % size); // O(size) :(
      }
      auto victim = it_victim->first;
      using namespace alba::stuff;
      ALBA_LOG(DEBUG, "cache '" << namespace_ << "' full("
                                << _manifest_cache_capacity
                                << "), evicting victim: " << victim);
      manifest_cache.erase(it_victim);
    }

    manifest_cache[object_name] = std::move(mfp);
  }
}

std::shared_ptr<Manifest> ManifestCache::find(const std::string &namespace_,
                                              const std::string &object_name) {
  std::pair<std::shared_ptr<manifest_cache>, std::shared_ptr<std::mutex>> vp;
  {
    std::lock_guard<std::mutex> g(_level1_mutex);
    auto it = _level1.find(namespace_);
    if (it == _level1.end()) {
      return nullptr;
    } else {
      vp = it->second;
    }
  }
  auto &map = *vp.first;
  auto &mm = *vp.second;
  {
    std::lock_guard<std::mutex> g(mm);
    const auto &map_it = map.find(object_name);
    if (map_it == map.end()) {
      return nullptr;
    } else {
      return map_it->second;
    }
  }
}

void ManifestCache::invalidate_namespace(const std::string &namespace_) {
  ALBA_LOG(DEBUG, "ManifestCache::invalidate_namespace(" << namespace_ << ")");
  std::lock_guard<std::mutex> g(_level1_mutex);
  auto it = _level1.find(namespace_);
  if (it != _level1.end()) {
    _level1.erase(it);
  }
}
}
}
<commit_msg>don't be defensive here.<commit_after>/*
Copyright (C) 2016 iNuron NV

This file is part of Open vStorage Open Source Edition (OSE), as available from

    http://www.openvstorage.org and
    http://www.openvstorage.com.

This file is free software; you can redistribute it and/or modify it
under the terms of the GNU Affero General Public License v3 (GNU AGPLv3)
as published by the Free Software Foundation, in version 3 as it comes
in the <LICENSE.txt> file of the Open vStorage OSE distribution.

Open vStorage is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY of any kind.
*/

#include "manifest_cache.h"

namespace alba {
namespace proxy_client {

ManifestCache &ManifestCache::getInstance() {
  static ManifestCache instance;
  return instance;
}

static size_t _manifest_cache_capacity = 10000;
void ManifestCache::set_capacity(size_t capacity) {
  _manifest_cache_capacity = capacity;
}

void ManifestCache::add(std::string namespace_, std::string object_name,
                        std::shared_ptr<Manifest> mfp) {
  ALBA_LOG(DEBUG, "ManifestCache::add");

  std::shared_ptr<manifest_cache> mcp = nullptr;
  std::shared_ptr<std::mutex> mp = nullptr;
  {
    std::lock_guard<std::mutex> lock(_level1_mutex);
    auto it1 = _level1.find(namespace_);

    if (it1 == _level1.end()) {
      ALBA_LOG(INFO, "ManifestCache::add namespace:'"
                         << namespace_ << "' : new manifest cache");
      std::shared_ptr<manifest_cache> mc(new manifest_cache);
      std::shared_ptr<std::mutex> mm(new std::mutex);
      auto p = std::make_pair(mc, mm);
      _level1[namespace_] = std::move(p);
      it1 = _level1.find(namespace_);
    } else {
      ALBA_LOG(DEBUG, "ManifestCache::add namespace:'"
                          << namespace_ << "' : existing manifest cache");
    }
    const auto &v = it1->second;
    mcp = v.first;
    mp = v.second;
  }

  manifest_cache &manifest_cache = *mcp;
  std::mutex &m = *mp;
  {
    std::lock_guard<std::mutex> lock(m);
    auto it2 = manifest_cache.find(object_name);
    if (it2 != manifest_cache.end()) {
      manifest_cache.erase(it2);
    }

    if (manifest_cache.size() > _manifest_cache_capacity) {
      auto it_victim = manifest_cache.begin();
      int size = manifest_cache.size();
      std::advance(it_victim, rand() % size); // O(size) :(
      auto victim = it_victim->first;
      using namespace alba::stuff;
      ALBA_LOG(DEBUG, "cache '" << namespace_ << "' full("
                                << _manifest_cache_capacity
                                << "), evicting victim: " << victim);
      manifest_cache.erase(it_victim);
    }

    manifest_cache[object_name] = std::move(mfp);
  }
}

std::shared_ptr<Manifest> ManifestCache::find(const std::string &namespace_,
                                              const std::string &object_name) {
  std::pair<std::shared_ptr<manifest_cache>, std::shared_ptr<std::mutex>> vp;
  {
    std::lock_guard<std::mutex> g(_level1_mutex);
    auto it = _level1.find(namespace_);
    if (it == _level1.end()) {
      return nullptr;
    } else {
      vp = it->second;
    }
  }
  auto &map = *vp.first;
  auto &mm = *vp.second;
  {
    std::lock_guard<std::mutex> g(mm);
    const auto &map_it = map.find(object_name);
    if (map_it == map.end()) {
      return nullptr;
    } else {
      return map_it->second;
    }
  }
}

void ManifestCache::invalidate_namespace(const std::string &namespace_) {
  ALBA_LOG(DEBUG, "ManifestCache::invalidate_namespace(" << namespace_ << ")");
  std::lock_guard<std::mutex> g(_level1_mutex);
  auto it = _level1.find(namespace_);
  if (it != _level1.end()) {
    _level1.erase(it);
  }
}
}
}
<|endoftext|>