<commit_before>#include "SahoteApp.h"
#include "Moose.h"
#include "AppFactory.h"

// Include kernel header files
#include "RadiationHeatSource.h"
#include "MatPropDiffusion.h"
#include "Convection.h"

// Include auxkernel header files
#include "BeamHeating.h"
#include "MaterialHeatAux.h"
#include "VelocityAux.h"

// Next come the materials
#include "SahoteMaterial.h"

// Next come the boundary conditions
#include "CRUDCoolantNeumannBC.h"
#include "CoolantNeumannBC.h"

template<>
InputParameters validParams<SahoteApp>()
{
  InputParameters params = validParams<MooseApp>();
  return params;
}

SahoteApp::SahoteApp(const std::string & name, InputParameters parameters) :
    MooseApp(name, parameters)
{
  srand(processor_id());

  Moose::registerObjects(_factory);
  SahoteApp::registerObjects(_factory);

  Moose::associateSyntax(_syntax, _action_factory);
  SahoteApp::associateSyntax(_syntax, _action_factory);
}

SahoteApp::~SahoteApp()
{
}

void
SahoteApp::registerApps()
{
  registerApp(SahoteApp);
}

void
SahoteApp::registerObjects(Factory & factory)
{
  // Register kernels
  registerKernel(RadiationHeatSource);
  registerKernel(MatPropDiffusion);
  registerKernel(Convection);

  // Register auxkernels
  registerAux(BeamHeating);
  registerAux(MaterialHeatAux);
  registerAux(VelocityAux);

  // Register materials classes
  registerMaterial(SahoteMaterial);

  // Register boundary conditions
  registerBoundaryCondition(CRUDCoolantNeumannBC);
  registerBoundaryCondition(CoolantNeumannBC);
}

void
SahoteApp::associateSyntax(Syntax & syntax, ActionFactory & action_factory)
{
}
<commit_msg>Adding support for dynamic multiapps (see https://github.com/idaholab/moose/issues/4643)<commit_after>#include "SahoteApp.h"
#include "Moose.h"
#include "AppFactory.h"

// Include kernel header files
#include "RadiationHeatSource.h"
#include "MatPropDiffusion.h"
#include "Convection.h"

// Include auxkernel header files
#include "BeamHeating.h"
#include "MaterialHeatAux.h"
#include "VelocityAux.h"

// Next come the materials
#include "SahoteMaterial.h"

// Next come the boundary conditions
#include "CRUDCoolantNeumannBC.h"
#include "CoolantNeumannBC.h"

template<>
InputParameters validParams<SahoteApp>()
{
  InputParameters params = validParams<MooseApp>();
  return params;
}

SahoteApp::SahoteApp(const std::string & name, InputParameters parameters) :
    MooseApp(name, parameters)
{
  srand(processor_id());

  Moose::registerObjects(_factory);
  SahoteApp::registerObjects(_factory);

  Moose::associateSyntax(_syntax, _action_factory);
  SahoteApp::associateSyntax(_syntax, _action_factory);
}

SahoteApp::~SahoteApp()
{
}

extern "C" void SahoteApp__registerApps() { SahoteApp::registerApps(); }
void
SahoteApp::registerApps()
{
  registerApp(SahoteApp);
}

void
SahoteApp::registerObjects(Factory & factory)
{
  // Register kernels
  registerKernel(RadiationHeatSource);
  registerKernel(MatPropDiffusion);
  registerKernel(Convection);

  // Register auxkernels
  registerAux(BeamHeating);
  registerAux(MaterialHeatAux);
  registerAux(VelocityAux);

  // Register materials classes
  registerMaterial(SahoteMaterial);

  // Register boundary conditions
  registerBoundaryCondition(CRUDCoolantNeumannBC);
  registerBoundaryCondition(CoolantNeumannBC);
}

void
SahoteApp::associateSyntax(Syntax & syntax, ActionFactory & action_factory)
{
}
<|endoftext|>


<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield
 *
 * This application is open source and may be redistributed and/or modified
 * freely and without restriction, both in commericial and non commericial applications,
 * as long as this copyright notice is maintained.
 *
 * This application 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.
*/

#include <osgDB/FileUtils>
#include <osg/Version>

#include "PluginQuery.h"

using namespace osgDB;

FileNameList osgDB::listAllAvailablePlugins()
{
    FileNameList pluginFiles;

    std::string pluginDirectoryName = std::string("osgPlugins-")+std::string(osgGetVersion());
    std::string fullPath = osgDB::findLibraryFile(pluginDirectoryName);
    if (!fullPath.empty())
    {
        osgDB::DirectoryContents contents = getDirectoryContents(fullPath);
        for(DirectoryContents::iterator itr = contents.begin();
            itr != contents.end();
            ++itr)
        {
            std::string::size_type pos = itr->find("osgdb_");
            if (pos!=std::string::npos)
            {
                pluginFiles.push_back(fullPath + std::string("/")+*itr);
            }
        }
    }

    return pluginFiles;
}

bool osgDB::queryPlugin(const std::string& fileName, ReaderWriterInfoList& infoList)
{
    if (osgDB::Registry::instance()->loadLibrary(fileName))
    {
        const Registry::ReaderWriterList& rwList = osgDB::Registry::instance()->getReaderWriterList();
        for(Registry::ReaderWriterList::const_iterator itr = rwList.begin();
            itr != rwList.end();
            ++itr)
        {
            const ReaderWriter* rw = itr->get();
            osg::ref_ptr<ReaderWriterInfo> rwi = new ReaderWriterInfo;
            rwi->plugin = fileName;
            rwi->description = rw->className();
            rwi->protocols = rw->supportedProtocols();
            rwi->extensions = rw->supportedExtensions();
            rwi->options = rw->supportedOptions();

            infoList.push_back(rwi.get());
        }

        osgDB::Registry::instance()->closeLibrary(fileName);
        return true;
    }
    else
    {
        return false;
    }
}

static std::string padwithspaces(const std::string& str, unsigned int padLength)
{
    std::string newStr(str);
    while(newStr.length()<padLength) newStr.push_back(' ');
    return newStr;
}

bool osgDB::outputPluginDetails(std::ostream& out, const std::string& fileName)
{

    out<<"Plugin "<<fileName<<std::endl;
    out<<"{"<<std::endl;
    osgDB::ReaderWriterInfoList infoList;
    if (osgDB::queryPlugin(fileName, infoList))
    {
        for(osgDB::ReaderWriterInfoList::iterator rwi_itr = infoList.begin();
            rwi_itr != infoList.end();
            ++rwi_itr)
        {
            osgDB::ReaderWriterInfo& info = *(*rwi_itr);
            out<<"    ReaderWriter : "<<info.description<<std::endl;
            out<<"    {"<<std::endl;

            unsigned int longestOptionLength = 0;
            osgDB::ReaderWriter::FormatDescriptionMap::iterator fdm_itr;
            for(fdm_itr = info.protocols.begin();
                fdm_itr != info.protocols.end();
                ++fdm_itr)
            {
                if (fdm_itr->first.length()>longestOptionLength) longestOptionLength = fdm_itr->first.length();
            }

            for(fdm_itr = info.extensions.begin();
                fdm_itr != info.extensions.end();
                ++fdm_itr)
            {
                if (fdm_itr->first.length()>longestOptionLength) longestOptionLength = fdm_itr->first.length();
            }

            for(fdm_itr = info.options.begin();
                fdm_itr != info.options.end();
                ++fdm_itr)
            {
                if (fdm_itr->first.length()>longestOptionLength) longestOptionLength = fdm_itr->first.length();
            }

            unsigned int padLength = longestOptionLength+4;

            for(fdm_itr = info.protocols.begin();
                fdm_itr != info.protocols.end();
                ++fdm_itr)
            {
                out<<"        protocol   : "<<padwithspaces(fdm_itr->first, padLength)<<fdm_itr->second<<std::endl;
            }

            for(fdm_itr = info.extensions.begin();
                fdm_itr != info.extensions.end();
                ++fdm_itr)
            {
                out<<"        extensions : ."<<padwithspaces(fdm_itr->first, padLength-1)<<fdm_itr->second<<std::endl;
            }

            for(fdm_itr = info.options.begin();
                fdm_itr != info.options.end();
                ++fdm_itr)
            {
                out<<"        options    : "<<padwithspaces(fdm_itr->first, padLength)<<fdm_itr->second<<std::endl;
            }
            out<<"    }"<<std::endl;
        }
    }
    out<<"}"<<std::endl<<std::endl;
}

<commit_msg>Improved the feedback for when a plugin isn't available.<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield
 *
 * This application is open source and may be redistributed and/or modified
 * freely and without restriction, both in commericial and non commericial applications,
 * as long as this copyright notice is maintained.
 *
 * This application 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.
*/

#include <osgDB/FileUtils>
#include <osg/Version>

#include "PluginQuery.h"

using namespace osgDB;

FileNameList osgDB::listAllAvailablePlugins()
{
    FileNameList pluginFiles;

    std::string pluginDirectoryName = std::string("osgPlugins-")+std::string(osgGetVersion());
    std::string fullPath = osgDB::findLibraryFile(pluginDirectoryName);
    if (!fullPath.empty())
    {
        osgDB::DirectoryContents contents = getDirectoryContents(fullPath);
        for(DirectoryContents::iterator itr = contents.begin();
            itr != contents.end();
            ++itr)
        {
            std::string::size_type pos = itr->find("osgdb_");
            if (pos!=std::string::npos)
            {
                pluginFiles.push_back(fullPath + std::string("/")+*itr);
            }
        }
    }

    return pluginFiles;
}

bool osgDB::queryPlugin(const std::string& fileName, ReaderWriterInfoList& infoList)
{
    if (osgDB::Registry::instance()->loadLibrary(fileName))
    {
        const Registry::ReaderWriterList& rwList = osgDB::Registry::instance()->getReaderWriterList();
        for(Registry::ReaderWriterList::const_iterator itr = rwList.begin();
            itr != rwList.end();
            ++itr)
        {
            const ReaderWriter* rw = itr->get();
            osg::ref_ptr<ReaderWriterInfo> rwi = new ReaderWriterInfo;
            rwi->plugin = fileName;
            rwi->description = rw->className();
            rwi->protocols = rw->supportedProtocols();
            rwi->extensions = rw->supportedExtensions();
            rwi->options = rw->supportedOptions();

            infoList.push_back(rwi.get());
        }

        osgDB::Registry::instance()->closeLibrary(fileName);
        return true;
    }
    else
    {
        return false;
    }
}

static std::string padwithspaces(const std::string& str, unsigned int padLength)
{
    std::string newStr(str);
    while(newStr.length()<padLength) newStr.push_back(' ');
    return newStr;
}

bool osgDB::outputPluginDetails(std::ostream& out, const std::string& fileName)
{
    osgDB::ReaderWriterInfoList infoList;
    if (osgDB::queryPlugin(fileName, infoList))
    {
        out<<"Plugin "<<fileName<<std::endl;
        out<<"{"<<std::endl;

        for(osgDB::ReaderWriterInfoList::iterator rwi_itr = infoList.begin();
            rwi_itr != infoList.end();
            ++rwi_itr)
        {
            osgDB::ReaderWriterInfo& info = *(*rwi_itr);
            out<<"    ReaderWriter : "<<info.description<<std::endl;
            out<<"    {"<<std::endl;

            unsigned int longestOptionLength = 0;
            osgDB::ReaderWriter::FormatDescriptionMap::iterator fdm_itr;
            for(fdm_itr = info.protocols.begin();
                fdm_itr != info.protocols.end();
                ++fdm_itr)
            {
                if (fdm_itr->first.length()>longestOptionLength) longestOptionLength = fdm_itr->first.length();
            }

            for(fdm_itr = info.extensions.begin();
                fdm_itr != info.extensions.end();
                ++fdm_itr)
            {
                if (fdm_itr->first.length()>longestOptionLength) longestOptionLength = fdm_itr->first.length();
            }

            for(fdm_itr = info.options.begin();
                fdm_itr != info.options.end();
                ++fdm_itr)
            {
                if (fdm_itr->first.length()>longestOptionLength) longestOptionLength = fdm_itr->first.length();
            }

            unsigned int padLength = longestOptionLength+4;

            for(fdm_itr = info.protocols.begin();
                fdm_itr != info.protocols.end();
                ++fdm_itr)
            {
                out<<"        protocol   : "<<padwithspaces(fdm_itr->first, padLength)<<fdm_itr->second<<std::endl;
            }

            for(fdm_itr = info.extensions.begin();
                fdm_itr != info.extensions.end();
                ++fdm_itr)
            {
                out<<"        extensions : ."<<padwithspaces(fdm_itr->first, padLength-1)<<fdm_itr->second<<std::endl;
            }

            for(fdm_itr = info.options.begin();
                fdm_itr != info.options.end();
                ++fdm_itr)
            {
                out<<"        options    : "<<padwithspaces(fdm_itr->first, padLength)<<fdm_itr->second<<std::endl;
            }
            out<<"    }"<<std::endl;
        }
        out<<"}"<<std::endl<<std::endl;
    }
    else
    {
        out<<"Plugin "<<fileName<<" not found."<<std::endl;
    }
}

<|endoftext|>


<commit_before>// Copyright (c) 2015 Andrew Sutton
// All rights reserved

#ifndef LINGO_NODE_HPP
#define LINGO_NODE_HPP

#include <cassert>

// This module provides defines a node abstraction for various
// kinds of trees used in different languages and facilities
// for working with those abstractions.

namespace lingo
{

// The Kind_of class is a helper class that supports the definition
// of node models. This provides a static representation of the
// node kind and a static `is` function for dynamic type testing.
template<typename T, T K>
struct Kind_base
{
  static constexpr T node_kind = K;

  static bool is(T k) { return node_kind == k; }
};

// -------------------------------------------------------------------------- //
//                        Dynamic type information

// Returns true if the object pointed to by `u` has
// the dynamic type `T`.
template<typename T, typename U>
inline bool
is(U const* u)
{
  return T::is(u->kind());
}

// Statically cast a pointer to a Node of type T to a
// pointer to a Node of type U. This is not a checked
// operation.
//
// TODO: Support checking by making node kind
// a static property of all node classes.
template<typename T, typename U>
inline T*
cast(U* u)
{
  assert(is<T>(u));
  return static_cast<T*>(u);
}

template<typename T, typename U>
inline T const*
cast(U const* u)
{
  assert(is<T>(u));
  return static_cast<T const*>(u);
}

// Returns `u` with type `T*` iff the object pointed
// to by `u` has dynamic type `T`.
template<typename T, typename U>
inline T*
as(U* u)
{
  return is<T>(u) ? cast<T>(u) : nullptr;
}

template<typename T, typename U>
inline T const*
as(U const* u)
{
  return is<T>(u) ? cast<T>(u) : nullptr;
}

} // namespace lingo

#endif
<commit_msg>Improve support for error nodes.<commit_after>// Copyright (c) 2015 Andrew Sutton
// All rights reserved

#ifndef LINGO_NODE_HPP
#define LINGO_NODE_HPP

#include <cassert>

// This module provides defines a node abstraction for various
// kinds of trees used in different languages and facilities
// for working with those abstractions.

namespace lingo
{

// The Kind_of class is a helper class that supports the definition
// of node models. This provides a static representation of the
// node kind and a static `is` function for dynamic type testing.
template<typename T, T K>
struct Kind_base
{
  static constexpr T node_kind = K;

  static bool is(T k) { return node_kind == k; }
};

// -------------------------------------------------------------------------- //
//                        Dynamic type information

// Returns true if the object pointed to by `u` has
// the dynamic type `T`.
template<typename T, typename U>
inline bool
is(U const* u)
{
  return T::is(u->kind());
}

// Statically cast a pointer to a Node of type T to a
// pointer to a Node of type U. This is not a checked
// operation.
//
// TODO: Support checking by making node kind
// a static property of all node classes.
template<typename T, typename U>
inline T*
cast(U* u)
{
  assert(is<T>(u));
  return static_cast<T*>(u);
}

template<typename T, typename U>
inline T const*
cast(U const* u)
{
  assert(is<T>(u));
  return static_cast<T const*>(u);
}

// Returns `u` with type `T*` iff the object pointed
// to by `u` has dynamic type `T`.
template<typename T, typename U>
inline T*
as(U* u)
{
  return is<T>(u) ? cast<T>(u) : nullptr;
}

template<typename T, typename U>
inline T const*
as(U const* u)
{
  return is<T>(u) ? cast<T>(u) : nullptr;
}

// -------------------------------------------------------------------------- //
//                            Special values
//
// The following functions define special values of node pointers.

// Construct a node pointer that acts as an error value.
// The type of the node is explicitly given as a template
// argument.
template<typename T>
inline T*
make_error()
{
  return (T*)0x01;
}

// Returns true if `t` is null.
template<typename T>
inline bool
is_null(T const* p)
{
  return p == nullptr;
}

// Returns true if `t` is null.
template<typename T>
inline bool
is_error(T const* p)
{
  return p == make_error<T>();
}

// Returns true if p is neither null nor an error.
template<typename T>
inline bool
is_node(T const* p)
{
  return !is_null(p) && !is_error(p);
}

// The Maybe template is typically used to declare node
// pointers within condition declarations.
//
//    if (Maybe<Var_decl> var = ...)
//
// This class contextually evaluates to `true` whenever
// it is initialized to a non-null, non-error value.
template<typename T>
struct Maybe
{
  Maybe(T* p)
    : ptr(p)
  { }

  explicit operator bool() const { is_node(ptr); }

  T*       operator*()       { return ptr; }
  T const* operator*() const { return ptr; }

  T* ptr;
};

} // namespace lingo

#endif
<|endoftext|>


<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2015 Relja Ljubobratovic, ljubobratovic.relja@gmail.com
//
// 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.
//
// Description:
// Collection of functions for calibration pattern detection.
//
// Author:
// Relja Ljubobratovic, ljubobratovic.relja@gmail.com

#ifndef CALIBPATTERN_HPP_ORZQNP5Z
#define CALIBPATTERN_HPP_ORZQNP5Z

#include <vector>

#include <contour.hpp>
#include <vector.hpp>
#include <matrix.hpp>
#include <draw.hpp>

std::vector<cv::vec2r> detect_pattern(const cv::matrixr &image, unsigned patternRows, unsigned patternCols,
		real_t angThresh = 15., real_t magThresh = 0.15, unsigned nnCount = 8);

std::vector<cv::vec2r> sub_pixel_detect(const std::vector<cv::vec2r> &corners, const cv::matrixr &src,
		const cv::vec2i &win = {10, 10}, real_t eps = 10e-6, unsigned maxIters = 100);

template<typename _Tp>
void draw_chessboard(cv::matrix<_Tp> &image, const std::vector<cv::vec2r> &pattern, const _Tp &color) {

	ASSERT(image && !pattern.empty());

	for (unsigned i = 1; i < pattern.size(); ++i) {
		cv::draw_line(image, pattern[i-1], pattern[i], color);
	}
}

#endif /* end of include guard: CALIBPATTERN_HPP_ORZQNP5Z */

<commit_msg>changed defaults in detect_pattern<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2015 Relja Ljubobratovic, ljubobratovic.relja@gmail.com
//
// 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.
//
// Description:
// Collection of functions for calibration pattern detection.
//
// Author:
// Relja Ljubobratovic, ljubobratovic.relja@gmail.com

#ifndef CALIBPATTERN_HPP_ORZQNP5Z
#define CALIBPATTERN_HPP_ORZQNP5Z

#include <vector>

#include <contour.hpp>
#include <vector.hpp>
#include <matrix.hpp>
#include <draw.hpp>

std::vector<cv::vec2r> detect_pattern(const cv::matrixr &image, unsigned patternRows, unsigned patternCols,
		real_t angThresh = 15., real_t magThresh = 0.15, unsigned nnCount = 10);

std::vector<cv::vec2r> sub_pixel_detect(const std::vector<cv::vec2r> &corners, const cv::matrixr &src,
		const cv::vec2i &win = {10, 10}, real_t eps = 10e-6, unsigned maxIters = 100);

template<typename _Tp>
void draw_chessboard(cv::matrix<_Tp> &image, const std::vector<cv::vec2r> &pattern, const _Tp &color) {

	ASSERT(image && !pattern.empty());

	for (unsigned i = 1; i < pattern.size(); ++i) {
		cv::draw_line(image, pattern[i-1], pattern[i], color);
	}
}

#endif /* end of include guard: CALIBPATTERN_HPP_ORZQNP5Z */

<|endoftext|>


<commit_before>#pragma once

#ifndef VISION_CCTAG_PARAMS_HPP_
#define VISION_CCTAG_PARAMS_HPP_

#include <boost/math/constants/constants.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/nvp.hpp>

#include <cmath>
#include <cstddef>
#include <string>
#include <sys/stat.h>  // needed for stat and mkdir
#include <sys/types.h> // needed for stat and mkdir

#define NO_WEIGHT 0
#define INV_GRAD_WEIGHT 1
#define INV_SQRT_GRAD_WEIGHT 2

namespace cctag
{

static const std::size_t kDefaultDistSearch = 30;
static const std::size_t kDefaultNCrowns  = 3;//4;
static const std::size_t kDefaultNCircles = 6;//8;
static const int kDefaultThrGradientMagInVote = 2500;
static const float kDefaultAngleVoting        = 0.0f;
static const float kDefaultRatioVoting        = 4.f;
static const float kDefaultAverageVoteMin        = 0.f;
static const double kDefaultThrMedianDistanceEllipse = 3.0;
static const std::size_t kDefaultMaximumNbSeeds = 500;
static const std::size_t kDefaultMaximumNbCandidatesLoopTwo = 30;
static const float kDefaultCannyThrLow      =  0.01f ;//0.002
static const float kDefaultCannyThrHigh     =  0.04f ;// 0.04
static const std::size_t kDefaultMinPointsSegmentCandidate =  10;
static const std::size_t kDefaultMinVotesToSelectCandidate =  3;
static const double kDefaultThreshRobustEstimationOfOuterEllipse =  30.0;
static const double kDefaultEllipseGrowingEllipticHullWidth =  2.3;
static const std::size_t kDefaultWindowSizeOnInnerEllipticSegment =  20;
static const std::size_t kDefaultNumberOfMultiresLayers = 4;
static const std::size_t kDefaultNumberOfProcessedMultiresLayers = 4;
static const std::size_t kDefaultNSamplesOuterEllipse = 400;
static const std::size_t kDefaultNumCutsInIdentStep = 30;//100;//15;
static const std::size_t kDefaultNumSamplesOuterEdgePointsRefinement = 20;
static const std::size_t kDefaultCutsSelectionTrials = 500;//10000;
static const std::size_t kDefaultSampleCutLength = 100;
static const std::size_t kDefaultImagedCenterNGridSample = 5;
static const double kDefaultImagedCenterNeighbourSize = 0.20;
static const double kDefaultMinIdentProba = 1e-6;//1e-4
static const bool kDefaultUseLMDif = true;
static const bool kDefaultSearchForAnotherSegment = true;
static const bool kDefaultWriteOutput = false;
static const bool kDefaultDoIdentification = true;
static const uint32_t kDefaultMaxEdges = 20000;
static const bool kDefaultUseCuda = true;

static const std::string kParamCannyThrLow( "kParamCannyThrLow" );
static const std::string kParamCannyThrHigh( "kParamCannyThrHigh" );
static const std::string kParamDistSearch( "kParamDistSearch" );
static const std::string kThrGradientMagInVote("kThrGradientMagInVote");
static const std::string kParamAngleVoting( "kParamAngleVoting" );
static const std::string kParamRatioVoting( "kParamRatioVoting" );
static const std::string kParamAverageVoteMin( "kParamAverageVoteMin" );
static const std::string kParamThrMedianDistanceEllipse( "kParamThrMedianDistanceEllipse" );
static const std::string kParamMaximumNbSeeds( "kParamMaximumNbSeeds" );
static const std::string kParamMaximumNbCandidatesLoopTwo( "kParamMaximumNbCandidatesLoopTwo" );
static const std::string kParamNCrowns( "kParamNCrowns" );
static const std::string kParamMinPointsSegmentCandidate( "kParamMinPointsSegmentCandidate" );
static const std::string kParamMinVotesToSelectCandidate( "kParamMinVotesToSelectCandidate" );
static const std::string kParamThreshRobustEstimationOfOuterEllipse( "kParamThreshRobustEstimationOfOuterEllipse" );
static const std::string kParamEllipseGrowingEllipticHullWidth( "kParamEllipseGrowingEllipticHullWidth" );
static const std::string kParamWindowSizeOnInnerEllipticSegment( "kParamWindowSizeOnInnerEllipticSegment" );
static const std::string kParamNumberOfMultiresLayers( "kParamNumberOfMultiresLayers" );
static const std::string kParamNumberOfProcessedMultiresLayers( "kParamNumberOfProcessedMultiresLayers" );
static const std::string kParamNSamplesOuterEllipse( "kParamNSamplesOuterEllipse" );
static const std::string kParamNumCutsInIdentStep( "kParamNumCutsInIdentStep" );
static const std::string kParamNumSamplesOuterEdgePointsRefinement( "kParamNumSamplesOuterEdgePointsRefinement" );
static const std::string kParamCutsSelectionTrials( "kParamCutsSelectionTrials" );
static const std::string kParamSampleCutLength( "kParamSampleCutLength" );
static const std::string kParamImagedCenterNGridSample( "kParamImagedCenterNGridSample" );
static const std::string kParamImagedCenterNeighbourSize( "kParamImagedCenterNeighbourSize" );
static const std::string kParamMinIdentProba( "kParamMinIdentProba" );
static const std::string kParamUseLMDif( "kParamUseLMDif" );
static const std::string kParamSearchForAnotherSegment( "kParamSearchForAnotherSegment" );
static const std::string kParamWriteOutput( "kParamWriteOutput" );
static const std::string kParamDoIdentification( "kParamDoIdentification" );
static const std::string kParamMaxEdges( "kParamMaxEdges" );
static const std::string kUseCuda( "kUseCuda" );

static const std::size_t kWeight = INV_GRAD_WEIGHT; // todo@L

struct Parameters
{
  friend class boost::serialization::access;

  Parameters(const std::size_t nCrowns);

  float _cannyThrLow; // canny low threshold
  float _cannyThrHigh; // canny high threshold
  std::size_t _distSearch; // maximum distance (in pixels) of research from one edge points
  // to another one. maximum length of a arc segment composing the polygonal line.
  int _thrGradientMagInVote; // during the voting procedure, the gradient direction
  // is followed as long as the gradient magnitude is
  // greater than this threshold
  float _angleVoting; // maximum angle between of gradient directions of two consecutive
  // edge points.
  float _ratioVoting; // maximum distance ratio between of gradient directions of two consecutive
  // edge points.
  float _averageVoteMin;
  double _thrMedianDistanceEllipse;
  std::size_t _maximumNbSeeds; // number of seeds to process as potential candidates
  std::size_t _maximumNbCandidatesLoopTwo;
  std::size_t _nCrowns; // number of crowns
  std::size_t _nCircles; // number of circles
  std::size_t _minPointsSegmentCandidate; // minimal number of points on the outer ellipse to select an inner segment candidate
  std::size_t _minVotesToSelectCandidate; // minimum number of received votes to select an edge
  // point as a new seed.
  double _threshRobustEstimationOfOuterEllipse; // LMeDs threshold on robust estimation of the outer ellipse
  double _ellipseGrowingEllipticHullWidth; // width of elliptic hull in ellipse growing
  std::size_t _windowSizeOnInnerEllipticSegment; // window size on the inner elliptic segment
  std::size_t _numberOfMultiresLayers; // number of multi-resolution layers
  std::size_t _numberOfProcessedMultiresLayers; // number of processed layers in multi-resolution
  std::size_t _nSamplesOuterEllipse; // Number of points considered in the preliminary sampling in identification
  std::size_t _numCutsInIdentStep; // number of cuts in the identification step
  std::size_t _numSamplesOuterEdgePointsRefinement; // number of sample for the outer edge points refinement in identification
  std::size_t _cutsSelectionTrials; // number of trials in cuts selection
  std::size_t _sampleCutLength; // sample cut length
  std::size_t  _imagedCenterNGridSample; // number of point sample along the square grid side (e.g. 5 for a grid of 5x5=25 points)
  double _imagedCenterNeighbourSize; // grid width relatively to the length of longest semi-axis of the outer ellipse
  double _minIdentProba; // minimal probability of delivered by the identification algorithm
  // to consider a candidate as a CCTag
  bool _useLMDif;
  bool _searchForAnotherSegment; // is CCTag can be made of many flow components (2).
  // This implies an assembling step which may be time
  // time consuming.
  bool _writeOutput;
  bool _doIdentification; // perform the identification step
  uint32_t _maxEdges; // max number of edge point, determines memory allocation
  bool        _useCuda; // if compiled WITH_CUDA, allow CLI selection, ignore if not
  std::string _debugDir; // prefix for debug output !!!! ONLY ON COMMAND LINE

  template<class Archive>
  void serialize(Archive & ar, const unsigned int version)
  {
    ar & BOOST_SERIALIZATION_NVP( _cannyThrLow );
    ar & BOOST_SERIALIZATION_NVP( _cannyThrHigh );
    ar & BOOST_SERIALIZATION_NVP( _distSearch );
    ar & BOOST_SERIALIZATION_NVP( _thrGradientMagInVote );
    ar & BOOST_SERIALIZATION_NVP( _angleVoting );
    ar & BOOST_SERIALIZATION_NVP( _ratioVoting );
    ar & BOOST_SERIALIZATION_NVP( _averageVoteMin);
    ar & BOOST_SERIALIZATION_NVP( _thrMedianDistanceEllipse);
    ar & BOOST_SERIALIZATION_NVP( _maximumNbSeeds);
    ar & BOOST_SERIALIZATION_NVP( _maximumNbCandidatesLoopTwo);
    ar & BOOST_SERIALIZATION_NVP( _nCrowns );
    ar & BOOST_SERIALIZATION_NVP( _minPointsSegmentCandidate );
    ar & BOOST_SERIALIZATION_NVP( _minVotesToSelectCandidate );
    ar & BOOST_SERIALIZATION_NVP( _threshRobustEstimationOfOuterEllipse );
    ar & BOOST_SERIALIZATION_NVP( _ellipseGrowingEllipticHullWidth );
    ar & BOOST_SERIALIZATION_NVP( _windowSizeOnInnerEllipticSegment );
    ar & BOOST_SERIALIZATION_NVP( _numberOfMultiresLayers );
    ar & BOOST_SERIALIZATION_NVP( _numberOfProcessedMultiresLayers );
    ar & BOOST_SERIALIZATION_NVP( _nSamplesOuterEllipse );
    ar & BOOST_SERIALIZATION_NVP( _numCutsInIdentStep );
    ar & BOOST_SERIALIZATION_NVP( _numSamplesOuterEdgePointsRefinement );
    ar & BOOST_SERIALIZATION_NVP( _cutsSelectionTrials );
    ar & BOOST_SERIALIZATION_NVP( _sampleCutLength );
    ar & BOOST_SERIALIZATION_NVP( _imagedCenterNGridSample );
    ar & BOOST_SERIALIZATION_NVP( _imagedCenterNeighbourSize );
    ar & BOOST_SERIALIZATION_NVP( _minIdentProba );
    ar & BOOST_SERIALIZATION_NVP( _useLMDif );
    ar & BOOST_SERIALIZATION_NVP( _searchForAnotherSegment );
    ar & BOOST_SERIALIZATION_NVP( _writeOutput );
    ar & BOOST_SERIALIZATION_NVP( _doIdentification );
    ar & BOOST_SERIALIZATION_NVP( _maxEdges );
    ar & BOOST_SERIALIZATION_NVP( _useCuda );
    _nCircles = 2*_nCrowns;
  }

  void setDebugDir( const std::string& debugDir );

  void setUseCuda( bool val );
};

} // namespace cctag

#endif

<commit_msg>[param] kDefaultNSamplesOuterEllipse 400 -> 300, kDefaultNumCutsInIdentStep 30 -> 15<commit_after>#pragma once

#ifndef VISION_CCTAG_PARAMS_HPP_
#define VISION_CCTAG_PARAMS_HPP_

#include <boost/math/constants/constants.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/nvp.hpp>

#include <cmath>
#include <cstddef>
#include <string>
#include <sys/stat.h>  // needed for stat and mkdir
#include <sys/types.h> // needed for stat and mkdir

#define NO_WEIGHT 0
#define INV_GRAD_WEIGHT 1
#define INV_SQRT_GRAD_WEIGHT 2

namespace cctag
{

static const std::size_t kDefaultDistSearch = 30;
static const std::size_t kDefaultNCrowns  = 3;//4;
static const std::size_t kDefaultNCircles = 6;//8;
static const int kDefaultThrGradientMagInVote = 2500;
static const float kDefaultAngleVoting        = 0.0f;
static const float kDefaultRatioVoting        = 4.f;
static const float kDefaultAverageVoteMin        = 0.f;
static const double kDefaultThrMedianDistanceEllipse = 3.0;
static const std::size_t kDefaultMaximumNbSeeds = 500;
static const std::size_t kDefaultMaximumNbCandidatesLoopTwo = 30;
static const float kDefaultCannyThrLow      =  0.01f ;//0.002
static const float kDefaultCannyThrHigh     =  0.04f ;// 0.04
static const std::size_t kDefaultMinPointsSegmentCandidate =  10;
static const std::size_t kDefaultMinVotesToSelectCandidate =  3;
static const double kDefaultThreshRobustEstimationOfOuterEllipse =  30.0;
static const double kDefaultEllipseGrowingEllipticHullWidth =  2.3;
static const std::size_t kDefaultWindowSizeOnInnerEllipticSegment =  20;
static const std::size_t kDefaultNumberOfMultiresLayers = 4;
static const std::size_t kDefaultNumberOfProcessedMultiresLayers = 4;
static const std::size_t kDefaultNSamplesOuterEllipse = 300;
static const std::size_t kDefaultNumCutsInIdentStep = 15;//30;//100;//15;
static const std::size_t kDefaultNumSamplesOuterEdgePointsRefinement = 20;
static const std::size_t kDefaultCutsSelectionTrials = 500;//10000;
static const std::size_t kDefaultSampleCutLength = 100;
static const std::size_t kDefaultImagedCenterNGridSample = 5;
static const double kDefaultImagedCenterNeighbourSize = 0.20;
static const double kDefaultMinIdentProba = 1e-6;//1e-4
static const bool kDefaultUseLMDif = true;
static const bool kDefaultSearchForAnotherSegment = true;
static const bool kDefaultWriteOutput = false;
static const bool kDefaultDoIdentification = true;
static const uint32_t kDefaultMaxEdges = 20000;
static const bool kDefaultUseCuda = true;

static const std::string kParamCannyThrLow( "kParamCannyThrLow" );
static const std::string kParamCannyThrHigh( "kParamCannyThrHigh" );
static const std::string kParamDistSearch( "kParamDistSearch" );
static const std::string kThrGradientMagInVote("kThrGradientMagInVote");
static const std::string kParamAngleVoting( "kParamAngleVoting" );
static const std::string kParamRatioVoting( "kParamRatioVoting" );
static const std::string kParamAverageVoteMin( "kParamAverageVoteMin" );
static const std::string kParamThrMedianDistanceEllipse( "kParamThrMedianDistanceEllipse" );
static const std::string kParamMaximumNbSeeds( "kParamMaximumNbSeeds" );
static const std::string kParamMaximumNbCandidatesLoopTwo( "kParamMaximumNbCandidatesLoopTwo" );
static const std::string kParamNCrowns( "kParamNCrowns" );
static const std::string kParamMinPointsSegmentCandidate( "kParamMinPointsSegmentCandidate" );
static const std::string kParamMinVotesToSelectCandidate( "kParamMinVotesToSelectCandidate" );
static const std::string kParamThreshRobustEstimationOfOuterEllipse( "kParamThreshRobustEstimationOfOuterEllipse" );
static const std::string kParamEllipseGrowingEllipticHullWidth( "kParamEllipseGrowingEllipticHullWidth" );
static const std::string kParamWindowSizeOnInnerEllipticSegment( "kParamWindowSizeOnInnerEllipticSegment" );
static const std::string kParamNumberOfMultiresLayers( "kParamNumberOfMultiresLayers" );
static const std::string kParamNumberOfProcessedMultiresLayers( "kParamNumberOfProcessedMultiresLayers" );
static const std::string kParamNSamplesOuterEllipse( "kParamNSamplesOuterEllipse" );
static const std::string kParamNumCutsInIdentStep( "kParamNumCutsInIdentStep" );
static const std::string kParamNumSamplesOuterEdgePointsRefinement( "kParamNumSamplesOuterEdgePointsRefinement" );
static const std::string kParamCutsSelectionTrials( "kParamCutsSelectionTrials" );
static const std::string kParamSampleCutLength( "kParamSampleCutLength" );
static const std::string kParamImagedCenterNGridSample( "kParamImagedCenterNGridSample" );
static const std::string kParamImagedCenterNeighbourSize( "kParamImagedCenterNeighbourSize" );
static const std::string kParamMinIdentProba( "kParamMinIdentProba" );
static const std::string kParamUseLMDif( "kParamUseLMDif" );
static const std::string kParamSearchForAnotherSegment( "kParamSearchForAnotherSegment" );
static const std::string kParamWriteOutput( "kParamWriteOutput" );
static const std::string kParamDoIdentification( "kParamDoIdentification" );
static const std::string kParamMaxEdges( "kParamMaxEdges" );
static const std::string kUseCuda( "kUseCuda" );

static const std::size_t kWeight = INV_GRAD_WEIGHT; // todo@L

struct Parameters
{
  friend class boost::serialization::access;

  Parameters(const std::size_t nCrowns);

  float _cannyThrLow; // canny low threshold
  float _cannyThrHigh; // canny high threshold
  std::size_t _distSearch; // maximum distance (in pixels) of research from one edge points
  // to another one. maximum length of a arc segment composing the polygonal line.
  int _thrGradientMagInVote; // during the voting procedure, the gradient direction
  // is followed as long as the gradient magnitude is
  // greater than this threshold
  float _angleVoting; // maximum angle between of gradient directions of two consecutive
  // edge points.
  float _ratioVoting; // maximum distance ratio between of gradient directions of two consecutive
  // edge points.
  float _averageVoteMin;
  double _thrMedianDistanceEllipse;
  std::size_t _maximumNbSeeds; // number of seeds to process as potential candidates
  std::size_t _maximumNbCandidatesLoopTwo;
  std::size_t _nCrowns; // number of crowns
  std::size_t _nCircles; // number of circles
  std::size_t _minPointsSegmentCandidate; // minimal number of points on the outer ellipse to select an inner segment candidate
  std::size_t _minVotesToSelectCandidate; // minimum number of received votes to select an edge
  // point as a new seed.
  double _threshRobustEstimationOfOuterEllipse; // LMeDs threshold on robust estimation of the outer ellipse
  double _ellipseGrowingEllipticHullWidth; // width of elliptic hull in ellipse growing
  std::size_t _windowSizeOnInnerEllipticSegment; // window size on the inner elliptic segment
  std::size_t _numberOfMultiresLayers; // number of multi-resolution layers
  std::size_t _numberOfProcessedMultiresLayers; // number of processed layers in multi-resolution
  std::size_t _nSamplesOuterEllipse; // Number of points considered in the preliminary sampling in identification
  std::size_t _numCutsInIdentStep; // number of cuts in the identification step
  std::size_t _numSamplesOuterEdgePointsRefinement; // number of sample for the outer edge points refinement in identification
  std::size_t _cutsSelectionTrials; // number of trials in cuts selection
  std::size_t _sampleCutLength; // sample cut length
  std::size_t  _imagedCenterNGridSample; // number of point sample along the square grid side (e.g. 5 for a grid of 5x5=25 points)
  double _imagedCenterNeighbourSize; // grid width relatively to the length of longest semi-axis of the outer ellipse
  double _minIdentProba; // minimal probability of delivered by the identification algorithm
  // to consider a candidate as a CCTag
  bool _useLMDif;
  bool _searchForAnotherSegment; // is CCTag can be made of many flow components (2).
  // This implies an assembling step which may be time
  // time consuming.
  bool _writeOutput;
  bool _doIdentification; // perform the identification step
  uint32_t _maxEdges; // max number of edge point, determines memory allocation
  bool        _useCuda; // if compiled WITH_CUDA, allow CLI selection, ignore if not
  std::string _debugDir; // prefix for debug output !!!! ONLY ON COMMAND LINE

  template<class Archive>
  void serialize(Archive & ar, const unsigned int version)
  {
    ar & BOOST_SERIALIZATION_NVP( _cannyThrLow );
    ar & BOOST_SERIALIZATION_NVP( _cannyThrHigh );
    ar & BOOST_SERIALIZATION_NVP( _distSearch );
    ar & BOOST_SERIALIZATION_NVP( _thrGradientMagInVote );
    ar & BOOST_SERIALIZATION_NVP( _angleVoting );
    ar & BOOST_SERIALIZATION_NVP( _ratioVoting );
    ar & BOOST_SERIALIZATION_NVP( _averageVoteMin);
    ar & BOOST_SERIALIZATION_NVP( _thrMedianDistanceEllipse);
    ar & BOOST_SERIALIZATION_NVP( _maximumNbSeeds);
    ar & BOOST_SERIALIZATION_NVP( _maximumNbCandidatesLoopTwo);
    ar & BOOST_SERIALIZATION_NVP( _nCrowns );
    ar & BOOST_SERIALIZATION_NVP( _minPointsSegmentCandidate );
    ar & BOOST_SERIALIZATION_NVP( _minVotesToSelectCandidate );
    ar & BOOST_SERIALIZATION_NVP( _threshRobustEstimationOfOuterEllipse );
    ar & BOOST_SERIALIZATION_NVP( _ellipseGrowingEllipticHullWidth );
    ar & BOOST_SERIALIZATION_NVP( _windowSizeOnInnerEllipticSegment );
    ar & BOOST_SERIALIZATION_NVP( _numberOfMultiresLayers );
    ar & BOOST_SERIALIZATION_NVP( _numberOfProcessedMultiresLayers );
    ar & BOOST_SERIALIZATION_NVP( _nSamplesOuterEllipse );
    ar & BOOST_SERIALIZATION_NVP( _numCutsInIdentStep );
    ar & BOOST_SERIALIZATION_NVP( _numSamplesOuterEdgePointsRefinement );
    ar & BOOST_SERIALIZATION_NVP( _cutsSelectionTrials );
    ar & BOOST_SERIALIZATION_NVP( _sampleCutLength );
    ar & BOOST_SERIALIZATION_NVP( _imagedCenterNGridSample );
    ar & BOOST_SERIALIZATION_NVP( _imagedCenterNeighbourSize );
    ar & BOOST_SERIALIZATION_NVP( _minIdentProba );
    ar & BOOST_SERIALIZATION_NVP( _useLMDif );
    ar & BOOST_SERIALIZATION_NVP( _searchForAnotherSegment );
    ar & BOOST_SERIALIZATION_NVP( _writeOutput );
    ar & BOOST_SERIALIZATION_NVP( _doIdentification );
    ar & BOOST_SERIALIZATION_NVP( _maxEdges );
    ar & BOOST_SERIALIZATION_NVP( _useCuda );
    _nCircles = 2*_nCrowns;
  }

  void setDebugDir( const std::string& debugDir );

  void setUseCuda( bool val );
};

} // namespace cctag

#endif

<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. All rights reserved
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// +build ignore

#include "stats.h"

#include <mutex>
#include <vector>

#include "flags.h"
#include "log.h"
#include "stringprintf.h"
#include "thread_local.h"
#include "timeutil.h"

namespace {

mutex g_mu;
vector<Stats*>* g_stats;
DEFINE_THREAD_LOCAL(double, g_start_time);

}  // namespace

Stats::Stats(const char* name)
    : name_(name), elapsed_(0), cnt_(0) {
  unique_lock<mutex> lock(g_mu);
  if (g_stats == NULL)
    g_stats = new vector<Stats*>;
  g_stats->push_back(this);
}

string Stats::String() const {
  unique_lock<mutex> lock(mu_);
  return StringPrintf("%s: %f / %d", name_, elapsed_, cnt_);
}

void Stats::Start() {
  CHECK(!g_start_time.Ref());
  g_start_time.Ref() = GetTime();
  unique_lock<mutex> lock(mu_);
  cnt_++;
}

double Stats::End() {
  CHECK(g_start_time.Ref());
  double e = GetTime() - g_start_time.Ref();
  g_start_time.Ref() = 0;
  unique_lock<mutex> lock(mu_);
  elapsed_ += e;
  return e;
}

ScopedStatsRecorder::ScopedStatsRecorder(Stats* st, const char* msg)
    : st_(st), msg_(msg) {
  if (!g_flags.enable_stat_logs)
    return;
  st_->Start();
}

ScopedStatsRecorder::~ScopedStatsRecorder() {
  if (!g_flags.enable_stat_logs)
    return;
  double e = st_->End();
  if (msg_ && e > 3.0) {
    LOG_STAT("slow %s (%f): %s", st_->name_, e, msg_);
  }
}

void ReportAllStats() {
  if (!g_stats)
    return;
  for (Stats* st : *g_stats) {
    LOG_STAT("%s", st->String().c_str());
  }
  delete g_stats;
}
<commit_msg>[C++] Use thraed_local keyword on linux again<commit_after>// Copyright 2015 Google Inc. All rights reserved
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// +build ignore

#include "stats.h"

#include <mutex>
#include <vector>

#include "flags.h"
#include "log.h"
#include "stringprintf.h"
#include "thread_local.h"
#include "timeutil.h"

namespace {

mutex g_mu;
vector<Stats*>* g_stats;
#ifdef __linux__
thread_local double g_start_time;
#define REF(x) x
#else
DEFINE_THREAD_LOCAL(double, g_start_time);
#define REF(x) x.Ref()
#endif

}  // namespace

Stats::Stats(const char* name)
    : name_(name), elapsed_(0), cnt_(0) {
  unique_lock<mutex> lock(g_mu);
  if (g_stats == NULL)
    g_stats = new vector<Stats*>;
  g_stats->push_back(this);
}

string Stats::String() const {
  unique_lock<mutex> lock(mu_);
  return StringPrintf("%s: %f / %d", name_, elapsed_, cnt_);
}

void Stats::Start() {
  CHECK(!REF(g_start_time));
  REF(g_start_time) = GetTime();
  unique_lock<mutex> lock(mu_);
  cnt_++;
}

double Stats::End() {
  CHECK(REF(g_start_time));
  double e = GetTime() - REF(g_start_time);
  REF(g_start_time) = 0;
  unique_lock<mutex> lock(mu_);
  elapsed_ += e;
  return e;
}

ScopedStatsRecorder::ScopedStatsRecorder(Stats* st, const char* msg)
    : st_(st), msg_(msg) {
  if (!g_flags.enable_stat_logs)
    return;
  st_->Start();
}

ScopedStatsRecorder::~ScopedStatsRecorder() {
  if (!g_flags.enable_stat_logs)
    return;
  double e = st_->End();
  if (msg_ && e > 3.0) {
    LOG_STAT("slow %s (%f): %s", st_->name_, e, msg_);
  }
}

void ReportAllStats() {
  if (!g_stats)
    return;
  for (Stats* st : *g_stats) {
    LOG_STAT("%s", st->String().c_str());
  }
  delete g_stats;
}
<|endoftext|>


<commit_before>#include "scsi/constants.h"
#include "scsi/moment2.h"
#include "scsi/moment2_sup.h"
#include "scsi/chg_stripper.h"

void GetCenofChg(const Config &conf, const Moment2State &ST,
                 Moment2State::vector_t &CenofChg, Moment2State::vector_t &BeamRMS)
{
    size_t i, j;
    const size_t n = ST.real.size(); // # of states

    CenofChg = boost::numeric::ublas::zero_vector<double>(PS_Dim);
    BeamRMS  = boost::numeric::ublas::zero_vector<double>(PS_Dim);
    Moment2State::vector_t BeamVar(boost::numeric::ublas::zero_vector<double>(PS_Dim));

    double Ntot = 0e0;
    for (i = 0; i < n; i++) {
        CenofChg += ST.moment0[i]*ST.real[i].IonQ;
        Ntot += ST.real[i].IonQ;
    }

    CenofChg /= Ntot;

    for (i = 0; i < n; i++) {
        for (j = 0; j < Moment2State::maxsize; j++) {
            BeamVar[j]  +=
                    ST.real[i].IonQ*(ST.moment1[i](j, j)
                    +(ST.moment0[i][j]-CenofChg[j])*(ST.moment0[i][j]-CenofChg[j]));
        }
    }

    for (j = 0; j < PS_Dim; j++)
        BeamRMS[j] = sqrt(BeamVar[j]/Ntot);
}

static
double Gaussian(double in, const double Q_ave, const double d)
{
    // Gaussian distribution.
    return 1e0/sqrt(2e0*M_PI)/d*exp(-0.5e0*sqr(in-Q_ave)/sqr(d));
}

static
void StripperCharge(const double beta, double &Q_ave, double &d)
{
    // Baron's formula for carbon foil.
    double Q_ave1, Y;

    Q_ave1 = Stripper_IonProton*(1e0-exp(-83.275*(beta/pow(Stripper_IonProton, 0.447))));
    Q_ave  = Q_ave1*(1e0-exp(-12.905+0.2124*Stripper_IonProton-0.00122*sqr(Stripper_IonProton)));
    Y      = Q_ave1/Stripper_IonProton;
    d      = sqrt(Q_ave1*(0.07535+0.19*Y-0.2654*sqr(Y)));
}

static
void ChargeStripper(const double beta, const std::vector<double> ChgState, double chargeAmount_Baron[])
{
    unsigned    k;
    double Q_ave, d;

    StripperCharge(beta, Q_ave, d);
    for (k = 0; k < ChgState.size(); k++)
        chargeAmount_Baron[k] = Gaussian(ChgState[k]*Stripper_IonMass, Q_ave, d);
}

static
void Stripper_Propagate_ref(const Config &conf, Particle &ref, const std::vector<double> ChgState)
{
    const int n = ChgState.size();

    double chargeAmount_Baron[n];

    // Change reference particle charge state.
    ref.IonZ = Stripper_IonZ;

    ChargeStripper(ref.beta, ChgState, chargeAmount_Baron);

    // Evaluate change in reference particle energy due to stripper model energy straggling.
    ref.IonEk      = (ref.IonEk-Stripper_Para[2])*Stripper_E0Para[1] + Stripper_E0Para[0];

    ref.IonW       = ref.IonEk + ref.IonEs;
    ref.gamma      = ref.IonW/ref.IonEs;
    ref.beta       = sqrt(1e0-1e0/sqr(ref.gamma));
    ref.SampleIonK = 2e0*M_PI/(ref.beta*SampleLambda);

    // chargeAmount = fribstripper.chargeAmount_Baron;
}

static
void PrtMat1(const state_t::matrix_t &M)
{
    for (size_t j = 0; j < M.size1(); j++) {
        for (size_t k = 0; k < M.size2(); k++)
            std::cout << std::scientific << std::setprecision(10)
                      << std::setw(18) << M(j, k);
        std::cout << "\n";
    }
}

static
std::vector<double> GetStrChgState(const Config &conf)
{
    return conf.get<std::vector<double> >("Stripper_IonChargeStates");
}

void Stripper_GetMat(const Config &conf,
                     Moment2State &ST, std::vector<double> ChgState)
{
    unsigned               k, n;
    double                 tmptotCharge, Fy_abs_recomb, Ek_recomb, stdEkFoilVariation, ZpAfStr, growthRate;
    double                 stdXYp, XpAfStr, growthRateXp, YpAfStr, growthRateYp, s;
    std::vector<double>    NChg;
    Particle               ref;
    state_t                *StatePtr = &ST;
    Moment2State::vector_t CenofChg, BeamRMS;
    Moment2State::matrix_t tmpmat;

    // Evaluate beam parameter recombination.

    GetCenofChg(conf, ST, CenofChg, BeamRMS);
    assert(CenofChg==ST.moment0_env);

    n = conf.get<std::vector<double> >("IonChargeStates").size();
    NChg.resize(n);
    NChg = conf.get<std::vector<double> >("NCharge");

    tmptotCharge  = 0e0;
    Fy_abs_recomb = 0e0;
    Ek_recomb     = 0e0;
    tmpmat        = boost::numeric::ublas::zero_matrix<double>(PS_Dim);
    for (k = 0; k < ST.size(); k++) {

        tmptotCharge  += NChg[k];
        Fy_abs_recomb += NChg[k]*StatePtr->real[k].phis;
        Ek_recomb     += NChg[k]*StatePtr->real[k].IonEk;
        tmpmat        +=
                NChg[k]*(StatePtr->moment1[k]+outer_prod(StatePtr->moment0[k]-CenofChg, StatePtr->moment0[k]-CenofChg));
    }

    Fy_abs_recomb /= tmptotCharge;
    Ek_recomb     /= tmptotCharge;

    // Stripper model energy straggling.
    Ek_recomb      = (Ek_recomb-Stripper_Para[2])*Stripper_E0Para[1] + Stripper_E0Para[0];
    tmpmat        /= tmptotCharge;

    // Estimate Zp stripper caused envelope increase.
    stdEkFoilVariation = sqrt(1e0/3e0)*Stripper_Para[1]/100e0*Stripper_Para[0]*Stripper_E0Para[2];
    ZpAfStr            = tmpmat(5, 5) + sqr(Stripper_E1Para) + sqr(stdEkFoilVariation);
    growthRate         = sqrt(ZpAfStr/tmpmat(5, 5));

    for (k = 0; k < 6; k++) {
        tmpmat(k, 5) = tmpmat(k, 5)*growthRate;
        // This trick allows two times growthRate for <Zp, Zp>.
        tmpmat(5, k) = tmpmat(5, k)*growthRate;
    }

    // Estimate Xp, Yp stripper caused envelope increase.
    stdXYp       = sqrt(Stripper_upara/sqr(Stripper_lambda))*1e-3;// mrad to rad
    XpAfStr      = tmpmat(1, 1) + sqr(stdXYp);
    growthRateXp = sqrt(XpAfStr/tmpmat(1, 1));
    YpAfStr      = tmpmat(3, 3) + sqr(stdXYp);
    growthRateYp = sqrt(YpAfStr/tmpmat(3, 3));

    for (k = 0; k < 6; k++) {
        tmpmat(k, 1) = tmpmat(k, 1)*growthRateXp;
        // This trick allows two times growthRate for <Zp, Zp>.
        tmpmat(1, k) = tmpmat(1, k)*growthRateXp;
        tmpmat(k, 3) = tmpmat(k, 3)*growthRateYp;
        tmpmat(3, k) = tmpmat(3, k)*growthRateYp;
    }

    // Get new charge states.
    ChgState = GetStrChgState(conf);
    NChg = conf.get<std::vector<double> >("Stripper_NCharge");
    n = ChgState.size();
    assert(NChg.size()==n);

    // Propagate reference particle.
    ref = ST.ref;
    Stripper_Propagate_ref(conf, ref, ChgState);

    s = StatePtr->pos;

    ST.real.resize(n);
    ST.moment0.resize(n);
    ST.moment1.resize(n);

    for (k = 0; k < n; k++) {

        // Length is zero.
        StatePtr->pos        = s;

        StatePtr->ref        = ref;

        StatePtr->real[k].IonZ  = ChgState[k];
        StatePtr->real[k].IonQ  = NChg[k];
        StatePtr->real[k].IonEs = ref.IonEs;
        StatePtr->real[k].IonEk = Ek_recomb;
        StatePtr->real[k].IonW  = StatePtr->real[k].IonEk + StatePtr->ref.IonEs;
        StatePtr->real[k].gamma = StatePtr->real[k].IonW/StatePtr->ref.IonEs;
        StatePtr->real[k].beta  = sqrt(1e0-1e0/sqr(StatePtr->real[k].gamma));
        StatePtr->real[k].phis  = Fy_abs_recomb;
        StatePtr->real[k].IonEk = Ek_recomb;
        StatePtr->moment0[k]    = CenofChg;
        StatePtr->moment1[k]    = tmpmat;
    }

    assert(CenofChg==StatePtr->moment0_env);
}
<commit_msg>noise<commit_after>#include "scsi/constants.h"
#include "scsi/moment2.h"
#include "scsi/moment2_sup.h"
#include "scsi/chg_stripper.h"

void GetCenofChg(const Config &conf, const Moment2State &ST,
                 Moment2State::vector_t &CenofChg, Moment2State::vector_t &BeamRMS)
{
    size_t i, j;
    const size_t n = ST.real.size(); // # of states

    CenofChg = boost::numeric::ublas::zero_vector<double>(PS_Dim);
    BeamRMS  = boost::numeric::ublas::zero_vector<double>(PS_Dim);
    Moment2State::vector_t BeamVar(boost::numeric::ublas::zero_vector<double>(PS_Dim));

    double Ntot = 0e0;
    for (i = 0; i < n; i++) {
        CenofChg += ST.moment0[i]*ST.real[i].IonQ;
        Ntot += ST.real[i].IonQ;
    }

    CenofChg /= Ntot;

    for (i = 0; i < n; i++) {
        for (j = 0; j < Moment2State::maxsize; j++) {
            BeamVar[j]  +=
                    ST.real[i].IonQ*(ST.moment1[i](j, j)
                    +(ST.moment0[i][j]-CenofChg[j])*(ST.moment0[i][j]-CenofChg[j]));
        }
    }

    for (j = 0; j < PS_Dim; j++)
        BeamRMS[j] = sqrt(BeamVar[j]/Ntot);
}

static
double Gaussian(double in, const double Q_ave, const double d)
{
    // Gaussian distribution.
    return 1e0/sqrt(2e0*M_PI)/d*exp(-0.5e0*sqr(in-Q_ave)/sqr(d));
}

static
void StripperCharge(const double beta, double &Q_ave, double &d)
{
    // Baron's formula for carbon foil.
    double Q_ave1, Y;

    Q_ave1 = Stripper_IonProton*(1e0-exp(-83.275*(beta/pow(Stripper_IonProton, 0.447))));
    Q_ave  = Q_ave1*(1e0-exp(-12.905+0.2124*Stripper_IonProton-0.00122*sqr(Stripper_IonProton)));
    Y      = Q_ave1/Stripper_IonProton;
    d      = sqrt(Q_ave1*(0.07535+0.19*Y-0.2654*sqr(Y)));
}

static
void ChargeStripper(const double beta, const std::vector<double> ChgState, double chargeAmount_Baron[])
{
    unsigned    k;
    double Q_ave, d;

    StripperCharge(beta, Q_ave, d);
    for (k = 0; k < ChgState.size(); k++)
        chargeAmount_Baron[k] = Gaussian(ChgState[k]*Stripper_IonMass, Q_ave, d);
}

static
void Stripper_Propagate_ref(const Config &conf, Particle &ref, const std::vector<double> ChgState)
{
    const int n = ChgState.size();

    double chargeAmount_Baron[n];

    // Change reference particle charge state.
    ref.IonZ = Stripper_IonZ;

    ChargeStripper(ref.beta, ChgState, chargeAmount_Baron);

    // Evaluate change in reference particle energy due to stripper model energy straggling.
    ref.IonEk      = (ref.IonEk-Stripper_Para[2])*Stripper_E0Para[1] + Stripper_E0Para[0];

    ref.IonW       = ref.IonEk + ref.IonEs;
    ref.gamma      = ref.IonW/ref.IonEs;
    ref.beta       = sqrt(1e0-1e0/sqr(ref.gamma));
    ref.SampleIonK = 2e0*M_PI/(ref.beta*SampleLambda);

    // chargeAmount = fribstripper.chargeAmount_Baron;
}

static
void PrtMat1(const state_t::matrix_t &M)
{
    for (size_t j = 0; j < M.size1(); j++) {
        for (size_t k = 0; k < M.size2(); k++)
            std::cout << std::scientific << std::setprecision(10)
                      << std::setw(18) << M(j, k);
        std::cout << "\n";
    }
}

static
std::vector<double> GetStrChgState(const Config &conf)
{
    return conf.get<std::vector<double> >("Stripper_IonChargeStates");
}

void Stripper_GetMat(const Config &conf,
                     Moment2State &ST, std::vector<double> ChgState)
{
    unsigned               k, n;
    double                 tmptotCharge, Fy_abs_recomb, Ek_recomb, stdEkFoilVariation, ZpAfStr, growthRate;
    double                 stdXYp, XpAfStr, growthRateXp, YpAfStr, growthRateYp, s;
    std::vector<double>    NChg;
    Particle               ref;
    state_t                *StatePtr = &ST;
    Moment2State::vector_t CenofChg, BeamRMS;
    Moment2State::matrix_t tmpmat;

    // Evaluate beam parameter recombination.

    GetCenofChg(conf, ST, CenofChg, BeamRMS);
    assert(CenofChg==ST.moment0_env);

    std::cout<<"In "<<__FUNCTION__<<"\n";

    n = conf.get<std::vector<double> >("IonChargeStates").size();
    NChg.resize(n);
    NChg = conf.get<std::vector<double> >("NCharge");

    tmptotCharge  = 0e0;
    Fy_abs_recomb = 0e0;
    Ek_recomb     = 0e0;
    tmpmat        = boost::numeric::ublas::zero_matrix<double>(PS_Dim);
    for (k = 0; k < ST.size(); k++) {

        tmptotCharge  += NChg[k];
        Fy_abs_recomb += NChg[k]*StatePtr->real[k].phis;
        Ek_recomb     += NChg[k]*StatePtr->real[k].IonEk;
        tmpmat        +=
                NChg[k]*(StatePtr->moment1[k]+outer_prod(StatePtr->moment0[k]-CenofChg, StatePtr->moment0[k]-CenofChg));
    }

    Fy_abs_recomb /= tmptotCharge;
    Ek_recomb     /= tmptotCharge;

    // Stripper model energy straggling.
    Ek_recomb      = (Ek_recomb-Stripper_Para[2])*Stripper_E0Para[1] + Stripper_E0Para[0];
    tmpmat        /= tmptotCharge;

    // Estimate Zp stripper caused envelope increase.
    stdEkFoilVariation = sqrt(1e0/3e0)*Stripper_Para[1]/100e0*Stripper_Para[0]*Stripper_E0Para[2];
    ZpAfStr            = tmpmat(5, 5) + sqr(Stripper_E1Para) + sqr(stdEkFoilVariation);
    growthRate         = sqrt(ZpAfStr/tmpmat(5, 5));

    for (k = 0; k < 6; k++) {
        tmpmat(k, 5) = tmpmat(k, 5)*growthRate;
        // This trick allows two times growthRate for <Zp, Zp>.
        tmpmat(5, k) = tmpmat(5, k)*growthRate;
    }

    // Estimate Xp, Yp stripper caused envelope increase.
    stdXYp       = sqrt(Stripper_upara/sqr(Stripper_lambda))*1e-3;// mrad to rad
    XpAfStr      = tmpmat(1, 1) + sqr(stdXYp);
    growthRateXp = sqrt(XpAfStr/tmpmat(1, 1));
    YpAfStr      = tmpmat(3, 3) + sqr(stdXYp);
    growthRateYp = sqrt(YpAfStr/tmpmat(3, 3));

    for (k = 0; k < 6; k++) {
        tmpmat(k, 1) = tmpmat(k, 1)*growthRateXp;
        // This trick allows two times growthRate for <Zp, Zp>.
        tmpmat(1, k) = tmpmat(1, k)*growthRateXp;
        tmpmat(k, 3) = tmpmat(k, 3)*growthRateYp;
        tmpmat(3, k) = tmpmat(3, k)*growthRateYp;
    }

    // Get new charge states.
    ChgState = GetStrChgState(conf);
    NChg = conf.get<std::vector<double> >("Stripper_NCharge");
    n = ChgState.size();
    assert(NChg.size()==n);

    // Propagate reference particle.
    ref = ST.ref;
    Stripper_Propagate_ref(conf, ref, ChgState);

    s = StatePtr->pos;

    ST.real.resize(n);
    ST.moment0.resize(n);
    ST.moment1.resize(n);

    for (k = 0; k < n; k++) {

        // Length is zero.
        StatePtr->pos        = s;

        StatePtr->ref        = ref;

        StatePtr->real[k].IonZ  = ChgState[k];
        StatePtr->real[k].IonQ  = NChg[k];
        StatePtr->real[k].IonEs = ref.IonEs;
        StatePtr->real[k].IonEk = Ek_recomb;
        StatePtr->real[k].IonW  = StatePtr->real[k].IonEk + StatePtr->ref.IonEs;
        StatePtr->real[k].gamma = StatePtr->real[k].IonW/StatePtr->ref.IonEs;
        StatePtr->real[k].beta  = sqrt(1e0-1e0/sqr(StatePtr->real[k].gamma));
        StatePtr->real[k].phis  = Fy_abs_recomb;
        StatePtr->real[k].IonEk = Ek_recomb;
        StatePtr->moment0[k]    = CenofChg;
        StatePtr->moment1[k]    = tmpmat;
    }

    assert(CenofChg==StatePtr->moment0_env);
}
<|endoftext|>


<commit_before>/*
 * Copyright deipi.com LLC and contributors. All rights reserved.
 *
 * 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 "client_binary.h"

#include "server.h"
#include "utils.h"
#include "length.h"

#include <assert.h>
#include <sys/socket.h>

#ifdef HAVE_REMOTE_PROTOCOL

//
// Xapian binary client
//

BinaryClient::BinaryClient(XapiandServer *server_, ev::loop_ref *loop, int sock_, DatabasePool *database_pool_, ThreadPool *thread_pool_, double active_timeout_, double idle_timeout_)
	: BaseClient(server_, loop, sock_, database_pool_, thread_pool_, active_timeout_, idle_timeout_),
	  RemoteProtocol(std::vector<std::string>(), active_timeout_, idle_timeout_, true),
	  running(false),
	  started(false)
{
	pthread_mutex_lock(&XapiandServer::static_mutex);
	int total_clients = XapiandServer::total_clients;
	int binary_clients = ++XapiandServer::binary_clients;
	pthread_mutex_unlock(&XapiandServer::static_mutex);

	LOG_CONN(this, "Got connection (sock=%d), %d binary client(s) of a total of %d connected.\n", sock, binary_clients, XapiandServer::total_clients);

	thread_pool->addTask(this);

	LOG_OBJ(this, "CREATED BINARY CLIENT! (%d clients)\n", binary_clients);
	assert(binary_clients <= total_clients);
}

BinaryClient::~BinaryClient()
{
	std::unordered_map<Xapian::Database *, Database *>::const_iterator it(databases.begin());
	for (; it != databases.end(); it++) {
		Database *database = it->second;
		database_pool->checkin(&database);
	}

	pthread_mutex_lock(&XapiandServer::static_mutex);
	int binary_clients = --XapiandServer::binary_clients;
	pthread_mutex_unlock(&XapiandServer::static_mutex);

	LOG_OBJ(this, "DELETED BINARY CLIENT! (%d clients left)\n", binary_clients);
	assert(binary_clients >= 0);
}

void BinaryClient::on_read(const char *buf, ssize_t received)
{
	buffer.append(buf, received);
	while (buffer.length() >= 2) {
		const char *o = buffer.data();
		const char *p = o;
		const char *p_end = p + buffer.size();

		message_type type = static_cast<message_type>(*p++);
		size_t len = decode_length(&p, p_end, true);
		if (len == -1) {
			return;
		}
		std::string data = std::string(p, len);
		buffer.erase(0, p - o + len);

		Buffer *msg = new Buffer(type, data.c_str(), data.size());

		messages_queue.push(msg);
	}
	pthread_mutex_lock(&qmtx);
	if (!messages_queue.empty()) {
		if (!running) {
			running = true;
			thread_pool->addTask(this);
		}
	}
	pthread_mutex_unlock(&qmtx);
}

message_type BinaryClient::get_message(double timeout, std::string & result, message_type required_type)
{
	Buffer* msg;
	if (!messages_queue.pop(msg)) {
		throw Xapian::NetworkError("No message available");
	}

	const char *msg_str = msg->dpos();
	size_t msg_size = msg->nbytes();

	std::string message = std::string(msg_str, msg_size);

	std::string buf(&msg->type, 1);
	buf += encode_length(msg_size);
	buf += message;
	LOG_BINARY_PROTO(this, "get_message: '%s'\n", repr(buf).c_str());

	result = message;

	message_type type = static_cast<message_type>(msg->type);

	delete msg;

	return type;
}

void BinaryClient::send_message(reply_type type, const std::string &message) {
	char type_as_char = static_cast<char>(type);
	std::string buf(&type_as_char, 1);
	buf += encode_length(message.size());
	buf += message;

	LOG_BINARY_PROTO(this, "send_message: '%s'\n", repr(buf).c_str());

	write(buf);
}

void BinaryClient::send_message(reply_type type, const std::string &message, double end_time)
{
	send_message(type, message);
}

void BinaryClient::shutdown()
{
	server->manager->async_shutdown.send();
}

Xapian::Database * BinaryClient::get_db(bool writable_)
{
	pthread_mutex_lock(&qmtx);
	if (endpoints.empty()) {
		pthread_mutex_unlock(&qmtx);
		return NULL;
	}
	Endpoints endpoints_ = endpoints;
	pthread_mutex_unlock(&qmtx);

	Database *database = NULL;
	if (!database_pool->checkout(&database, endpoints_, writable_)) {
		return NULL;
	}

	pthread_mutex_lock(&qmtx);
	databases[database->db] = database;
	pthread_mutex_unlock(&qmtx);

	return database->db;
}

void BinaryClient::release_db(Xapian::Database *db_)
{
	if (db_) {
		pthread_mutex_lock(&qmtx);
		Database *database = databases[db_];
		databases.erase(db_);
		pthread_mutex_unlock(&qmtx);

		database_pool->checkin(&database);
	}
}

void BinaryClient::select_db(const std::vector<std::string> &dbpaths_, bool writable_, int flags)
{
	pthread_mutex_lock(&qmtx);
	endpoints.clear();
	std::vector<std::string>::const_iterator i(dbpaths_.begin());
	for (; i != dbpaths_.end(); i++) {
		endpoints.insert(Endpoint(*i, std::string(), XAPIAND_BINARY_SERVERPORT));
	}
	dbpaths = dbpaths_;
	pthread_mutex_unlock(&qmtx);
}

void BinaryClient::run()
{
	while (true) {
		pthread_mutex_lock(&qmtx);
		if (started && messages_queue.empty()) {
			running = false;
			pthread_mutex_unlock(&qmtx);
			break;
		}
		pthread_mutex_unlock(&qmtx);

		try {
			if (started) {
				run_one();
			} else {
				started = true;
				msg_update(std::string());
			}
		} catch (const Xapian::NetworkError &e) {
			LOG_ERR(this, "ERROR: %s\n", e.get_msg().c_str());
		} catch (...) {
			LOG_ERR(this, "ERROR!\n");
		}
	}
}

#endif  /* HAVE_REMOTE_PROTOCOL */
<commit_msg>Binary protocol shutdown only closes client<commit_after>/*
 * Copyright deipi.com LLC and contributors. All rights reserved.
 *
 * 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 "client_binary.h"

#include "server.h"
#include "utils.h"
#include "length.h"

#include <assert.h>
#include <sys/socket.h>

#ifdef HAVE_REMOTE_PROTOCOL

//
// Xapian binary client
//

BinaryClient::BinaryClient(XapiandServer *server_, ev::loop_ref *loop, int sock_, DatabasePool *database_pool_, ThreadPool *thread_pool_, double active_timeout_, double idle_timeout_)
	: BaseClient(server_, loop, sock_, database_pool_, thread_pool_, active_timeout_, idle_timeout_),
	  RemoteProtocol(std::vector<std::string>(), active_timeout_, idle_timeout_, true),
	  running(false),
	  started(false)
{
	pthread_mutex_lock(&XapiandServer::static_mutex);
	int total_clients = XapiandServer::total_clients;
	int binary_clients = ++XapiandServer::binary_clients;
	pthread_mutex_unlock(&XapiandServer::static_mutex);

	LOG_CONN(this, "Got connection (sock=%d), %d binary client(s) of a total of %d connected.\n", sock, binary_clients, XapiandServer::total_clients);

	thread_pool->addTask(this);

	LOG_OBJ(this, "CREATED BINARY CLIENT! (%d clients)\n", binary_clients);
	assert(binary_clients <= total_clients);
}

BinaryClient::~BinaryClient()
{
	std::unordered_map<Xapian::Database *, Database *>::const_iterator it(databases.begin());
	for (; it != databases.end(); it++) {
		Database *database = it->second;
		database_pool->checkin(&database);
	}

	pthread_mutex_lock(&XapiandServer::static_mutex);
	int binary_clients = --XapiandServer::binary_clients;
	pthread_mutex_unlock(&XapiandServer::static_mutex);

	LOG_OBJ(this, "DELETED BINARY CLIENT! (%d clients left)\n", binary_clients);
	assert(binary_clients >= 0);
}

void BinaryClient::on_read(const char *buf, ssize_t received)
{
	buffer.append(buf, received);
	while (buffer.length() >= 2) {
		const char *o = buffer.data();
		const char *p = o;
		const char *p_end = p + buffer.size();

		message_type type = static_cast<message_type>(*p++);
		size_t len = decode_length(&p, p_end, true);
		if (len == -1) {
			return;
		}
		std::string data = std::string(p, len);
		buffer.erase(0, p - o + len);

		Buffer *msg = new Buffer(type, data.c_str(), data.size());

		messages_queue.push(msg);
	}
	pthread_mutex_lock(&qmtx);
	if (!messages_queue.empty()) {
		if (!running) {
			running = true;
			thread_pool->addTask(this);
		}
	}
	pthread_mutex_unlock(&qmtx);
}

message_type BinaryClient::get_message(double timeout, std::string & result, message_type required_type)
{
	Buffer* msg;
	if (!messages_queue.pop(msg)) {
		throw Xapian::NetworkError("No message available");
	}

	const char *msg_str = msg->dpos();
	size_t msg_size = msg->nbytes();

	std::string message = std::string(msg_str, msg_size);

	std::string buf(&msg->type, 1);
	buf += encode_length(msg_size);
	buf += message;
	LOG_BINARY_PROTO(this, "get_message: '%s'\n", repr(buf).c_str());

	result = message;

	message_type type = static_cast<message_type>(msg->type);

	delete msg;

	return type;
}

void BinaryClient::send_message(reply_type type, const std::string &message) {
	char type_as_char = static_cast<char>(type);
	std::string buf(&type_as_char, 1);
	buf += encode_length(message.size());
	buf += message;

	LOG_BINARY_PROTO(this, "send_message: '%s'\n", repr(buf).c_str());

	write(buf);
}

void BinaryClient::send_message(reply_type type, const std::string &message, double end_time)
{
	send_message(type, message);
}

void BinaryClient::shutdown()
{
	destroy();
	// server->manager->async_shutdown.send();
}

Xapian::Database * BinaryClient::get_db(bool writable_)
{
	pthread_mutex_lock(&qmtx);
	if (endpoints.empty()) {
		pthread_mutex_unlock(&qmtx);
		return NULL;
	}
	Endpoints endpoints_ = endpoints;
	pthread_mutex_unlock(&qmtx);

	Database *database = NULL;
	if (!database_pool->checkout(&database, endpoints_, writable_)) {
		return NULL;
	}

	pthread_mutex_lock(&qmtx);
	databases[database->db] = database;
	pthread_mutex_unlock(&qmtx);

	return database->db;
}

void BinaryClient::release_db(Xapian::Database *db_)
{
	if (db_) {
		pthread_mutex_lock(&qmtx);
		Database *database = databases[db_];
		databases.erase(db_);
		pthread_mutex_unlock(&qmtx);

		database_pool->checkin(&database);
	}
}

void BinaryClient::select_db(const std::vector<std::string> &dbpaths_, bool writable_, int flags)
{
	pthread_mutex_lock(&qmtx);
	endpoints.clear();
	std::vector<std::string>::const_iterator i(dbpaths_.begin());
	for (; i != dbpaths_.end(); i++) {
		endpoints.insert(Endpoint(*i, std::string(), XAPIAND_BINARY_SERVERPORT));
	}
	dbpaths = dbpaths_;
	pthread_mutex_unlock(&qmtx);
}

void BinaryClient::run()
{
	while (true) {
		pthread_mutex_lock(&qmtx);
		if (started && messages_queue.empty()) {
			running = false;
			pthread_mutex_unlock(&qmtx);
			break;
		}
		pthread_mutex_unlock(&qmtx);

		try {
			if (started) {
				run_one();
			} else {
				started = true;
				msg_update(std::string());
			}
		} catch (const Xapian::NetworkError &e) {
			LOG_ERR(this, "ERROR: %s\n", e.get_msg().c_str());
		} catch (...) {
			LOG_ERR(this, "ERROR!\n");
		}
	}
}

#endif  /* HAVE_REMOTE_PROTOCOL */
<|endoftext|>


<commit_before>// Copyright Hugh Perkins 2016

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cocl/cocl_streams.h"

#include "cocl/cocl_events.h"
#include "cocl/hostside_opencl_funcs.h"
#include "cocl/cocl_context.h"

#include "EasyCL/EasyCL.h"

#include <iostream>
#include <memory>
#include <vector>
#include <map>
#include <set>

#include "pthread.h"

// #include "CL/cl.h"

using namespace std;
using namespace cocl;
using namespace easycl;

// #undef COCL_PRINT
// #define COCL_PRINT(stuff) \
//     stuff ;

namespace cocl {
    void coclCallback(cl_event event, cl_int status, void *userdata) {
        // cout << "coclCallback running " << endl;
        EasyCL::checkError(status);
        CoclCallbackInfo *info = (CoclCallbackInfo *)userdata;
        clReleaseEvent(event);
        info->callback(info->_queue, 0, info->userdata);
        delete info;
    }

    CoclStream::CoclStream(EasyCL *cl) {
        this->clqueue = cl->newQueue();
    }
    CoclStream::~CoclStream() {
        delete clqueue;
    }
    // StreamLock::StreamLock(CoclStream *stream) {
    //     this->stream = stream;
    //     pthread_mutex_lock(&stream->mutex);
    // }
    // StreamLock::~StreamLock() {
    //     pthread_mutex_unlock(&stream->mutex);
    // }
}

size_t cudaStreamSynchronize(char *_queue) {
    // cout << "cudaStreamSynchronize()" << endl;
    CoclStream *stream = (CoclStream *)_queue;
    ThreadVars *v = getThreadVars();
    EasyCL *cl = v->getContext()->getCl();
    if(stream == 0) {
        stream = v->currentContext->default_stream.get();
    }
    // cout << "got stream " << (void *)stream << endl;
    // cout << "got v" << endl;
    // cout << "got cl" << endl;
    // StreamLock streamlock(stream);
    CLQueue *queue = stream->clqueue;
    // cout << "got queu" << endl;
    // CLQueue *queue = (CLQueue*)_queue;
    COCL_PRINT(cout << "cudaStreamSynchronize queue=" << queue << endl);
    // hostside_opencl_funcs_assure_initialized();

    // assert(stream == 0);

    if(queue == 0) {
        cl->finish();
    } else {
        clFinish(queue->queue);
    }

    return 0;
}

size_t cuStreamSynchronize(char *_queue) {
    // CLQueue *queue = (CLQueue*)_queue;
    // cout << "cuStreamSynchronize()" << endl;
    return cudaStreamSynchronize(_queue);
}

size_t cuStreamCreate(char **_pstream, unsigned int flags) {
    // COCL_PRINT(cout << "cuStreamCreate redirected" << endl);
    CoclStream **pstream = (CoclStream**)_pstream;
    ThreadVars *v = getThreadVars();
    // COCL_PRINT(cout << "cuStreamCreate current context=" << (void *)v->currentContext << endl);
    EasyCL *cl = v->getContext()->getCl();
    // hostside_opencl_funcs_assure_initialized();
    // CLQueue *clqueue = cl->newQueue();
    CoclStream *coclStream = new CoclStream(cl);
    // COCL_PRINT(cout << "cuStreamCreate redirected new stream " << (void *)coclStream << endl);
    // coclStream->clqueue = clqueue;
    *pstream = coclStream;
    // cout << "done assign" << endl;
    return 0;
}

size_t cudaStreamCreate(char **_pstream) {
    return cuStreamCreate(_pstream, 0);
}

size_t cuStreamDestroy_v2(char *_queue) {
    CoclStream *stream = (CoclStream *)_queue;
    // StreamLock streamlock(stream);
    // COCL_PRINT(cout << "cuStreamDestroy_v2 redirected stream=" << (void *)stream << endl);
    delete stream;
    return 0;
}

size_t cudaStreamDestroy(char *_queue) {
    return cuStreamDestroy_v2(_queue);
}

size_t cudaStreamQuery(char *_queue) {
    return cuStreamSynchronize(_queue);
}

size_t cuStreamQuery(char *_queue) {
    return cuStreamSynchronize(_queue);
}

size_t cudaStreamAddCallback(char *_queue, cudacallbacktype callback, void *userdata, int flags) {
    CoclStream *stream = (CoclStream *)_queue;
    // StreamLock streamlock(stream);
    CLQueue *queue = stream->clqueue;
    // CLQueue *queue = (CLQueue*)_queue;
    // we need to queue an event, and attach the callback to that;
    cl_int err;
    cl_event event;
    err= clEnqueueBarrierWithWaitList(queue->queue,
        0,
        0,
        &event
        );
    EasyCL::checkError(err);
    CoclCallbackInfo *info = new CoclCallbackInfo();
    // cout << "created info" << endl;
    info->callback = callback;
    info->userdata = userdata;
    info->_queue = _queue;
    // cout << "calling seteventcallback" << endl;
    err = clSetEventCallback(event, CL_COMPLETE, cocl::coclCallback, info);
    // cout << "called clseteventcallback" << endl;
    EasyCL::checkError(err);
    return 0;
}
<commit_msg>reduce spam<commit_after>// Copyright Hugh Perkins 2016

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cocl/cocl_streams.h"

#include "cocl/cocl_events.h"
#include "cocl/hostside_opencl_funcs.h"
#include "cocl/cocl_context.h"

#include "EasyCL/EasyCL.h"

#include <iostream>
#include <memory>
#include <vector>
#include <map>
#include <set>

#include "pthread.h"

// #include "CL/cl.h"

using namespace std;
using namespace cocl;
using namespace easycl;

#undef COCL_PRINT
#define COCL_PRINT(x)
// #define COCL_PRINT(stuff) \
//     stuff ;

namespace cocl {
    void coclCallback(cl_event event, cl_int status, void *userdata) {
        // cout << "coclCallback running " << endl;
        EasyCL::checkError(status);
        CoclCallbackInfo *info = (CoclCallbackInfo *)userdata;
        clReleaseEvent(event);
        info->callback(info->_queue, 0, info->userdata);
        delete info;
    }

    CoclStream::CoclStream(EasyCL *cl) {
        this->clqueue = cl->newQueue();
    }
    CoclStream::~CoclStream() {
        delete clqueue;
    }
    // StreamLock::StreamLock(CoclStream *stream) {
    //     this->stream = stream;
    //     pthread_mutex_lock(&stream->mutex);
    // }
    // StreamLock::~StreamLock() {
    //     pthread_mutex_unlock(&stream->mutex);
    // }
}

size_t cudaStreamSynchronize(char *_queue) {
    // cout << "cudaStreamSynchronize()" << endl;
    CoclStream *stream = (CoclStream *)_queue;
    ThreadVars *v = getThreadVars();
    EasyCL *cl = v->getContext()->getCl();
    if(stream == 0) {
        stream = v->currentContext->default_stream.get();
    }
    // cout << "got stream " << (void *)stream << endl;
    // cout << "got v" << endl;
    // cout << "got cl" << endl;
    // StreamLock streamlock(stream);
    CLQueue *queue = stream->clqueue;
    // cout << "got queu" << endl;
    // CLQueue *queue = (CLQueue*)_queue;
    COCL_PRINT(cout << "cudaStreamSynchronize queue=" << queue << endl);
    // hostside_opencl_funcs_assure_initialized();

    // assert(stream == 0);

    if(queue == 0) {
        cl->finish();
    } else {
        clFinish(queue->queue);
    }

    return 0;
}

size_t cuStreamSynchronize(char *_queue) {
    // CLQueue *queue = (CLQueue*)_queue;
    // cout << "cuStreamSynchronize()" << endl;
    return cudaStreamSynchronize(_queue);
}

size_t cuStreamCreate(char **_pstream, unsigned int flags) {
    // COCL_PRINT(cout << "cuStreamCreate redirected" << endl);
    CoclStream **pstream = (CoclStream**)_pstream;
    ThreadVars *v = getThreadVars();
    // COCL_PRINT(cout << "cuStreamCreate current context=" << (void *)v->currentContext << endl);
    EasyCL *cl = v->getContext()->getCl();
    // hostside_opencl_funcs_assure_initialized();
    // CLQueue *clqueue = cl->newQueue();
    CoclStream *coclStream = new CoclStream(cl);
    // COCL_PRINT(cout << "cuStreamCreate redirected new stream " << (void *)coclStream << endl);
    // coclStream->clqueue = clqueue;
    *pstream = coclStream;
    // cout << "done assign" << endl;
    return 0;
}

size_t cudaStreamCreate(char **_pstream) {
    return cuStreamCreate(_pstream, 0);
}

size_t cuStreamDestroy_v2(char *_queue) {
    CoclStream *stream = (CoclStream *)_queue;
    // StreamLock streamlock(stream);
    // COCL_PRINT(cout << "cuStreamDestroy_v2 redirected stream=" << (void *)stream << endl);
    delete stream;
    return 0;
}

size_t cudaStreamDestroy(char *_queue) {
    return cuStreamDestroy_v2(_queue);
}

size_t cudaStreamQuery(char *_queue) {
    return cuStreamSynchronize(_queue);
}

size_t cuStreamQuery(char *_queue) {
    return cuStreamSynchronize(_queue);
}

size_t cudaStreamAddCallback(char *_queue, cudacallbacktype callback, void *userdata, int flags) {
    CoclStream *stream = (CoclStream *)_queue;
    // StreamLock streamlock(stream);
    CLQueue *queue = stream->clqueue;
    // CLQueue *queue = (CLQueue*)_queue;
    // we need to queue an event, and attach the callback to that;
    cl_int err;
    cl_event event;
    err= clEnqueueBarrierWithWaitList(queue->queue,
        0,
        0,
        &event
        );
    EasyCL::checkError(err);
    CoclCallbackInfo *info = new CoclCallbackInfo();
    // cout << "created info" << endl;
    info->callback = callback;
    info->userdata = userdata;
    info->_queue = _queue;
    // cout << "calling seteventcallback" << endl;
    err = clSetEventCallback(event, CL_COMPLETE, cocl::coclCallback, info);
    // cout << "called clseteventcallback" << endl;
    EasyCL::checkError(err);
    return 0;
}
<|endoftext|>


<commit_before>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software
 * Foundation.  See file COPYING.
 *
 */

#include <string>

#include "LogType.h"
#include "Logger.h"

#include <iostream>
#include "Clock.h"

#include "config.h"

#include <sys/stat.h>
#include <sys/types.h>

#include "common/Timer.h"

// per-process lock.  lame, but this way I protect LogType too!
Mutex logger_lock;
SafeTimer logger_timer(logger_lock);
Context *logger_event = 0;
list<Logger*> logger_list;
utime_t start;
int last_flush; // in seconds since start

static void flush_all_loggers();

class C_FlushLoggers : public Context {
public:
  void finish(int r) {
    if (logger_event == this) {
      logger_event = 0;
      flush_all_loggers();
    }
  }
};

void Logger::set_start(utime_t s)
{
  logger_lock.Lock();

  start = s;

  utime_t fromstart = g_clock.now();
  if (fromstart < start) {
    cerr << "set_start: logger time jumped backwards from " << start << " to " << fromstart << std::endl;
    fromstart = start;
  }
  fromstart -= start;
  last_flush = fromstart.sec();

  logger_lock.Unlock();
}

static void flush_all_loggers()
{
  generic_dout(20) << "flush_all_loggers" << dendl;

  utime_t now = g_clock.now();
  utime_t fromstart = now;
  if (fromstart < start) {
    cerr << "logger time jumped backwards from " << start << " to " << fromstart << std::endl;
    //assert(0);
    start = fromstart;
  }
  fromstart -= start;
  int now_sec = fromstart.sec();

  // do any catching up we need to
  while (now_sec - last_flush >= g_conf.log_interval) {
    generic_dout(20) << "fromstart " << fromstart << " last_flush " << last_flush << " flushign" << dendl;
    for (list<Logger*>::iterator p = logger_list.begin();
	 p != logger_list.end();
	 ++p)
      (*p)->_flush();
    last_flush += g_conf.log_interval;
  }

  // schedule next flush event
  utime_t next;
  next.sec_ref() = start.sec() + last_flush + g_conf.log_interval;
  next.usec_ref() = start.usec();
  generic_dout(20) << "logger now=" << now
		   << "  start=" << start
		   << "  next=" << next
		   << dendl;
  logger_event = new C_FlushLoggers;
  logger_timer.add_event_at(next, logger_event);
}

// ---------

Logger::Logger(string fn, LogType *type, bool append)
{
  logger_lock.Lock();
  {
    filename = "";
    if (g_conf.use_abspaths) {
      char cwd[200];
      getcwd(cwd, 200);
      filename = cwd;
      filename += "/";
    }

    filename = "log/";
    if (g_conf.log_name) {
      filename += g_conf.log_name;
      ::mkdir( filename.c_str(), 0755 );   // make sure dir exists
      filename += "/";
    }
    filename += fn;

    if (append)
      out.open(filename.c_str(), ofstream::out|ofstream::app);
    else
      out.open(filename.c_str(), ofstream::out);

    this->type = type;
    wrote_header = -1;
    wrote_header_last = 0;

    version = 0;

    if (logger_list.empty()) {
      // init logger
      if (!g_conf.clock_tare)
	start = g_clock.now();  // time 0!  otherwise g_clock does it for us.

      last_flush = 0;

      // call manually the first time; then it'll schedule itself.
      flush_all_loggers();
    }
    logger_list.push_back(this);
  }
  logger_lock.Unlock();
}

Logger::~Logger()
{
  logger_lock.Lock();
  {
    _flush();
    out.close();
    logger_list.remove(this); // slow, but rare.
    if (logger_list.empty())
      logger_event = 0;       // stop the timer events.
  }
  logger_lock.Unlock();
}

/*
void Logger::flush()
{
  logger_lock.Lock();
  _flush();
  logger_lock.Unlock();
}
*/

void Logger::_flush()
{
  // header?
  wrote_header_last++;
  if (wrote_header != type->version ||
      wrote_header_last > 10) {
    out << "#" << type->keymap.size();
    for (unsigned i=0; i<type->keys.size(); i++) {
      out << "\t" << type->keys[i];
      if (type->avg[i])
	out << "\t" << type->keys[i] << "*\t" << type->keys[i] << "~";
    }
    out << std::endl;  //out << "\t (" << type->keymap.size() << ")" << endl;
    wrote_header = type->version;
    wrote_header_last = 0;
  }

  maybe_resize(type->keys.size());

  // write line to log
  out << last_flush;
  for (unsigned i=0; i<type->keys.size(); i++) {
    if (type->avg[i]) {
      if (vals[i] > 0) {
	double avg = (fvals[i] / (double)vals[i]);
	double var = 0.0;
	if (g_conf.logger_calc_variance) {
	  int n = vals[i];
	  for (vector<double>::iterator p = vals_to_avg[i].begin(); n--; ++p)
	    var += (avg - *p) * (avg - *p);
	}
	out << "\t" << avg << "\t" << vals[i] << "\t" << var;
      } else
	out << "\t0\t0\t0";
    } else {
      if (fvals[i] > 0 && vals[i] == 0)
	out << "\t" << fvals[i];
      else {
	//cout << this << " p " << i << " and size is " << vals.size() << std::endl;
	out << "\t" << vals[i];
      }
    }
  }
  out << std::endl;

  // reset the counters
  for (unsigned i=0; i<type->keys.size(); i++) {
    if (type->inc_keys.count(i)) {
      this->vals[i] = 0;
      this->fvals[i] = 0;
    }
  }
}

long Logger::inc(const char *key, long v)
{
  if (!g_conf.log) return 0;
  logger_lock.Lock();
  int i = type->lookup_key(key);
  if (i < 0) i = type->add_inc(key);
  maybe_resize(i+1);

  vals[i] += v;
  long r = vals[i];
  logger_lock.Unlock();
  return r;
}

double Logger::finc(const char *key, double v)
{
  if (!g_conf.log) return 0;
  logger_lock.Lock();
  int i = type->lookup_key(key);
  if (i < 0) i = type->add_inc(key);
  maybe_resize(i+1);

  fvals[i] += v;
  double r = fvals[i];
  logger_lock.Unlock();
  return r;
}

long Logger::set(const char *key, long v)
{
  if (!g_conf.log) return 0;
  logger_lock.Lock();
  int i = type->lookup_key(key);
  if (i < 0) i = type->add_set(key);
  maybe_resize(i+1);

  //cout << this << " set " << i << " to " << v << std::endl;
  long r = vals[i] = v;
  logger_lock.Unlock();
  return r;
}

double Logger::fset(const char *key, double v)
{
  if (!g_conf.log) return 0;
  logger_lock.Lock();
  int i = type->lookup_key(key);
  if (i < 0) i = type->add_set(key);
  maybe_resize(i+1);

  //cout << this << " fset " << i << " to " << v << std::endl;
  double r = fvals[i] = v;
  logger_lock.Unlock();
  return r;
}

double Logger::favg(const char *key, double v)
{
  if (!g_conf.log) return 0;
  logger_lock.Lock();
  int i = type->lookup_key(key);
  if (i < 0) i = type->add_avg(key);
  maybe_resize(i+1);

  vals[i]++;
  double r = fvals[i] = v;
  if (g_conf.logger_calc_variance)
    vals_to_avg[i].push_back(v);
  logger_lock.Unlock();
  return r;
}

long Logger::get(const char* key)
{
  if (!g_conf.log) return 0;
  logger_lock.Lock();
  int i = type->lookup_key(key);
  maybe_resize(i+1);

  long r = 0;
  if (i >= 0 && i < (int)vals.size())
    r = vals[i];
  logger_lock.Unlock();
  return r;
}

<commit_msg>logger: typo<commit_after>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software
 * Foundation.  See file COPYING.
 *
 */

#include <string>

#include "LogType.h"
#include "Logger.h"

#include <iostream>
#include "Clock.h"

#include "config.h"

#include <sys/stat.h>
#include <sys/types.h>

#include "common/Timer.h"

// per-process lock.  lame, but this way I protect LogType too!
Mutex logger_lock;
SafeTimer logger_timer(logger_lock);
Context *logger_event = 0;
list<Logger*> logger_list;
utime_t start;
int last_flush; // in seconds since start

static void flush_all_loggers();

class C_FlushLoggers : public Context {
public:
  void finish(int r) {
    if (logger_event == this) {
      logger_event = 0;
      flush_all_loggers();
    }
  }
};

void Logger::set_start(utime_t s)
{
  logger_lock.Lock();

  start = s;

  utime_t fromstart = g_clock.now();
  if (fromstart < start) {
    cerr << "set_start: logger time jumped backwards from " << start << " to " << fromstart << std::endl;
    fromstart = start;
  }
  fromstart -= start;
  last_flush = fromstart.sec();

  logger_lock.Unlock();
}

static void flush_all_loggers()
{
  generic_dout(20) << "flush_all_loggers" << dendl;

  utime_t now = g_clock.now();
  utime_t fromstart = now;
  if (fromstart < start) {
    cerr << "logger time jumped backwards from " << start << " to " << fromstart << std::endl;
    //assert(0);
    start = fromstart;
  }
  fromstart -= start;
  int now_sec = fromstart.sec();

  // do any catching up we need to
  while (now_sec - last_flush >= g_conf.log_interval) {
    generic_dout(20) << "fromstart " << fromstart << " last_flush " << last_flush << " flushing" << dendl;
    for (list<Logger*>::iterator p = logger_list.begin();
	 p != logger_list.end();
	 ++p)
      (*p)->_flush();
    last_flush += g_conf.log_interval;
  }

  // schedule next flush event
  utime_t next;
  next.sec_ref() = start.sec() + last_flush + g_conf.log_interval;
  next.usec_ref() = start.usec();
  generic_dout(20) << "logger now=" << now
		   << "  start=" << start
		   << "  next=" << next
		   << dendl;
  logger_event = new C_FlushLoggers;
  logger_timer.add_event_at(next, logger_event);
}

// ---------

Logger::Logger(string fn, LogType *type, bool append)
{
  logger_lock.Lock();
  {
    filename = "";
    if (g_conf.use_abspaths) {
      char cwd[200];
      getcwd(cwd, 200);
      filename = cwd;
      filename += "/";
    }

    filename = "log/";
    if (g_conf.log_name) {
      filename += g_conf.log_name;
      ::mkdir( filename.c_str(), 0755 );   // make sure dir exists
      filename += "/";
    }
    filename += fn;

    if (append)
      out.open(filename.c_str(), ofstream::out|ofstream::app);
    else
      out.open(filename.c_str(), ofstream::out);

    this->type = type;
    wrote_header = -1;
    wrote_header_last = 0;

    version = 0;

    if (logger_list.empty()) {
      // init logger
      if (!g_conf.clock_tare)
	start = g_clock.now();  // time 0!  otherwise g_clock does it for us.

      last_flush = 0;

      // call manually the first time; then it'll schedule itself.
      flush_all_loggers();
    }
    logger_list.push_back(this);
  }
  logger_lock.Unlock();
}

Logger::~Logger()
{
  logger_lock.Lock();
  {
    _flush();
    out.close();
    logger_list.remove(this); // slow, but rare.
    if (logger_list.empty())
      logger_event = 0;       // stop the timer events.
  }
  logger_lock.Unlock();
}

/*
void Logger::flush()
{
  logger_lock.Lock();
  _flush();
  logger_lock.Unlock();
}
*/

void Logger::_flush()
{
  // header?
  wrote_header_last++;
  if (wrote_header != type->version ||
      wrote_header_last > 10) {
    out << "#" << type->keymap.size();
    for (unsigned i=0; i<type->keys.size(); i++) {
      out << "\t" << type->keys[i];
      if (type->avg[i])
	out << "\t" << type->keys[i] << "*\t" << type->keys[i] << "~";
    }
    out << std::endl;  //out << "\t (" << type->keymap.size() << ")" << endl;
    wrote_header = type->version;
    wrote_header_last = 0;
  }

  maybe_resize(type->keys.size());

  // write line to log
  out << last_flush;
  for (unsigned i=0; i<type->keys.size(); i++) {
    if (type->avg[i]) {
      if (vals[i] > 0) {
	double avg = (fvals[i] / (double)vals[i]);
	double var = 0.0;
	if (g_conf.logger_calc_variance) {
	  int n = vals[i];
	  for (vector<double>::iterator p = vals_to_avg[i].begin(); n--; ++p)
	    var += (avg - *p) * (avg - *p);
	}
	out << "\t" << avg << "\t" << vals[i] << "\t" << var;
      } else
	out << "\t0\t0\t0";
    } else {
      if (fvals[i] > 0 && vals[i] == 0)
	out << "\t" << fvals[i];
      else {
	//cout << this << " p " << i << " and size is " << vals.size() << std::endl;
	out << "\t" << vals[i];
      }
    }
  }
  out << std::endl;

  // reset the counters
  for (unsigned i=0; i<type->keys.size(); i++) {
    if (type->inc_keys.count(i)) {
      this->vals[i] = 0;
      this->fvals[i] = 0;
    }
  }
}

long Logger::inc(const char *key, long v)
{
  if (!g_conf.log) return 0;
  logger_lock.Lock();
  int i = type->lookup_key(key);
  if (i < 0) i = type->add_inc(key);
  maybe_resize(i+1);

  vals[i] += v;
  long r = vals[i];
  logger_lock.Unlock();
  return r;
}

double Logger::finc(const char *key, double v)
{
  if (!g_conf.log) return 0;
  logger_lock.Lock();
  int i = type->lookup_key(key);
  if (i < 0) i = type->add_inc(key);
  maybe_resize(i+1);

  fvals[i] += v;
  double r = fvals[i];
  logger_lock.Unlock();
  return r;
}

long Logger::set(const char *key, long v)
{
  if (!g_conf.log) return 0;
  logger_lock.Lock();
  int i = type->lookup_key(key);
  if (i < 0) i = type->add_set(key);
  maybe_resize(i+1);

  //cout << this << " set " << i << " to " << v << std::endl;
  long r = vals[i] = v;
  logger_lock.Unlock();
  return r;
}

double Logger::fset(const char *key, double v)
{
  if (!g_conf.log) return 0;
  logger_lock.Lock();
  int i = type->lookup_key(key);
  if (i < 0) i = type->add_set(key);
  maybe_resize(i+1);

  //cout << this << " fset " << i << " to " << v << std::endl;
  double r = fvals[i] = v;
  logger_lock.Unlock();
  return r;
}

double Logger::favg(const char *key, double v)
{
  if (!g_conf.log) return 0;
  logger_lock.Lock();
  int i = type->lookup_key(key);
  if (i < 0) i = type->add_avg(key);
  maybe_resize(i+1);

  vals[i]++;
  double r = fvals[i] = v;
  if (g_conf.logger_calc_variance)
    vals_to_avg[i].push_back(v);
  logger_lock.Unlock();
  return r;
}

long Logger::get(const char* key)
{
  if (!g_conf.log) return 0;
  logger_lock.Lock();
  int i = type->lookup_key(key);
  maybe_resize(i+1);

  long r = 0;
  if (i >= 0 && i < (int)vals.size())
    r = vals[i];
  logger_lock.Unlock();
  return r;
}

<|endoftext|>