<commit_before>/** @file gsDofMapper.h

    @brief Provides the gsDofMapper class for re-indexing DoFs.

    This file is part of the G+Smo library.

    This Source Code Form is subject to the terms of the Mozilla Public
    License, v. 2.0. If a copy of the MPL was not distributed with this
    file, You can obtain one at http://mozilla.org/MPL/2.0/.

    Author(s): C. Hofreither, A. Mantzaflaris
*/

#include <gsCore/gsDofMapper.h>

namespace gismo
{

gsDofMapper::gsDofMapper() :
m_shift(0), m_numFreeDofs(0), m_curElimId(-1), m_curCouplingId(1)
{
    m_offset.resize(1,0);
}

void gsDofMapper::localToGlobal(const gsMatrix<unsigned>& locals,
                                index_t patchIndex,
                                gsMatrix<unsigned>& globals) const
{
    GISMO_ASSERT( locals.cols() == 1, "localToGlobal: Expecting one column of locals");
    const index_t numActive = locals.rows();

    globals.resize(numActive,1);

    for (index_t i = 0; i < numActive; ++i)
        globals(i,0) = MAPPER_PATCH_DOF(locals(i,0), patchIndex)+m_shift;
}

// This function can not have enough information to do its job if dim>2
// GISMO_DEPRECATED
void gsDofMapper::matchInterface( index_t k1, index_t k2,
                                     const gsMatrix<unsigned> & b1,
                                     const gsMatrix<unsigned> & b2,
                                     const gsVector<bool> &orient )
{
    // Boundaries must be conforming (matching)
    const index_t sz = b1.size();
    if ( sz != b2.size() )
    {
        gsWarn<<"gsDofMapper: Problem: non-conforming interface "<<
                "("    <<k1<<","<< //i.first().side<<
                ")<->("<<k2<<","<< //i.second().side<<
                ") ~ ("<<sz<<","<<b2.size() <<").\n";

        gsWarn<< b1.transpose() << "\n";
        gsWarn<< b2.transpose() << "\n";

        GISMO_ERROR( "Non-conforming boundaries.\n" );
    }

    if( orient.size() )
    {
        if ( orient[0] == true ) // assumes 1D side
        {
            for ( index_t k=0; k<sz; ++k)
                this->matchDof( k1, b1(k,0), k2, b2(k,0) );
        }
        else
        {
            for ( index_t k=0; k<sz; ++k)
                this->matchDof( k1, b1(k,0), k2, b2(sz-k-1,0) );
        }
    }
    else
        for ( index_t k=0; k<sz; ++k)
            this->matchDof( k1, b1(k,0), k2, b2(k,0) );
}

void gsDofMapper::colapseDofs(index_t k, const gsMatrix<unsigned> & b )
{
    const index_t last = b.size()-1;
    for ( index_t k=0; k<last; ++k)
    {
        this->matchDof( k, b(k,0), k, b(k+1,0) );
    }
}

void gsDofMapper::matchDof( index_t u, index_t i, index_t v, index_t j )
{
    index_t d1 = MAPPER_PATCH_DOF(i,u);
    index_t d2 = MAPPER_PATCH_DOF(j,v);

    // make sure that d1 <= d2, simplifies implementation
    if (d1 > d2)
    {
        std::swap(d1, d2);
        std::swap(u, v);
        std::swap(i, j);
    }

    if (d1 < 0)         // first dof is eliminated
    {
        if (d2 < 0)         mergeDofsGlobally( d1, d2 );        // both are eliminated, merge their indices
        else if (d2 == 0)   MAPPER_PATCH_DOF(j,v) = d1;             // second is free, eliminate it along with first
        else /* d2 > 0*/    replaceDofGlobally( d2, d1 );       // second is coupling, eliminate all instances of it
    }
    else if (d1 == 0)   // first dof is a free dof
    {
        if (d2 == 0)        MAPPER_PATCH_DOF(i,u) = MAPPER_PATCH_DOF(j,v) = m_curCouplingId++;  // both are free, assign them a new coupling id
        else if (d2 > 0)    MAPPER_PATCH_DOF(i,u) = d2;             // second is coupling, add first to the same coupling group
        else                GISMO_ERROR("Something went terribly wrong");
    }
    else /* d1 > 0 */   // first dof is a coupling dof
    {
        GISMO_ASSERT(d2 > 0, "Something went terribly wrong");
        mergeDofsGlobally( d1, d2 );                            // both are coupling dofs, merge them
    }

    // if we merged two different non-eliminated dofs, we lost one free dof
    if ( (d1 != d2 && (d1 >= 0 || d2 >= 0) ) || (d1 == 0 && d2 == 0) )
        --m_numFreeDofs;
}

void gsDofMapper::markBoundary( index_t k, const gsMatrix<unsigned> & boundaryDofs )
{
    for (index_t i = 0; i < boundaryDofs.rows(); ++i)
    {
        eliminateDof( boundaryDofs(i,0), k );
    }

    // TO DO: save inverse, eg boundaryDofs(i,0)
}

void gsDofMapper::eliminateDof( index_t i, index_t k )
{
    const index_t old = MAPPER_PATCH_DOF(i,k);
    if (old == 0)       // regular free dof
    {
        --m_numFreeDofs;
        MAPPER_PATCH_DOF(i,k) = m_curElimId--;
    }
    else if (old > 0)   // coupling dof
    {
        --m_numFreeDofs;
        replaceDofGlobally( old, m_curElimId-- );
    }
    // else: old < 0: already an eliminated dof, nothing to do
}

void gsDofMapper::finalize()
{
    GISMO_ASSERT(m_curElimId!=0, "Error in gsDofMapper::finalize() called twince.");

    index_t curFreeDof = 0;                 // free dofs start at 0
    index_t curElimDof = m_numFreeDofs;     // eliminated dofs start after free dofs
    std::vector<index_t> couplingDofs(m_curCouplingId - 1, -1);
    std::vector<index_t> elimDofs(-m_curElimId - 1, -1);

    // Coupled dofs start after standard dofs
    index_t curCplDof = m_numFreeDofs - couplingDofs.size();

    for (std::size_t k = 0; k < m_dofs.size(); ++k)
    {
        const index_t dofType = m_dofs[k];

        if (dofType == 0)       // standard dof
            m_dofs[k] = curFreeDof++;
        else if (dofType < 0)   // eliminated dof
        {
            const index_t id = -dofType - 1;
            if (elimDofs[id] < 0)
                elimDofs[id] = curElimDof++;
            m_dofs[k] = elimDofs[id];
        }
        else // dofType > 0     // coupling dof
        {
            const index_t id = dofType - 1;
            if (couplingDofs[id] < 0)
                //couplingDofs[id] = curFreeDof++;
                couplingDofs[id] =   curCplDof++;
            m_dofs[k] = couplingDofs[id];
        }
    }
    m_numElimDofs = curElimDof - m_numFreeDofs;

    GISMO_ASSERT(curCplDof == m_numFreeDofs,
                 "gsDofMapper::finalize() - computed number of coupling dofs does not match allocated number");
    GISMO_ASSERT(curFreeDof + static_cast<index_t>(couplingDofs.size()) == m_numFreeDofs,
                 "gsDofMapper::finalize() - computed number of free dofs does not match allocated number");

    m_curElimId = 0;// Only equal to zero after finalize is called.

}

void gsDofMapper::print() const
{
    gsInfo<<"Dofs: "<< this->size() <<"\n";
    gsInfo<<" free: "<< this->freeSize() <<"\n";
    gsInfo<<" elim: "<< this->boundarySize() <<"\n";
}

void gsDofMapper::setIdentity(index_t nPatches, size_t nDofs)
{
    m_curElimId     = -1;
    m_curCouplingId =  1;
    m_numFreeDofs = nDofs;

    // Initialize all offsets to zero
    m_offset.resize(nPatches, 0);

    m_dofs.resize( m_numFreeDofs, 0);

    finalize();
}

void gsDofMapper::initPatchDofs(const gsVector<index_t> & patchDofSizes)
{
    m_curElimId     = -1;
    m_curCouplingId =  1;

    const size_t nPatches = patchDofSizes.size();

    // Initialize offsets and dof holder
    m_offset.reserve( nPatches );
    m_offset.push_back(0);
    for (size_t k = 1; k < nPatches; ++k)
    {
        m_offset.push_back( m_offset.back() + patchDofSizes[k-1] );
    }

    m_numFreeDofs = m_offset.back() + patchDofSizes[nPatches-1];

    m_dofs.resize( m_numFreeDofs, 0);
}

void gsDofMapper::replaceDofGlobally(index_t oldIdx, index_t newIdx)
{
    std::replace( m_dofs.begin(), m_dofs.end(), oldIdx, newIdx );
}

void gsDofMapper::mergeDofsGlobally(index_t dof1, index_t dof2)
{
    if (dof1 != dof2)
    {
        // replace the larger by the smaller for more consistent numbering.
        if (dof1 < dof2)
            std::swap(dof1, dof2);

        replaceDofGlobally(dof1, dof2);
    }
}

index_t gsDofMapper::coupledSize() const
{
    // Property: coupled (eliminated or not) DoFs appear more than once in the mapping.
    GISMO_ENSURE(m_curElimId==0, "finalize() was not called on gsDofMapper");

    std::vector<index_t> CountMap(m_numFreeDofs,0);

    // Count number of appearances of each free DoF
    for (std::vector<index_t>::const_iterator it = m_dofs.begin(); it != m_dofs.end(); ++it)
        if ( *it < m_numFreeDofs )
            CountMap[*it]++;

    // Count the number of freeDoFs that appear more than once
    return std::count_if( CountMap.begin(), CountMap.end(), std::bind1st(std::greater<index_t>(), 1) );
    /* // Equivalent implementation
    index_t count = 0;
    for (std::vector<index_t>::const_iterator it = CountMap.begin(); it != CountMap.end(); ++it)
        if ( *it > 1 )
            count++;
    return count;
    */
}

void gsDofMapper::setShift (index_t shift)
{
    m_shift=shift;
}

} // namespace gismo

<commit_msg>small fix<commit_after>/** @file gsDofMapper.h

    @brief Provides the gsDofMapper class for re-indexing DoFs.

    This file is part of the G+Smo library.

    This Source Code Form is subject to the terms of the Mozilla Public
    License, v. 2.0. If a copy of the MPL was not distributed with this
    file, You can obtain one at http://mozilla.org/MPL/2.0/.

    Author(s): C. Hofreither, A. Mantzaflaris
*/

#include <gsCore/gsDofMapper.h>

namespace gismo
{

gsDofMapper::gsDofMapper() :
m_shift(0), m_numFreeDofs(0), m_curElimId(-1), m_curCouplingId(1)
{
    m_offset.resize(1,0);
}

void gsDofMapper::localToGlobal(const gsMatrix<unsigned>& locals,
                                index_t patchIndex,
                                gsMatrix<unsigned>& globals) const
{
    GISMO_ASSERT( locals.cols() == 1, "localToGlobal: Expecting one column of locals");
    const index_t numActive = locals.rows();

    globals.resize(numActive,1);

    for (index_t i = 0; i < numActive; ++i)
        globals(i,0) = MAPPER_PATCH_DOF(locals(i,0), patchIndex)+m_shift;
}

// This function can not have enough information to do its job if dim>2
// GISMO_DEPRECATED
void gsDofMapper::matchInterface( index_t k1, index_t k2,
                                     const gsMatrix<unsigned> & b1,
                                     const gsMatrix<unsigned> & b2,
                                     const gsVector<bool> &orient )
{
    // Boundaries must be conforming (matching)
    const index_t sz = b1.size();
    if ( sz != b2.size() )
    {
        gsWarn<<"gsDofMapper: Problem: non-conforming interface "<<
                "("    <<k1<<","<< //i.first().side<<
                ")<->("<<k2<<","<< //i.second().side<<
                ") ~ ("<<sz<<","<<b2.size() <<").\n";

        gsWarn<< b1.transpose() << "\n";
        gsWarn<< b2.transpose() << "\n";

        GISMO_ERROR( "Non-conforming boundaries.\n" );
    }

    if( orient.size() )
    {
        if ( orient[0] == true ) // assumes 1D side
        {
            for ( index_t k=0; k<sz; ++k)
                this->matchDof( k1, b1(k,0), k2, b2(k,0) );
        }
        else
        {
            for ( index_t k=0; k<sz; ++k)
                this->matchDof( k1, b1(k,0), k2, b2(sz-k-1,0) );
        }
    }
    else
        for ( index_t k=0; k<sz; ++k)
            this->matchDof( k1, b1(k,0), k2, b2(k,0) );
}

void gsDofMapper::colapseDofs(index_t k, const gsMatrix<unsigned> & b )
{
    const index_t last = b.size()-1;
    for ( index_t k=0; k<last; ++k)
    {
        this->matchDof( k, b(k,0), k, b(k+1,0) );
    }
}

void gsDofMapper::matchDof( index_t u, index_t i, index_t v, index_t j )
{
    index_t d1 = MAPPER_PATCH_DOF(i,u);
    index_t d2 = MAPPER_PATCH_DOF(j,v);

    // make sure that d1 <= d2, simplifies implementation
    if (d1 > d2)
    {
        std::swap(d1, d2);
        std::swap(u, v);
        std::swap(i, j);
    }

    if (d1 < 0)         // first dof is eliminated
    {
        if (d2 < 0)         mergeDofsGlobally( d1, d2 );        // both are eliminated, merge their indices
        else if (d2 == 0)   MAPPER_PATCH_DOF(j,v) = d1;             // second is free, eliminate it along with first
        else /* d2 > 0*/    replaceDofGlobally( d2, d1 );       // second is coupling, eliminate all instances of it
    }
    else if (d1 == 0)   // first dof is a free dof
    {
        if (d2 == 0)        MAPPER_PATCH_DOF(i,u) = MAPPER_PATCH_DOF(j,v) = m_curCouplingId++;  // both are free, assign them a new coupling id
        else if (d2 > 0)    MAPPER_PATCH_DOF(i,u) = d2;             // second is coupling, add first to the same coupling group
        else                GISMO_ERROR("Something went terribly wrong");
    }
    else /* d1 > 0 */   // first dof is a coupling dof
    {
        GISMO_ASSERT(d2 > 0, "Something went terribly wrong");
        mergeDofsGlobally( d1, d2 );                            // both are coupling dofs, merge them
    }

    // if we merged two different non-eliminated dofs, we lost one free dof
    if ( (d1 != d2 && (d1 >= 0 || d2 >= 0) ) || (d1 == 0 && d2 == 0) )
        --m_numFreeDofs;
}

void gsDofMapper::markBoundary( index_t k, const gsMatrix<unsigned> & boundaryDofs )
{
    for (index_t i = 0; i < boundaryDofs.rows(); ++i)
    {
        eliminateDof( boundaryDofs(i,0), k );
    }

    // TO DO: save inverse, eg boundaryDofs(i,0)
}

void gsDofMapper::eliminateDof( index_t i, index_t k )
{
    const index_t old = MAPPER_PATCH_DOF(i,k);
    if (old == 0)       // regular free dof
    {
        --m_numFreeDofs;
        MAPPER_PATCH_DOF(i,k) = m_curElimId--;
    }
    else if (old > 0)   // coupling dof
    {
        --m_numFreeDofs;
        replaceDofGlobally( old, m_curElimId-- );
    }
    // else: old < 0: already an eliminated dof, nothing to do
}

void gsDofMapper::finalize()
{
    GISMO_ASSERT(m_curElimId!=0, "Error in gsDofMapper::finalize() called twince.");

    index_t curFreeDof = 0;                 // free dofs start at 0
    index_t curElimDof = m_numFreeDofs;     // eliminated dofs start after free dofs
    std::vector<index_t> couplingDofs(m_curCouplingId - 1, -1);
    std::vector<index_t> elimDofs(-m_curElimId - 1, -1);

    // Coupled dofs start after standard dofs
    index_t curCplDof = m_numFreeDofs - couplingDofs.size();

    for (std::size_t k = 0; k < m_dofs.size(); ++k)
    {
        const index_t dofType = m_dofs[k];

        if (dofType == 0)       // standard dof
            m_dofs[k] = curFreeDof++;
        else if (dofType < 0)   // eliminated dof
        {
            const index_t id = -dofType - 1;
            if (elimDofs[id] < 0)
                elimDofs[id] = curElimDof++;
            m_dofs[k] = elimDofs[id];
        }
        else // dofType > 0     // coupling dof
        {
            const index_t id = dofType - 1;
            if (couplingDofs[id] < 0)
                //couplingDofs[id] = curFreeDof++;
                couplingDofs[id] =   curCplDof++;
            m_dofs[k] = couplingDofs[id];
        }
    }
    m_numElimDofs = curElimDof - m_numFreeDofs;

    GISMO_ASSERT(curCplDof == m_numFreeDofs,
                 "gsDofMapper::finalize() - computed number of coupling dofs does not match allocated number");
    GISMO_ASSERT(curFreeDof + static_cast<index_t>(couplingDofs.size()) == m_numFreeDofs,
                 "gsDofMapper::finalize() - computed number of free dofs does not match allocated number");

    m_curElimId = 0;// Only equal to zero after finalize is called.

}

void gsDofMapper::print() const
{
    gsInfo<<"Dofs: "<< this->size() <<"\n";
    gsInfo<<" free: "<< this->freeSize() <<"\n";
    gsInfo<<" elim: "<< this->boundarySize() <<"\n";
}

void gsDofMapper::setIdentity(index_t nPatches, size_t nDofs)
{
    m_curElimId     = -1;
    m_curCouplingId =  1;
    m_numFreeDofs = nDofs;

    // Initialize all offsets to zero
    m_offset.resize(nPatches, 0);

    m_dofs.resize( m_numFreeDofs, 0);

    finalize();
}

void gsDofMapper::initPatchDofs(const gsVector<index_t> & patchDofSizes)
{
    m_curElimId     = -1;
    m_curCouplingId =  1;

    const size_t nPatches = patchDofSizes.size();

    // Initialize offsets and dof holder
    m_offset.reserve( nPatches );
    m_offset.push_back(0);
    for (size_t k = 1; k < nPatches; ++k)
    {
        m_offset.push_back( m_offset.back() + patchDofSizes[k-1] );
    }

    m_numFreeDofs = m_offset.back() + patchDofSizes[nPatches-1];

    m_dofs.resize( m_numFreeDofs, 0);
}

void gsDofMapper::replaceDofGlobally(index_t oldIdx, index_t newIdx)
{
    std::replace( m_dofs.begin(), m_dofs.end(), oldIdx, newIdx );
}

void gsDofMapper::mergeDofsGlobally(index_t dof1, index_t dof2)
{
    if (dof1 != dof2)
    {
        // replace the larger by the smaller for more consistent numbering.
        if (dof1 < dof2)
            std::swap(dof1, dof2);

        replaceDofGlobally(dof1, dof2);
    }
}

index_t gsDofMapper::coupledSize() const
{
    // Property: coupled (eliminated or not) DoFs appear more than once in the mapping.
    GISMO_ENSURE(m_curElimId==0, "finalize() was not called on gsDofMapper");

    std::vector<index_t> CountMap(m_numFreeDofs,0);

    // Count number of appearances of each free DoF
    for (std::vector<index_t>::const_iterator it = m_dofs.begin(); it != m_dofs.end(); ++it)
        if ( *it < m_numFreeDofs )
            CountMap[*it]++;

    // Count the number of freeDoFs that appear more than once
    return std::count_if( CountMap.begin(), CountMap.end(), std::bind2nd(std::greater<index_t>(), 1) );
    /* // Equivalent implementation
    index_t count = 0;
    for (std::vector<index_t>::const_iterator it = CountMap.begin(); it != CountMap.end(); ++it)
        if ( *it > 1 )
            count++;
    return count;
    */
}

void gsDofMapper::setShift (index_t shift)
{
    m_shift=shift;
}

} // namespace gismo

<|endoftext|>


<commit_before>/** @file gsFileManager.cpp

    @brief Utility class for finding files and handling paths

    This file is part of the G+Smo library.

    This Source Code Form is subject to the terms of the Mozilla Public
    License, v. 2.0. If a copy of the MPL was not distributed with this
    file, You can obtain one at http://mozilla.org/MPL/2.0/.

    Author(s): S. Takacs
*/

#include <gsIO/gsFileManager.h>
#include <iostream>
#include <fstream>
#include <gsCore/gsConfig.h>
#include <gsUtils/gsUtils.h>

namespace gismo
{

class gsFileManagerData;

// Use a singleton to store data:
class GISMO_EXPORT gsFileManagerData
{
public:

    friend gsFileManagerData& gsFileManagerDataSingleton();
    friend class gsFileManager;

    void setSearchPaths(const std::string& paths);

private:
    gsFileManagerData()
    {
#ifdef GISMO_SEARCH_PATHS
        setSearchPaths("" GISMO_SEARCH_PATHS);
#endif
    }

    gsFileManagerData(const gsFileManagerData&);
    gsFileManagerData& operator= (const gsFileManagerData&);
    std::vector<std::string> m_paths;
};

gsFileManagerData& gsFileManagerDataSingleton()
{
    static gsFileManagerData singleton;
    return singleton;
}

bool gsFileManager::fileExists(const std::string& name)
{
    std::ifstream f(name.c_str());
    return f.good();
}

char gsFileManager::getLocalPathSeperator()
{
#if defined _WIN32
    return '\\';
#else
    return '/';
#endif
}

bool gsFileManager::isFullyQualified(const std::string& fn)
{
#if defined _WIN32
    return util::starts_with(fn,"/")
        || util::starts_with(fn,"\\")
        || ( fn.size() > 2 && fn[1] == ':' && ( fn[2] == '/' || fn[2] == '\\' ) );
#else
    return util::starts_with(fn,"/");
#endif
}

bool gsFileManager::isRelative(const std::string& fn)
{
#if defined _WIN32
    return util::starts_with(fn,"./")
        || util::starts_with(fn,".\\")
        || util::starts_with(fn,"../")
        || util::starts_with(fn,"..\\");
#else
    return util::starts_with(fn,"./")
        || util::starts_with(fn,"../");
#endif
}

void _replace_slash_by_basckslash(std::string& str)
{
    for ( std::string::iterator it=str.begin(); it!=str.end(); it++ )
        if ( *it=='/' ) *it = '\\';
}

void gsFileManager::setSearchPaths(const std::string& paths)
{
    gsFileManagerDataSingleton().setSearchPaths(paths);
}

void gsFileManagerData::setSearchPaths(const std::string& paths)
{
    m_paths.clear();

    std::string::const_iterator a;
    std::string::const_iterator b = paths.begin();
    while (true)
    {
        a = b;
        while (b != paths.end() && (*b) != ';') { ++b; }

        std::string p(a,b);

#if defined _WIN32
        _replace_slash_by_basckslash(p);
#endif

        if (!p.empty())
        {
#if defined _WIN32
            if (*p.rbegin() != '\\')
                p.push_back('\\');
#else
            if (*p.rbegin() != '/')
                p.push_back('/');
#endif

            m_paths.push_back(p);
        }

        if ( b == paths.end() ) break;

        ++b;
    }
}

std::string gsFileManager::getSearchPaths()
{
    std::string result;
    gsFileManagerData& dat = gsFileManagerDataSingleton();
    for (std::vector<std::string>::const_iterator it = dat.m_paths.begin();
            it < dat.m_paths.end(); ++it)
    {
        result += (*it) + ";";
    }
    return result;
}

bool gsFileManager::find( std::string& fn )
{
#if defined _WIN32
        _replace_slash_by_basckslash(p);
#endif

    if ( fileExists(fn) ) return true;

    if ( isFullyQualified(fn) || isRelative(fn) ) return false;

    gsFileManagerData& dat = gsFileManagerDataSingleton();

    for (std::vector<std::string>::const_iterator it = dat.m_paths.begin();
            it < dat.m_paths.end(); ++it)
    {
        const std::string tmp = (*it) + fn;
        if ( fileExists( tmp ) )
        {
            fn = tmp;
            return true;
        }
    }

    return false;
}

} //namespace gismo

<commit_msg><commit_after>/** @file gsFileManager.cpp

    @brief Utility class for finding files and handling paths

    This file is part of the G+Smo library.

    This Source Code Form is subject to the terms of the Mozilla Public
    License, v. 2.0. If a copy of the MPL was not distributed with this
    file, You can obtain one at http://mozilla.org/MPL/2.0/.

    Author(s): S. Takacs
*/

#include <gsIO/gsFileManager.h>
#include <iostream>
#include <fstream>
#include <gsCore/gsConfig.h>
#include <gsUtils/gsUtils.h>

namespace gismo
{

class gsFileManagerData;

// Use a singleton to store data:
class GISMO_EXPORT gsFileManagerData
{
public:

    friend gsFileManagerData& gsFileManagerDataSingleton();
    friend class gsFileManager;

    void setSearchPaths(const std::string& paths);

private:
    gsFileManagerData()
    {
#ifdef GISMO_SEARCH_PATHS
        setSearchPaths("" GISMO_SEARCH_PATHS);
#endif
    }

    gsFileManagerData(const gsFileManagerData&);
    gsFileManagerData& operator= (const gsFileManagerData&);
    std::vector<std::string> m_paths;
};

gsFileManagerData& gsFileManagerDataSingleton()
{
    static gsFileManagerData singleton;
    return singleton;
}

bool gsFileManager::fileExists(const std::string& name)
{
    std::ifstream f(name.c_str());
    return f.good();
}

char gsFileManager::getLocalPathSeperator()
{
#if defined _WIN32
    return '\\';
#else
    return '/';
#endif
}

bool gsFileManager::isFullyQualified(const std::string& fn)
{
#if defined _WIN32
    return util::starts_with(fn,"/")
        || util::starts_with(fn,"\\")
        || ( fn.size() > 2 && fn[1] == ':' && ( fn[2] == '/' || fn[2] == '\\' ) );
#else
    return util::starts_with(fn,"/");
#endif
}

bool gsFileManager::isRelative(const std::string& fn)
{
#if defined _WIN32
    return util::starts_with(fn,"./")
        || util::starts_with(fn,".\\")
        || util::starts_with(fn,"../")
        || util::starts_with(fn,"..\\");
#else
    return util::starts_with(fn,"./")
        || util::starts_with(fn,"../");
#endif
}

void _replace_slash_by_basckslash(std::string& str)
{
    for ( std::string::iterator it=str.begin(); it!=str.end(); it++ )
        if ( *it=='/' ) *it = '\\';
}

void gsFileManager::setSearchPaths(const std::string& paths)
{
    gsFileManagerDataSingleton().setSearchPaths(paths);
}

void gsFileManagerData::setSearchPaths(const std::string& paths)
{
    m_paths.clear();

    std::string::const_iterator a;
    std::string::const_iterator b = paths.begin();
    while (true)
    {
        a = b;
        while (b != paths.end() && (*b) != ';') { ++b; }

        std::string p(a,b);

#if defined _WIN32
        _replace_slash_by_basckslash(p);
#endif

        if (!p.empty())
        {
#if defined _WIN32
            if (*p.rbegin() != '\\')
                p.push_back('\\');
#else
            if (*p.rbegin() != '/')
                p.push_back('/');
#endif

            m_paths.push_back(p);
        }

        if ( b == paths.end() ) break;

        ++b;
    }
}

std::string gsFileManager::getSearchPaths()
{
    std::string result;
    gsFileManagerData& dat = gsFileManagerDataSingleton();
    for (std::vector<std::string>::const_iterator it = dat.m_paths.begin();
            it < dat.m_paths.end(); ++it)
    {
        result += (*it) + ";";
    }
    return result;
}

bool gsFileManager::find( std::string& fn )
{
#if defined _WIN32
        _replace_slash_by_basckslash(fn);
#endif

    if ( fileExists(fn) ) return true;

    if ( isFullyQualified(fn) || isRelative(fn) ) return false;

    gsFileManagerData& dat = gsFileManagerDataSingleton();

    for (std::vector<std::string>::const_iterator it = dat.m_paths.begin();
            it < dat.m_paths.end(); ++it)
    {
        const std::string tmp = (*it) + fn;
        if ( fileExists( tmp ) )
        {
            fn = tmp;
            return true;
        }
    }

    return false;
}

} //namespace gismo

<|endoftext|>


<commit_before>/* -*- mode: C++; c-basic-offset: 4; tab-width: 8; -*-
 * vi: set shiftwidth=4 tabstop=8:
 * :indentSize=4:tabSize=8:
 */
#include "file_index.h"
#include "error.h"
#include "event.h"
#include <cassert>
#include <sysexits.h>

file_index::file_index(const std::string& filename) :
    file_(filename),
    has_parsed_all_(false)
{
    if (file_.empty()) {
	throw error("could not memory map: " + filename, EX_NOINPUT);
    }

    // we start counting lines with number 1. So add an invalid pointer to index 0.
    line_.push_back(line_t(nullptr, nullptr, nullptr, 0));
}

bool
file_index::parse_line(const line_number_t num_)
{
    if (file_.empty()) {
	has_parsed_all_ = true;
	return false;
    }

    if (num_ <= size()) {
	return true;
    }

    line_number_t num = 0;
    const c_t* it = nullptr;
    if (num_ > 1 && size() > 0) {
	line_t current_line = line_[size()];
	it = current_line.next_;
	num = current_line.num_;
    } else {
	it = file_.begin();
    }

    const c_t* const end = file_.end();
    if (it == end) {
	return false;
    }
    if (it == nullptr) {
	return false;
    }

    assert(it);
    const c_t* beg = it;
    while(num < num_) {
	if (*it == '\n') {
	    const c_t* next = it + 1;
	    push_line(beg, it, next, ++num);
	    beg = next;
	}
	++it;
	if (it == end) {
	    if (it != beg) {
		push_line(beg, it, nullptr, ++num);
	    }
	    has_parsed_all_ = true;
	    break;
	}
    }

    return num == num_;
}

void
file_index::push_line(const c_t* beg, const c_t* end, const c_t* next, const line_number_t num)
{
    while(beg < end) {
	if (*(end - 1) == '\n') {
	    --end;
	    continue;
	}
	if (*(end - 1) == '\r') {
	    --end;
	    continue;
	}
	break;
    }
    line_.push_back(line_t(beg, end, next, num));
}

line_t file_index::line(const line_number_t num)
{
    if (num > size()) {
	if (! parse_line(num)) {
	    throw std::runtime_error("file_index::line(" + std::to_string(num) + "): number too large, file only contains " + std::to_string(size()));
	}
    }
    line_t l = line_[num];
    assert(l.num_ == num);
    return l;
}

lineNum_vector_t
file_index::lineNum_vector()
{
    const line_number_t s = size();
    lineNum_vector_t v(s);
    for(line_number_t i = 0; i < s; ++i) {
	v[i] = i + 1;
    }
    return v;
}

void
file_index::parse_all(regex_index_vec_t& regex_index_vec, ProgressFunctor *func)
{
    for(line_number_t num = 1; true; ++num) {
	if (num > size()) {
	    if (! parse_line(num)) {
		break;
	    }
	}

	const line_t& line = line_[num];
	for(auto ri : regex_index_vec) {
	    ri->match(line);
	}

	if (func && (num % 10000) == 0) {
	    const uint64_t pos = line.end_ - line_[1].beg_;
	    func->progress(num, static_cast<unsigned>(pos * 100llu / file_.size()));
	}
    }
}

void
file_index::parse_all(std::shared_ptr<regex_index> ri, ProgressFunctor *func)
{
    regex_index_vec_t v = { ri };
    parse_all(v, func);
}

void
file_index::parse_all()
{
    regex_index_vec_t v;
    parse_all(v);
}

unsigned
file_index::perc(const line_number_t num)
{
    const line_number_t s = size();
    if (num > s) { return 100u; }
    return static_cast<uint64_t>(num) * 100llu / s;
}

void
file_index::parse_all_in_background(std::shared_ptr<regex_index> ri) const
{
    if (! has_parsed_all_) {
	return;
    }
    for(unsigned i = 1; i < line_.size(); ++i) {
	ri->match(line_[i]);
	if ((i % 10000) == 0) {
	    eventAdd(event("matching line " + std::to_string(i)));
	}
    }
}
<commit_msg>print percentage when matching filter regex<commit_after>/* -*- mode: C++; c-basic-offset: 4; tab-width: 8; -*-
 * vi: set shiftwidth=4 tabstop=8:
 * :indentSize=4:tabSize=8:
 */
#include "file_index.h"
#include "error.h"
#include "event.h"
#include <cassert>
#include <sysexits.h>

file_index::file_index(const std::string& filename) :
    file_(filename),
    has_parsed_all_(false)
{
    if (file_.empty()) {
	throw error("could not memory map: " + filename, EX_NOINPUT);
    }

    // we start counting lines with number 1. So add an invalid pointer to index 0.
    line_.push_back(line_t(nullptr, nullptr, nullptr, 0));
}

bool
file_index::parse_line(const line_number_t num_)
{
    if (file_.empty()) {
	has_parsed_all_ = true;
	return false;
    }

    if (num_ <= size()) {
	return true;
    }

    line_number_t num = 0;
    const c_t* it = nullptr;
    if (num_ > 1 && size() > 0) {
	line_t current_line = line_[size()];
	it = current_line.next_;
	num = current_line.num_;
    } else {
	it = file_.begin();
    }

    const c_t* const end = file_.end();
    if (it == end) {
	return false;
    }
    if (it == nullptr) {
	return false;
    }

    assert(it);
    const c_t* beg = it;
    while(num < num_) {
	if (*it == '\n') {
	    const c_t* next = it + 1;
	    push_line(beg, it, next, ++num);
	    beg = next;
	}
	++it;
	if (it == end) {
	    if (it != beg) {
		push_line(beg, it, nullptr, ++num);
	    }
	    has_parsed_all_ = true;
	    break;
	}
    }

    return num == num_;
}

void
file_index::push_line(const c_t* beg, const c_t* end, const c_t* next, const line_number_t num)
{
    while(beg < end) {
	if (*(end - 1) == '\n') {
	    --end;
	    continue;
	}
	if (*(end - 1) == '\r') {
	    --end;
	    continue;
	}
	break;
    }
    line_.push_back(line_t(beg, end, next, num));
}

line_t file_index::line(const line_number_t num)
{
    if (num > size()) {
	if (! parse_line(num)) {
	    throw std::runtime_error("file_index::line(" + std::to_string(num) + "): number too large, file only contains " + std::to_string(size()));
	}
    }
    line_t l = line_[num];
    assert(l.num_ == num);
    return l;
}

lineNum_vector_t
file_index::lineNum_vector()
{
    const line_number_t s = size();
    lineNum_vector_t v(s);
    for(line_number_t i = 0; i < s; ++i) {
	v[i] = i + 1;
    }
    return v;
}

void
file_index::parse_all(regex_index_vec_t& regex_index_vec, ProgressFunctor *func)
{
    for(line_number_t num = 1; true; ++num) {
	if (num > size()) {
	    if (! parse_line(num)) {
		break;
	    }
	}

	const line_t& line = line_[num];
	for(auto ri : regex_index_vec) {
	    ri->match(line);
	}

	if (func && (num % 10000) == 0) {
	    const uint64_t pos = line.end_ - line_[1].beg_;
	    func->progress(num, static_cast<unsigned>(pos * 100llu / file_.size()));
	}
    }
}

void
file_index::parse_all(std::shared_ptr<regex_index> ri, ProgressFunctor *func)
{
    regex_index_vec_t v = { ri };
    parse_all(v, func);
}

void
file_index::parse_all()
{
    regex_index_vec_t v;
    parse_all(v);
}

unsigned
file_index::perc(const line_number_t num)
{
    const line_number_t s = size();
    if (num > s) { return 100u; }
    return static_cast<uint64_t>(num) * 100llu / s;
}

void
file_index::parse_all_in_background(std::shared_ptr<regex_index> ri) const
{
    if (! has_parsed_all_) {
	return;
    }
    const unsigned line_size = line_.size();
    for(unsigned i = 1; i < line_size; ++i) {
	ri->match(line_[i]);
	if ((i % 10000) == 0) {
	    const unsigned perc = static_cast<double>(i) / static_cast<double>(line_size) * 100.0;
	    eventAdd(event(" matching line " + std::to_string(i) + " " + std::to_string(perc) + "% "));
	}
    }
}
<|endoftext|>


<commit_before>#pragma once

#include <algorithm>
#include <cassert>

namespace math {
	template<unsigned int _n, unsigned int _m, typename _Type>
	struct Determinant {};

	template<unsigned int _n, unsigned int _m = _n, typename _Type = double>
	struct mat {
		_Type m_a[_m][_n];

		mat() {}

		mat(_Type const (&a_a)[_m][_n])
			:
		m_a(a_a) {}

		mat(_Type (&&a_a)[_m][_n])
			:
		m_a(move(a_a)) {}

		struct row {
			_Type (&m_ra)[_m][_n];
			unsigned int m_i;

			row(_Type (&a_ra)[_m][_n], unsigned int a_i)
				:
			m_ra(a_ra),
				m_i(a_i) {}

			inline _Type &operator [] (unsigned int j) {
				assert(j < _m);
				return m_ra[j][m_i];
			}
		};

		struct const_row {
			_Type const (&m_ra)[_m][_n];
			unsigned int m_i;

			const_row(_Type const (&a_ra)[_m][_n], unsigned int a_i)
				:
			m_ra(a_ra),
				m_i(a_i) {}

			inline _Type const &operator [] (unsigned int j) const {
				assert(j < _m);
				return m_ra[j][m_i];
			}
		};

		inline row operator [] (unsigned int i) {
			assert(i < _n);
			return row(m_a, i);
		}

		inline const_row operator [] (unsigned int i) const {
			assert(i < _n);
			return const_row(m_a, i);
		}

		mat<_m, _n, _Type> transpose() const {
			mat<_m, _n, _Type> Result;
			for(unsigned int i = 0; i < _n; ++i) {
				for(unsigned int j = 0; j < _m; ++j) {
					Result[j][i] = m_a[j][i];
				}
			}
			return Result;
		}

		inline _Type determinant() const {
			return Determinant<_n, _m, _Type>::Compute(*this);
		}

		mat<_n, _m, _Type> operator + (mat<_n, _m, _Type> const &r) const {
			mat<_n, _m, _Type> Result;
			for (unsigned int i = 0; i < _n; ++i) {
				for (unsigned int j = 0; j < _m; ++j) {
					Result[i][j] += m_a[j][i] + r[i][j];
				}
			}
			return Result;
		}

		mat<_n, _m, _Type> &operator += (mat<_n, _m, _Type> const &r) {
			for (unsigned int i = 0; i < _n; ++i) {
				for (unsigned int j = 0; j < _m; ++j) {
					m_a[j][i] += r[i][j];
				}
			}
			return *this;
		}

		mat<_n, _m, _Type> operator - (mat<_n, _m, _Type> const &r) const {
			mat<_n, _m, _Type> Result;
			for (unsigned int i = 0; i < _n; ++i) {
				for (unsigned int j = 0; j < _m; ++j) {
					Result[i][j] += m_a[j][i] + r[i][j];
				}
			}
			return Result;
		}

		mat<_n, _m, _Type> &operator -= (mat<_n, _m, _Type> const &r) {
			for (unsigned int i = 0; i < _n; ++i) {
				for (unsigned int j = 0; j < _m; ++j) {
					m_a[j][i] -= r[i][j];
				}
			}
			return *this;
		}

		mat<_n, _m, _Type> operator * (_Type const &r) const {
			mat<_n, _m, _Type> Result;
			for (unsigned int i = 0; i < _n; ++i) {
				for (unsigned int j = 0; j < _m; ++j) {
					Result[i][j] = m_a[j][i] * r;
				}
			}
			return Result;
		}

		mat<_n, _m, _Type> &operator *= (_Type const &r) {
			for (unsigned int i = 0; i < _n; ++i) {
				for (unsigned int j = 0; j < _m; ++j) {
					m_a[j][i] *= r;
				}
			}
			return *this;
		}

		mat<_n, _m, _Type> operator / (_Type const &r) const {
			mat<_n, _m, _Type> Result;
			for (unsigned int i = 0; i < _n; ++i) {
				for (unsigned int j = 0; j < _m; ++j) {
					Result[i][j] = m_a[j][i] / r;
				}
			}
			return Result;
		}

		mat<_n, _m, _Type> &operator /= (_Type const &r) {
			for (unsigned int i = 0; i < _n; ++i) {
				for (unsigned int j = 0; j < _m; ++j) {
					m_a[j][i] /= r;
				}
			}
			return *this;
		}

		template<unsigned int _l>
		mat<_n, _l, _Type> operator * (mat<_m, _l, _Type> const &r) const {
			mat<_n, _l, _Type> Result;
			for (unsigned int i = 0; i < _n; ++i) {
				for (unsigned int j = 0; j < _l; ++j) {
					for (unsigned int k = 0; k < _m; ++k) {
						Result[i][j] += m_a[k][i] * r[k][j];
					}
				}
			}
			return Result;
		}
	};

	template<unsigned int _n, typename _Type>
	struct Determinant<_n, _n, _Type> {
		static _Type Compute(mat<_n, _n, _Type> const &r) {
			_Type d(0);
			int n = 1;
			for (unsigned int j = 0; j < _n; ++j) {
				// TODO
				n = -n;
			}
			return d;
		}
	};

	typedef mat<2, 2> mat22, mat2;
	typedef mat<2, 3> mat23;
	typedef mat<2, 4> mat24;
	typedef mat<3, 2> mat32;
	typedef mat<3, 3> mat33, mat3;
	typedef mat<3, 4> mat34;
	typedef mat<4, 2> mat42;
	typedef mat<4, 3> mat43;
	typedef mat<4, 4> mat44, mat4;

	template<unsigned int _n, typename _Type = double>
	struct vec : public mat<_n, 1, _Type> {};

	typedef vec<2> vec2;
	typedef vec<3> vec3;
	typedef vec<4> vec4;
}
<commit_msg>Optimized determinants<commit_after>#pragma once

#include <algorithm>
#include <cassert>

namespace math {
	template<unsigned int _n, unsigned int _m, typename _Type>
	struct Determinant {};

	template<unsigned int _n, unsigned int _m = _n, typename _Type = double>
	struct mat {
		_Type m_a[_m][_n];

		mat() {}

		mat(_Type const (&a_a)[_m][_n])
			:
		m_a(a_a) {}

		mat(_Type (&&a_a)[_m][_n])
			:
		m_a(move(a_a)) {}

		struct row {
			_Type (&m_ra)[_m][_n];
			unsigned int m_i;

			inline row(_Type (&a_ra)[_m][_n], unsigned int a_i)
				:
			m_ra(a_ra),
				m_i(a_i) {}

			inline _Type &operator [] (unsigned int j) {
				assert(j < _m);
				return m_ra[j][m_i];
			}
		};

		struct const_row {
			_Type const (&m_ra)[_m][_n];
			unsigned int m_i;

			inline const_row(_Type const (&a_ra)[_m][_n], unsigned int a_i)
				:
			m_ra(a_ra),
				m_i(a_i) {}

			inline _Type const &operator [] (unsigned int j) const {
				assert(j < _m);
				return m_ra[j][m_i];
			}
		};

		inline row operator [] (unsigned int i) {
			assert(i < _n);
			return row(m_a, i);
		}

		inline const_row operator [] (unsigned int i) const {
			assert(i < _n);
			return const_row(m_a, i);
		}

		mat<_m, _n, _Type> transpose() const {
			mat<_m, _n, _Type> Result;
			for(unsigned int i = 0; i < _n; ++i) {
				for(unsigned int j = 0; j < _m; ++j) {
					Result[j][i] = m_a[j][i];
				}
			}
			return Result;
		}

		inline _Type det() const {
			return Determinant<_n, _m, _Type>::Compute(*this);
		}

		mat<_n, _m, _Type> operator + (mat<_n, _m, _Type> const &r) const {
			mat<_n, _m, _Type> Result;
			for (unsigned int i = 0; i < _n; ++i) {
				for (unsigned int j = 0; j < _m; ++j) {
					Result[i][j] += m_a[j][i] + r[i][j];
				}
			}
			return Result;
		}

		mat<_n, _m, _Type> &operator += (mat<_n, _m, _Type> const &r) {
			for (unsigned int i = 0; i < _n; ++i) {
				for (unsigned int j = 0; j < _m; ++j) {
					m_a[j][i] += r[i][j];
				}
			}
			return *this;
		}

		mat<_n, _m, _Type> operator - (mat<_n, _m, _Type> const &r) const {
			mat<_n, _m, _Type> Result;
			for (unsigned int i = 0; i < _n; ++i) {
				for (unsigned int j = 0; j < _m; ++j) {
					Result[i][j] += m_a[j][i] + r[i][j];
				}
			}
			return Result;
		}

		mat<_n, _m, _Type> &operator -= (mat<_n, _m, _Type> const &r) {
			for (unsigned int i = 0; i < _n; ++i) {
				for (unsigned int j = 0; j < _m; ++j) {
					m_a[j][i] -= r[i][j];
				}
			}
			return *this;
		}

		mat<_n, _m, _Type> operator * (_Type const &r) const {
			mat<_n, _m, _Type> Result;
			for (unsigned int i = 0; i < _n; ++i) {
				for (unsigned int j = 0; j < _m; ++j) {
					Result[i][j] = m_a[j][i] * r;
				}
			}
			return Result;
		}

		mat<_n, _m, _Type> &operator *= (_Type const &r) {
			for (unsigned int i = 0; i < _n; ++i) {
				for (unsigned int j = 0; j < _m; ++j) {
					m_a[j][i] *= r;
				}
			}
			return *this;
		}

		mat<_n, _m, _Type> operator / (_Type const &r) const {
			mat<_n, _m, _Type> Result;
			for (unsigned int i = 0; i < _n; ++i) {
				for (unsigned int j = 0; j < _m; ++j) {
					Result[i][j] = m_a[j][i] / r;
				}
			}
			return Result;
		}

		mat<_n, _m, _Type> &operator /= (_Type const &r) {
			for (unsigned int i = 0; i < _n; ++i) {
				for (unsigned int j = 0; j < _m; ++j) {
					m_a[j][i] /= r;
				}
			}
			return *this;
		}

		template<unsigned int _l>
		mat<_n, _l, _Type> operator * (mat<_m, _l, _Type> const &r) const {
			mat<_n, _l, _Type> Result;
			for (unsigned int i = 0; i < _n; ++i) {
				for (unsigned int j = 0; j < _l; ++j) {
					for (unsigned int k = 0; k < _m; ++k) {
						Result[i][j] += m_a[k][i] * r[k][j];
					}
				}
			}
			return Result;
		}
	};

	template<typename _Type>
	struct Determinant<1, 1, _Type> {
		static inline _Type Compute(mat<1, 1, _Type> const &r) {
			return r.m_a[0][0];
		}
	};

	template<typename _Type>
	struct Determinant<2, 2, _Type> {
		static inline _Type Compute(mat<2, 2, _Type> const &r) {
			return r.m_a[0][0] * r.m_a[1][1] - r.m_a[0][1] * r.m_a[1][0];
		}
	};

	template<typename _Type>
	struct Determinant<3, 3, _Type> {
		static inline _Type Compute(mat<3, 3, _Type> const &r) {
			return
				r.m_a[0][0] * (r.m_a[1][1] * r.m_a[2][2] - r.m_a[1][2] * r.m_a[2][1]) -
				r.m_a[1][0] * (r.m_a[0][1] * r.m_a[2][2] - r.m_a[0][2] * r.m_a[2][1]) +
				r.m_a[2][0] * (r.m_a[0][1] * r.m_a[1][2] - r.m_a[0][2] * r.m_a[1][1]);
		}
	};

	template<typename _Type>
	struct Determinant<4, 4, _Type> {
		static inline _Type Compute(mat<4, 4, _Type> const &r) {
			return
				r.m_a[0][0] * (r.m_a[1][1] * (r.m_a[2][2] * r.m_a[3][3] - r.m_a[2][3] * r.m_a[3][2]) -
				               r.m_a[1][2] * (r.m_a[2][1] * r.m_a[3][3] - r.m_a[2][3] * r.m_a[3][1]) +
				               r.m_a[1][3] * (r.m_a[2][1] * r.m_a[3][2] - r.m_a[2][2] * r.m_a[3][1])) -
				r.m_a[0][1] * (r.m_a[1][0] * (r.m_a[2][2] * r.m_a[3][3] - r.m_a[2][3] * r.m_a[3][2]) -
				               r.m_a[1][2] * (r.m_a[2][0] * r.m_a[3][3] - r.m_a[2][3] * r.m_a[3][0]) +
				               r.m_a[1][3] * (r.m_a[2][0] * r.m_a[3][2] - r.m_a[2][2] * r.m_a[3][0])) +
				r.m_a[0][2] * (r.m_a[1][0] * (r.m_a[2][1] * r.m_a[3][3] - r.m_a[2][3] * r.m_a[3][1]) -
				               r.m_a[1][1] * (r.m_a[2][0] * r.m_a[3][3] - r.m_a[2][3] * r.m_a[3][0]) +
				               r.m_a[1][3] * (r.m_a[2][0] * r.m_a[3][1] - r.m_a[2][1] * r.m_a[3][0])) -
				r.m_a[0][3] * (r.m_a[1][0] * (r.m_a[2][1] * r.m_a[3][2] - r.m_a[2][2] * r.m_a[3][1]) -
				               r.m_a[1][1] * (r.m_a[2][0] * r.m_a[3][2] - r.m_a[2][2] * r.m_a[3][0]) +
				               r.m_a[1][2] * (r.m_a[2][0] * r.m_a[3][1] - r.m_a[2][1] * r.m_a[3][0]));
		}
	};

	template<unsigned int _n, typename _Type>
	struct Determinant<_n, _n, _Type> {
		static _Type Compute(mat<_n, _n, _Type> const &r) {
			_Type d(0);
			int n = 1;
			for (unsigned int j = 0; j < _n; ++j) {
				// TODO
				n = -n;
			}
			return d;
		}
	};

	typedef mat<2, 2> mat22, mat2;
	typedef mat<2, 3> mat23;
	typedef mat<2, 4> mat24;
	typedef mat<3, 2> mat32;
	typedef mat<3, 3> mat33, mat3;
	typedef mat<3, 4> mat34;
	typedef mat<4, 2> mat42;
	typedef mat<4, 3> mat43;
	typedef mat<4, 4> mat44, mat4;

	template<unsigned int _n, typename _Type = double>
	struct vec : public mat<_n, 1, _Type> {};

	typedef vec<2> vec2;
	typedef vec<3> vec3;
	typedef vec<4> vec4;
}
<|endoftext|>


<commit_before>/******************************************************************************
* Copyright (c) 2015, Hobu Inc., hobu@hobu.co
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in
*       the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
*       names of its contributors may be used to endorse or promote
*       products derived from this software without specific prior
*       written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#include <pdal/pdal_internal.hpp>

#include <zlib.h>

#include <pdal/Options.hpp>

#include "BpfWriter.hpp"

namespace pdal
{

void BpfWriter::processOptions(const Options&)
{
    if (m_filename.empty())
        throw pdal_error("Can't write BPF file without filename.");
}

void BpfWriter::ready(PointContextRef ctx)
{
    Dimension::IdList dims = ctx.dims();
    for (auto id : dims)
    {
        BpfDimension dim;
        dim.m_id = id;
        dim.m_label = ctx.dimName(id);
        m_dims.push_back(dim);
    }

    m_stream = FileUtils::createFile(m_filename, true);
    m_header.m_version = 3;
    m_header.m_numDim = dims.size();
    //ABELL - For now.
    m_header.m_pointFormat = BpfFormat::PointMajor;
    m_header.m_coordType = BpfCoordType::None;
    m_header.m_coordId = 0;
    m_header.setLog(log());

    // We will re-write the header and dimensions to account for the point
    // count and dimension min/max.
    m_header.write(m_stream);
    m_header.writeDimensions(m_stream, m_dims);
    m_header.m_len = m_stream.position();
}

void BpfWriter::write(const PointBuffer& data)
{
    writePointMajor(data);
    m_header.m_numPts += data.size();
}

void BpfWriter::writePointMajor(const PointBuffer& data)
{
    for (PointId idx = 0; idx < data.size(); ++idx)
    {
        for (auto & bpfDim : m_dims)
        {
            float v = data.getFieldAs<float>(bpfDim.m_id, idx);
            bpfDim.m_min = std::min(bpfDim.m_min, bpfDim.m_offset + v);
            bpfDim.m_max = std::min(bpfDim.m_max, bpfDim.m_offset + v);
            m_stream << v;
        }
    }
}

void BpfWriter::done(PointContextRef)
{
    m_stream.seek(0);
    m_header.write(m_stream);
    m_header.writeDimensions(m_stream, m_dims);
    m_stream.flush();
}

} //namespace pdal
<commit_msg>dimension max in bpf header never gets updated<commit_after>/******************************************************************************
* Copyright (c) 2015, Hobu Inc., hobu@hobu.co
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in
*       the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
*       names of its contributors may be used to endorse or promote
*       products derived from this software without specific prior
*       written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#include <pdal/pdal_internal.hpp>

#include <zlib.h>

#include <pdal/Options.hpp>

#include "BpfWriter.hpp"

namespace pdal
{

void BpfWriter::processOptions(const Options&)
{
    if (m_filename.empty())
        throw pdal_error("Can't write BPF file without filename.");
}

void BpfWriter::ready(PointContextRef ctx)
{
    Dimension::IdList dims = ctx.dims();
    for (auto id : dims)
    {
        BpfDimension dim;
        dim.m_id = id;
        dim.m_label = ctx.dimName(id);
        m_dims.push_back(dim);
    }

    m_stream = FileUtils::createFile(m_filename, true);
    m_header.m_version = 3;
    m_header.m_numDim = dims.size();
    //ABELL - For now.
    m_header.m_pointFormat = BpfFormat::PointMajor;
    m_header.m_coordType = BpfCoordType::None;
    m_header.m_coordId = 0;
    m_header.setLog(log());

    // We will re-write the header and dimensions to account for the point
    // count and dimension min/max.
    m_header.write(m_stream);
    m_header.writeDimensions(m_stream, m_dims);
    m_header.m_len = m_stream.position();
}

void BpfWriter::write(const PointBuffer& data)
{
    writePointMajor(data);
    m_header.m_numPts += data.size();
}

void BpfWriter::writePointMajor(const PointBuffer& data)
{
    for (PointId idx = 0; idx < data.size(); ++idx)
    {
        for (auto & bpfDim : m_dims)
        {
            float v = data.getFieldAs<float>(bpfDim.m_id, idx);
            bpfDim.m_min = std::min(bpfDim.m_min, bpfDim.m_offset + v);
            bpfDim.m_max = std::max(bpfDim.m_max, bpfDim.m_offset + v);
            m_stream << v;
        }
    }
}

void BpfWriter::done(PointContextRef)
{
    m_stream.seek(0);
    m_header.write(m_stream);
    m_header.writeDimensions(m_stream, m_dims);
    m_stream.flush();
}

} //namespace pdal
<|endoftext|>


<commit_before>// Copyright (c) 2011 Timur Iskhodzhanov and MIPT students. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <math.h>

#include "gtest/gtest.h"

#include "base/common.h"

const int kMaxFactorial = 13;

int Factorial(int v) {
  // NB we wrote the implementation of this function on the lecture;
  // before the lecture it was simply "return -1;"

  CHECK_GE(v, 0);
  CHECK_LT(v, kMaxFactorial);

  if (v <= 1)
    return 1;

  // TODO(timurrrr): don't use recursion.
  return v * Factorial(v - 1);
}

// Tests factorial of positive numbers.
TEST(FactorialTest, HandlesPositiveInput) {
  EXPECT_EQ(1, Factorial(1));
  EXPECT_EQ(2, Factorial(2));
  EXPECT_EQ(6, Factorial(3));
  EXPECT_EQ(40320, Factorial(8));
  EXPECT_EQ(479001600, Factorial(12));
}

// Tests factorial of 0.
// "Corner case test"
TEST(FactorialTest, HandlesZeroInput) {
  EXPECT_EQ(1, Factorial(0));
}

// Tests factorial of number that will cause integer type overflow.
TEST(FactorialTest, FailsOnTooBigInputDeathTest) {
    ASSERT_DEATH(Factorial(13), "");
    ASSERT_DEATH(Factorial(42), "");
}

TEST(FactorialTest, FailsOnNegativeInputDeathTest) {
  ASSERT_DEATH(Factorial(-1), "");
}

TEST(FailureTest, WillRemove) {
  ASSERT_EQ(1, 2);
}
<commit_msg>Temporary fix for the test again<commit_after>// Copyright (c) 2011 Timur Iskhodzhanov and MIPT students. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <math.h>

#include "gtest/gtest.h"

#include "base/common.h"

const int kMaxFactorial = 13;

int Factorial(int v) {
  // NB we wrote the implementation of this function on the lecture;
  // before the lecture it was simply "return -1;"

  CHECK_GE(v, 0);
  CHECK_LT(v, kMaxFactorial);

  if (v <= 1)
    return 1;

  // TODO(timurrrr): don't use recursion.
  return v * Factorial(v - 1);
}

// Tests factorial of positive numbers.
TEST(FactorialTest, HandlesPositiveInput) {
  EXPECT_EQ(1, Factorial(1));
  EXPECT_EQ(2, Factorial(2));
  EXPECT_EQ(6, Factorial(3));
  EXPECT_EQ(40320, Factorial(8));
  EXPECT_EQ(479001600, Factorial(12));
}

// Tests factorial of 0.
// "Corner case test"
TEST(FactorialTest, HandlesZeroInput) {
  EXPECT_EQ(1, Factorial(0));
}

// Tests factorial of number that will cause integer type overflow.
TEST(FactorialTest, FailsOnTooBigInputDeathTest) {
    ASSERT_DEATH(Factorial(13), "");
    ASSERT_DEATH(Factorial(42), "");
}

TEST(FactorialTest, FailsOnNegativeInputDeathTest) {
  ASSERT_DEATH(Factorial(-1), "");
}

TEST(FailureTest, WillRemove) {
  //ASSERT_EQ(1, 2);
}
<|endoftext|>


<commit_before>#include "SysUtil.h"
#include "lib/mace.h"

#include "TcpTransport-init.h"
#include "load_protocols.h"
#include <signal.h>
#include <string>
#include "mlist.h"

#include "RandomUtil.h"
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include <pthread.h>
//#include "TagServiceClass.h"
//#include "Tag-init.h"
#include "ContextJobApplication.h"
#include "../services/interfaces/NullServiceClass.h"

using namespace std;

/*class TagResponseHandler : public TagDataHandler {

};*/
typedef mace::vector<mace::list<mace::string> > StringListVector;
typedef mace::vector<mace::string> StringVector;

std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
  std::stringstream ss(s);
  std::string item;
  while(std::getline(ss, item, delim)) {
    elems.push_back(item);
  }
  return elems;
}

std::vector<std::string> split(const std::string &s, char delim) {
  std::vector<std::string> elems;
  split(s, delim, elems);
  return elems;
}

void loadContextFromParam( const mace::string& service, mace::map< mace::string, ContextMappingType >& contexts, mace::map< mace::string, MaceAddr>& migrateContexts){
  if( ! params::containsKey("nodeset") || ! params::containsKey("mapping") ){
    return;
  }
  NodeSet ns = params::get<NodeSet>("nodeset");

  StringVector mapping = split(params::get<mace::string>("mapping"), '\n');

  typedef mace::map<MaceAddr, mace::list<mace::string> > ContextMappingType;

  StringListVector node_context;

  ASSERT(ns.size() > 0);
  for( uint32_t i=0; i<ns.size(); i++ ) {
    mace::list<mace::string> string_list;
    node_context.push_back(string_list);
  }

  // Set for head node
  node_context[0].push_back( mace::ContextMapping::getHeadContext() ); //head context
  node_context[0].push_back( "" ); // global

  // key:value
  // context_peer_id:context_value
  // 2:A[0] 2:A[1] ...

  for( StringVector::const_iterator it = mapping.begin(); it != mapping.end(); it++ ) {
    StringVector kv = split(*it, ':');
    ASSERT(kv.size() == 2);

    uint32_t key;
    istringstream(kv[0]) >> key;
    ASSERT(key >= 0 && key < ns.size());
    node_context[key].push_back(kv[1]);
  }

  ContextMappingType contextMap;

  int i=0;
  std::vector< MaceAddr > nodeAddrs;
  for( NodeSet::iterator it = ns.begin(); it != ns.end(); it++ ) {
    std::cout << "nodeset[" << i << "] = " << *it << std::endl;
    contextMap[ (*it).getMaceAddr() ] = node_context[ i++ ];
    nodeAddrs.push_back(  (*it).getMaceAddr() );
  }

  contexts[ service ] = contextMap;

  if( params::containsKey("migrateBatch") ){
    // create a number of migrations
    StringVector migrateBatch = split(params::get<mace::string>("migrateBatch"), ':');
    std::string contextName = migrateBatch[0];
    uint32_t migrateFrom = atoi( migrateBatch[1].c_str() );
    uint32_t migrateTo = atoi( migrateBatch[2].c_str() );
    uint32_t nodeID = atoi( migrateBatch[3].c_str() );

    for( uint32_t index = migrateFrom; index <= migrateTo; index++ ){
      std::ostringstream oss;
      oss << contextName << "[" << index << "]";
      migrateContexts[ oss.str() ] = nodeAddrs[ nodeID ];
    }

  }else{

    if( !params::containsKey("migrate") ) return;
    StringVector migrate = split(params::get<mace::string>("migrate"), '\n');
    for( StringVector::const_iterator it = migrate.begin(); it != migrate.end(); it++ ) {
      StringVector kv = split(*it, ':');
      ASSERT(kv.size() == 2);

      uint32_t key;
      istringstream(kv[0]) >> key;
      ASSERT(key >= 0 && key < ns.size());
      migrateContexts[ kv[1] ] =  nodeAddrs[key];
    }

    if ( !params::containsKey("migrate2") ) return;
    StringVector migrateBack = split(params::get<mace::string>("migrate2"), '\n');
    for( StringVector::const_iterator it = migrate.begin(); it != migrate.end(); it++ ) {
      StringVector kv = split(*it, ':');
      ASSERT(kv.size() == 2);

      uint32_t key;
      istringstream(kv[0]) >> key;
      ASSERT(key >= 0 && key < ns.size());
      migrateContexts[ kv[1] ] =  nodeAddrs[key];
    }

    if ( !params::containsKey("migrate3") ) return;
    StringVector migrateBack = split(params::get<mace::string>("migrate3"), '\n');
    for( StringVector::const_iterator it = migrate.begin(); it != migrate.end(); it++ ) {
      StringVector kv = split(*it, ':');
      ASSERT(kv.size() == 2);

      uint32_t key;
      istringstream(kv[0]) >> key;
      ASSERT(key >= 0 && key < ns.size());
      migrateContexts[ kv[1] ] =  nodeAddrs[key];
    }
  }

}

bool ishead = false;
void writeOutProf( int signum ){
  if( ishead ){
    std::cout<<"Head node. perform global exit and clean up"<<std::endl;
  }else{
    std::cout<<"This is not a head node! You must terminate the head node first!"<<std::endl;
  }
  exit(EXIT_SUCCESS);
}

int main(int argc, char* argv[]) {
  //Log::autoAdd("^Tag");
  mace::Init(argc, argv);
  load_protocols();

  if( params::get<bool>("gprof", false ) ){

    SysUtil::signal( SIGINT, writeOutProf ); // intercept ctrl+c and call exit to force gprof output
    SysUtil::signal( SIGABRT, writeOutProf ); // intercept abort and call exit to force gprof output
    SysUtil::signal( SIGSEGV, writeOutProf ); // intercept seg fault and call exit to force gprof output
  }

  uint64_t runtime =  (uint64_t)(params::get<double>("run_time", 2) * 1000 * 1000);
  mace::string service = "Tag";

  mace::ContextJobApplication<NullServiceClass> app;
  app.installSignalHandler();

  params::print(stdout);

  typedef mace::map<MaceAddr, mace::list<mace::string> > ContextMappingType;
  mace::map< mace::string, ContextMappingType > contexts;
  mace::map< mace::string, MaceAddr> migrateContexts;
  mace::map< mace::string, MaceAddr> migrateteBackContexts;

  loadContextFromParam( service,  contexts, migrateContexts );
  app.loadContext(contexts);

  std::cout << "Starting at time " << TimeUtil::timeu() << std::endl;

  // create new thread. one is used to launch the service, one is to initiates the migration request.

  app.startService( service );

  mace::list< mace::string > &nodectx = contexts[ service ][ Util::getMaceAddr() ];
  mace::list< mace::string >::iterator it = find( nodectx.begin(), nodectx.end(), mace::ContextMapping::getHeadContext() );
  if( it != nodectx.end() ){
    ishead = true;
  }

  if( ishead ){
    uint8_t serviceID = 0;

    uint32_t migration_start = params::get<uint32_t>("migration_start",1);
    SysUtil::sleepm( 1000 * migration_start ); // sleep for one second

    std::cout << TimeUtil::timeu() << " Migration started." << std::endl;
    for( mace::map< mace::string, MaceAddr>::iterator migctxIt = migrateContexts.begin(); migctxIt != migrateContexts.end(); migctxIt++ ){
      app.getServiceObject()->requestContextMigration( serviceID, migctxIt->first, migctxIt->second, false );
      SysUtil::sleepm( params::get<uint32_t>("sleep", 10) ); // sleep for 0.1 second
    }

    uint32_t migration_start2 = params::get<uint32_t>("migration_start2",1);
    SysUtil::sleepm( 1000 * migration_start ); // sleep for one second

    std::cout << TimeUtil::timeu() << " Migration2 started." << std::endl;
    for( mace::map< mace::string, MaceAddr>::iterator migctxIt = migrateContexts.begin(); migctxIt != migrateContexts.end(); migctxIt++ ){
      app.getServiceObject()->requestContextMigration( serviceID, migctxIt->first, migctxIt->second, false );
      SysUtil::sleepm( params::get<uint32_t>("sleep", 10) ); // sleep for 0.1 second
    }

    uint32_t migration_start3 = params::get<uint32_t>("migration_start3",1);
    SysUtil::sleepm( 1000 * migration_start ); // sleep for one second

    std::cout << TimeUtil::timeu() << " Migration3 started." << std::endl;
    for( mace::map< mace::string, MaceAddr>::iterator migctxIt = migrateContexts.begin(); migctxIt != migrateContexts.end(); migctxIt++ ){
      app.getServiceObject()->requestContextMigration( serviceID, migctxIt->first, migctxIt->second, false );
      SysUtil::sleepm( params::get<uint32_t>("sleep", 10) ); // sleep for 0.1 second
    }

  }
  app.waitService( runtime );

  if( ishead ){ // head node sents exit event
    app.globalExit();
  }

  return EXIT_SUCCESS;
}
<commit_msg>firstTag.cc updated<commit_after>#include "SysUtil.h"
#include "lib/mace.h"

#include "TcpTransport-init.h"
#include "load_protocols.h"
#include <signal.h>
#include <string>
#include "mlist.h"

#include "RandomUtil.h"
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include <pthread.h>
//#include "TagServiceClass.h"
//#include "Tag-init.h"
#include "ContextJobApplication.h"
#include "../services/interfaces/NullServiceClass.h"

using namespace std;

/*class TagResponseHandler : public TagDataHandler {

};*/
typedef mace::vector<mace::list<mace::string> > StringListVector;
typedef mace::vector<mace::string> StringVector;

std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
  std::stringstream ss(s);
  std::string item;
  while(std::getline(ss, item, delim)) {
    elems.push_back(item);
  }
  return elems;
}

std::vector<std::string> split(const std::string &s, char delim) {
  std::vector<std::string> elems;
  split(s, delim, elems);
  return elems;
}

void loadContextFromParam( const mace::string& service, mace::map< mace::string, ContextMappingType >& contexts, mace::map< mace::string, MaceAddr>& migrateContexts, mace::map< mace::string, MaceAddr>& migrateContexts2 ){
  if( ! params::containsKey("nodeset") || ! params::containsKey("mapping") ){
    return;
  }
  NodeSet ns = params::get<NodeSet>("nodeset");

  StringVector mapping = split(params::get<mace::string>("mapping"), '\n');

  typedef mace::map<MaceAddr, mace::list<mace::string> > ContextMappingType;

  StringListVector node_context;

  ASSERT(ns.size() > 0);
  for( uint32_t i=0; i<ns.size(); i++ ) {
    mace::list<mace::string> string_list;
    node_context.push_back(string_list);
  }

  // Set for head node
  node_context[0].push_back( mace::ContextMapping::getHeadContext() ); //head context
  node_context[0].push_back( "" ); // global

  // key:value
  // context_peer_id:context_value
  // 2:A[0] 2:A[1] ...

  for( StringVector::const_iterator it = mapping.begin(); it != mapping.end(); it++ ) {
    StringVector kv = split(*it, ':');
    ASSERT(kv.size() == 2);

    uint32_t key;
    istringstream(kv[0]) >> key;
    ASSERT(key >= 0 && key < ns.size());
    node_context[key].push_back(kv[1]);
  }

  ContextMappingType contextMap;

  int i=0;
  std::vector< MaceAddr > nodeAddrs;
  for( NodeSet::iterator it = ns.begin(); it != ns.end(); it++ ) {
    std::cout << "nodeset[" << i << "] = " << *it << std::endl;
    contextMap[ (*it).getMaceAddr() ] = node_context[ i++ ];
    nodeAddrs.push_back(  (*it).getMaceAddr() );
  }

  contexts[ service ] = contextMap;

  if( params::containsKey("migrateBatch") ){
    // create a number of migrations
    StringVector migrateBatch = split(params::get<mace::string>("migrateBatch"), ':');
    std::string contextName = migrateBatch[0];
    uint32_t migrateFrom = atoi( migrateBatch[1].c_str() );
    uint32_t migrateTo = atoi( migrateBatch[2].c_str() );
    uint32_t nodeID = atoi( migrateBatch[3].c_str() );

    for( uint32_t index = migrateFrom; index <= migrateTo; index++ ){
      std::ostringstream oss;
      oss << contextName << "[" << index << "]";
      migrateContexts[ oss.str() ] = nodeAddrs[ nodeID ];
    }

  }else{

    if( !params::containsKey("migrate") ) return;
    StringVector migrate = split(params::get<mace::string>("migrate"), '\n');
    for( StringVector::const_iterator it = migrate.begin(); it != migrate.end(); it++ ) {
      StringVector kv = split(*it, ':');
      ASSERT(kv.size() == 2);

      uint32_t key;
      istringstream(kv[0]) >> key;
      ASSERT(key >= 0 && key < ns.size());
      migrateContexts[ kv[1] ] =  nodeAddrs[key];
    }

    if ( !params::containsKey("migrate2") ) return;
    StringVector migrate2 = split(params::get<mace::string>("migrate2"), '\n');
    for( StringVector::const_iterator it = migrate2.begin(); it != migrate2.end(); it++ ) {
      StringVector kv = split(*it, ':');
      ASSERT(kv.size() == 2);

      uint32_t key;
      istringstream(kv[0]) >> key;
      ASSERT(key >= 0 && key < ns.size());
      migrateContexts2[ kv[1] ] =  nodeAddrs[key];
    }

    //if ( !params::containsKey("migrate3") ) return;
    //StringVector migrateBack = split(params::get<mace::string>("migrate3"), '\n');
    //for( StringVector::const_iterator it = migrate.begin(); it != migrate.end(); it++ ) {
      //StringVector kv = split(*it, ':');
      //ASSERT(kv.size() == 2);

      //uint32_t key;
      //istringstream(kv[0]) >> key;
      //ASSERT(key >= 0 && key < ns.size());
      //migrateContexts[ kv[1] ] =  nodeAddrs[key];
    //}
  }

}

bool ishead = false;
void writeOutProf( int signum ){
  if( ishead ){
    std::cout<<"Head node. perform global exit and clean up"<<std::endl;
  }else{
    std::cout<<"This is not a head node! You must terminate the head node first!"<<std::endl;
  }
  exit(EXIT_SUCCESS);
}

int main(int argc, char* argv[]) {
  //Log::autoAdd("^Tag");
  mace::Init(argc, argv);
  load_protocols();

  if( params::get<bool>("gprof", false ) ){

    SysUtil::signal( SIGINT, writeOutProf ); // intercept ctrl+c and call exit to force gprof output
    SysUtil::signal( SIGABRT, writeOutProf ); // intercept abort and call exit to force gprof output
    SysUtil::signal( SIGSEGV, writeOutProf ); // intercept seg fault and call exit to force gprof output
  }

  uint64_t runtime =  (uint64_t)(params::get<double>("run_time", 2) * 1000 * 1000);
  mace::string service = "Tag";

  mace::ContextJobApplication<NullServiceClass> app;
  app.installSignalHandler();

  params::print(stdout);

  typedef mace::map<MaceAddr, mace::list<mace::string> > ContextMappingType;
  mace::map< mace::string, ContextMappingType > contexts;
  mace::map< mace::string, MaceAddr> migrateContexts;
  mace::map< mace::string, MaceAddr> migrateContexts2;
  mace::map< mace::string, MaceAddr> migrateteBackContexts;

  loadContextFromParam( service,  contexts, migrateContexts, migrateContexts2 );
  app.loadContext(contexts);

  std::cout << "Starting at time " << TimeUtil::timeu() << std::endl;

  // create new thread. one is used to launch the service, one is to initiates the migration request.

  app.startService( service );

  mace::list< mace::string > &nodectx = contexts[ service ][ Util::getMaceAddr() ];
  mace::list< mace::string >::iterator it = find( nodectx.begin(), nodectx.end(), mace::ContextMapping::getHeadContext() );
  if( it != nodectx.end() ){
    ishead = true;
  }

  if( ishead ){
    uint8_t serviceID = 0;

    uint32_t migration_start = params::get<uint32_t>("migration_start",1);
    SysUtil::sleepm( 1000 * migration_start ); // sleep until migration

    std::cout << TimeUtil::timeu() << " Migration started." << std::endl;
    for( mace::map< mace::string, MaceAddr>::iterator migctxIt = migrateContexts.begin(); migctxIt != migrateContexts.end(); migctxIt++ ){
      app.getServiceObject()->requestContextMigration( serviceID, migctxIt->first, migctxIt->second, false );
      SysUtil::sleepm( params::get<uint32_t>("sleep", 10) ); // sleep for 0.1 second
    }

    uint32_t migration_start2 = params::get<uint32_t>("migration_start2",1);
    if( migration_start2 > migration_start1 ) {
      SysUtil::sleepm( 1000 * (migration_start2-migration_start) ); // sleep until second migration

      std::cout << TimeUtil::timeu() << " Migration2 started." << std::endl;
      for( mace::map< mace::string, MaceAddr>::iterator migctxIt = migrateContexts2.begin(); migctxIt != migrateContexts2.end(); migctxIt++ ){
        app.getServiceObject()->requestContextMigration( serviceID, migctxIt->first, migctxIt->second, false );
        SysUtil::sleepm( params::get<uint32_t>("sleep", 10) ); // sleep for 0.1 second
      }
    } else {
      std::cout << TimeUtil::timeu() << " Migration2 will not be started." << std::endl;
    }

    //uint32_t migration_start3 = params::get<uint32_t>("migration_start3",1);
    //SysUtil::sleepm( 1000 * migration_start ); // sleep for one second

    //std::cout << TimeUtil::timeu() << " Migration3 started." << std::endl;
    //for( mace::map< mace::string, MaceAddr>::iterator migctxIt = migrateContexts.begin(); migctxIt != migrateContexts.end(); migctxIt++ ){
      //app.getServiceObject()->requestContextMigration( serviceID, migctxIt->first, migctxIt->second, false );
      //SysUtil::sleepm( params::get<uint32_t>("sleep", 10) ); // sleep for 0.1 second
    //}

  }
  app.waitService( runtime );

  if( ishead ){ // head node sents exit event
    app.globalExit();
  }

  return EXIT_SUCCESS;
}
<|endoftext|>


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

#include "qvalidatedlineedit.h"

#include "bitcoinaddressvalidator.h"
#include "guiconstants.h"

QValidatedLineEdit::QValidatedLineEdit(QWidget *parent) :
    QLineEdit(parent),
    valid(true),
    checkValidator(0)
{
    connect(this, SIGNAL(textChanged(QString)), this, SLOT(markValid()));
}

void QValidatedLineEdit::setValid(bool _valid)
{
    if(_valid == this->valid)
    {
        return;
    }

    if(_valid)
    {
        setStyleSheet("");
    }
    else
    {
        setStyleSheet("QValidatedLineEdit { " STYLE_INVALID "}");
    }
    this->valid = _valid;
}

void QValidatedLineEdit::focusInEvent(QFocusEvent *evt)
{
    // Clear invalid flag on focus
    setValid(true);

    QLineEdit::focusInEvent(evt);
}

void QValidatedLineEdit::focusOutEvent(QFocusEvent *evt)
{
    checkValidity();

    QLineEdit::focusOutEvent(evt);
}

void QValidatedLineEdit::markValid()
{
    // As long as a user is typing ensure we display state as valid
    setValid(true);
}

void QValidatedLineEdit::clear()
{
    setValid(true);
    QLineEdit::clear();
}

void QValidatedLineEdit::setEnabled(bool enabled)
{
    if (!enabled)
    {
        // A disabled QValidatedLineEdit should be marked valid
        setValid(true);
    }
    else
    {
        // Recheck validity when QValidatedLineEdit gets enabled
        checkValidity();
    }

    QLineEdit::setEnabled(enabled);
}

void QValidatedLineEdit::checkValidity()
{
    if (text().isEmpty())
    {
        setValid(true);
    }
    else if (hasAcceptableInput())
    {
        setValid(true);

        // Check contents on focus out
        if (checkValidator)
        {
            QString address = text();
            int pos = 0;
            if (checkValidator->validate(address, pos) == QValidator::Acceptable)
                setValid(true);
            else
                setValid(false);
        }
    }
    else
        setValid(false);

    Q_EMIT validationDidChange(this);
}

void QValidatedLineEdit::setCheckValidator(const QValidator *v)
{
    checkValidator = v;
}

bool QValidatedLineEdit::isValid()
{
    // use checkValidator in case the QValidatedLineEdit is disabled
    if (checkValidator)
    {
        QString address = text();
        int pos = 0;
        if (checkValidator->validate(address, pos) == QValidator::Acceptable)
            return true;
    }

    return valid;
}
<commit_msg>Bugfix: GUI: Re-check validity after QValidatedLineEdit::setCheckValidator<commit_after>// Copyright (c) 2011-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "qvalidatedlineedit.h"

#include "bitcoinaddressvalidator.h"
#include "guiconstants.h"

QValidatedLineEdit::QValidatedLineEdit(QWidget *parent) :
    QLineEdit(parent),
    valid(true),
    checkValidator(0)
{
    connect(this, SIGNAL(textChanged(QString)), this, SLOT(markValid()));
}

void QValidatedLineEdit::setValid(bool _valid)
{
    if(_valid == this->valid)
    {
        return;
    }

    if(_valid)
    {
        setStyleSheet("");
    }
    else
    {
        setStyleSheet("QValidatedLineEdit { " STYLE_INVALID "}");
    }
    this->valid = _valid;
}

void QValidatedLineEdit::focusInEvent(QFocusEvent *evt)
{
    // Clear invalid flag on focus
    setValid(true);

    QLineEdit::focusInEvent(evt);
}

void QValidatedLineEdit::focusOutEvent(QFocusEvent *evt)
{
    checkValidity();

    QLineEdit::focusOutEvent(evt);
}

void QValidatedLineEdit::markValid()
{
    // As long as a user is typing ensure we display state as valid
    setValid(true);
}

void QValidatedLineEdit::clear()
{
    setValid(true);
    QLineEdit::clear();
}

void QValidatedLineEdit::setEnabled(bool enabled)
{
    if (!enabled)
    {
        // A disabled QValidatedLineEdit should be marked valid
        setValid(true);
    }
    else
    {
        // Recheck validity when QValidatedLineEdit gets enabled
        checkValidity();
    }

    QLineEdit::setEnabled(enabled);
}

void QValidatedLineEdit::checkValidity()
{
    if (text().isEmpty())
    {
        setValid(true);
    }
    else if (hasAcceptableInput())
    {
        setValid(true);

        // Check contents on focus out
        if (checkValidator)
        {
            QString address = text();
            int pos = 0;
            if (checkValidator->validate(address, pos) == QValidator::Acceptable)
                setValid(true);
            else
                setValid(false);
        }
    }
    else
        setValid(false);

    Q_EMIT validationDidChange(this);
}

void QValidatedLineEdit::setCheckValidator(const QValidator *v)
{
    checkValidator = v;
    checkValidity();
}

bool QValidatedLineEdit::isValid()
{
    // use checkValidator in case the QValidatedLineEdit is disabled
    if (checkValidator)
    {
        QString address = text();
        int pos = 0;
        if (checkValidator->validate(address, pos) == QValidator::Acceptable)
            return true;
    }

    return valid;
}
<|endoftext|>


<commit_before><commit_msg>[wasm] fix memory info creation (#7461)<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 * REALM CONFIDENTIAL
 * __________________
 *
 *  [2011] - [2015] Realm Inc
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Realm Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Realm Incorporated
 * and its suppliers and may be covered by U.S. and Foreign Patents,
 * patents in process, and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Realm Incorporated.
 *
 **************************************************************************/
#ifndef REALM_COLUMN_DATETIME_HPP
#define REALM_COLUMN_DATETIME_HPP

#include <realm/column.hpp>

namespace realm {

struct NewDate {
    NewDate(int64_t seconds, uint32_t nanoseconds) : m_seconds(seconds), m_nanoseconds(nanoseconds), m_is_null(false)
    {
        REALM_ASSERT_3(nanoseconds, <, 1000000000);
    }
    NewDate(const null&) : m_is_null(true) { }
    NewDate() : NewDate(null()) { }

    bool is_null() const { return m_is_null; }
    bool operator == (const NewDate& rhs) const { return m_seconds == rhs.m_seconds && m_nanoseconds == rhs.m_nanoseconds; }
    bool operator != (const NewDate& rhs) const { return m_seconds != rhs.m_seconds || m_nanoseconds != rhs.m_nanoseconds; }
    bool operator > (const NewDate& rhs) const { return (m_seconds > rhs.m_seconds) || (m_seconds == rhs.m_seconds && m_nanoseconds > rhs.m_nanoseconds); }
    bool operator < (const NewDate& rhs) const { return (m_seconds < rhs.m_seconds) || (m_seconds == rhs.m_seconds && m_nanoseconds < rhs.m_nanoseconds); }
    bool operator <= (const NewDate& rhs) const { return *this < rhs || *this == rhs; }
    bool operator >= (const NewDate& rhs) const { return *this > rhs || *this == rhs; }
    NewDate& operator = (const NewDate& rhs) = default;

    template<class Ch, class Tr>
    friend std::basic_ostream<Ch, Tr>& operator<<(std::basic_ostream<Ch, Tr>& out, const NewDate&);

    int64_t m_seconds;
    uint32_t m_nanoseconds;
    bool m_is_null;
};

template<class C, class T>
inline std::basic_ostream<C, T>& operator<<(std::basic_ostream<C, T>& out, const NewDate& d)
{
    out << "NewDate(" << d.m_seconds << ", " << d.m_nanoseconds << ")";
    return out;
}

class DateTimeColumn : public ColumnBaseSimple {
public:
    DateTimeColumn(Allocator& alloc, ref_type ref);
    /// Get the number of entries in this column. This operation is relatively
    /// slow.

    static ref_type create(Allocator& alloc, size_t size);

    size_t size() const noexcept override;
    /// Whether or not this column is nullable.
    bool is_nullable() const noexcept override;
    /// Whether or not the value at \a row_ndx is NULL. If the column is not
    /// nullable, always returns false.
    bool is_null(size_t row_ndx) const noexcept override;
    /// Sets the value at \a row_ndx to be NULL.
    /// \throw LogicError Thrown if this column is not nullable.
    void set_null(size_t row_ndx) override;
    void insert_rows(size_t row_ndx, size_t num_rows_to_insert, size_t prior_num_rows, bool nullable) override;
    void erase_rows(size_t row_ndx, size_t num_rows_to_erase, size_t prior_num_rows,
                    bool broken_reciprocal_backlinks) override;
    void move_last_row_over(size_t row_ndx, size_t prior_num_rows,
                            bool broken_reciprocal_backlinks) override;
    void clear(size_t num_rows, bool broken_reciprocal_backlinks) override;
    void swap_rows(size_t row_ndx_1, size_t row_ndx_2) override;
    void destroy() noexcept override;
    StringData get_index_data(size_t, StringIndex::StringConversionBuffer& buffer) const noexcept override;
    MemRef clone_deep(Allocator& alloc) const override;
    ref_type write(size_t slice_offset, size_t slice_size, size_t table_size, _impl::OutputStream&) const override;
    void update_from_parent(size_t old_baseline) noexcept override;
    void refresh_accessor_tree(size_t new_col_ndx, const Spec&) override;
#ifdef REALM_DEBUG
    void verify() const override;
    void to_dot(std::ostream&, StringData title = StringData()) const override;
    void do_dump_node_structure(std::ostream&, int level) const override;
    void leaf_to_dot(MemRef, ArrayParent*, size_t ndx_in_parent, std::ostream&) const override;
#endif
    void add(const NewDate& ndt = NewDate{});
    NewDate get(size_t row_ndx) const noexcept;
    void set(size_t row_ndx, const NewDate& ndt);
private:

    IntNullColumn m_seconds;
    IntegerColumn m_nanoseconds;

};

} // namespace realm

#endif // REALM_COLUMN_DATETIME_HPP
<commit_msg>Moved comment to correct place<commit_after>/*************************************************************************
 *
 * REALM CONFIDENTIAL
 * __________________
 *
 *  [2011] - [2015] Realm Inc
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Realm Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Realm Incorporated
 * and its suppliers and may be covered by U.S. and Foreign Patents,
 * patents in process, and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Realm Incorporated.
 *
 **************************************************************************/
#ifndef REALM_COLUMN_DATETIME_HPP
#define REALM_COLUMN_DATETIME_HPP

#include <realm/column.hpp>

namespace realm {

struct NewDate {
    NewDate(int64_t seconds, uint32_t nanoseconds) : m_seconds(seconds), m_nanoseconds(nanoseconds), m_is_null(false)
    {
        REALM_ASSERT_3(nanoseconds, <, 1000000000);
    }
    NewDate(const null&) : m_is_null(true) { }
    NewDate() : NewDate(null()) { }

    bool is_null() const { return m_is_null; }
    bool operator == (const NewDate& rhs) const { return m_seconds == rhs.m_seconds && m_nanoseconds == rhs.m_nanoseconds; }
    bool operator != (const NewDate& rhs) const { return m_seconds != rhs.m_seconds || m_nanoseconds != rhs.m_nanoseconds; }
    bool operator > (const NewDate& rhs) const { return (m_seconds > rhs.m_seconds) || (m_seconds == rhs.m_seconds && m_nanoseconds > rhs.m_nanoseconds); }
    bool operator < (const NewDate& rhs) const { return (m_seconds < rhs.m_seconds) || (m_seconds == rhs.m_seconds && m_nanoseconds < rhs.m_nanoseconds); }
    bool operator <= (const NewDate& rhs) const { return *this < rhs || *this == rhs; }
    bool operator >= (const NewDate& rhs) const { return *this > rhs || *this == rhs; }
    NewDate& operator = (const NewDate& rhs) = default;

    template<class Ch, class Tr>
    friend std::basic_ostream<Ch, Tr>& operator<<(std::basic_ostream<Ch, Tr>& out, const NewDate&);

    int64_t m_seconds;
    uint32_t m_nanoseconds;
    bool m_is_null;
};

template<class C, class T>
inline std::basic_ostream<C, T>& operator<<(std::basic_ostream<C, T>& out, const NewDate& d)
{
    out << "NewDate(" << d.m_seconds << ", " << d.m_nanoseconds << ")";
    return out;
}

class DateTimeColumn : public ColumnBaseSimple {
public:
    DateTimeColumn(Allocator& alloc, ref_type ref);

    static ref_type create(Allocator& alloc, size_t size);

    /// Get the number of entries in this column. This operation is relatively
    /// slow.
    size_t size() const noexcept override;
    /// Whether or not this column is nullable.
    bool is_nullable() const noexcept override;
    /// Whether or not the value at \a row_ndx is NULL. If the column is not
    /// nullable, always returns false.
    bool is_null(size_t row_ndx) const noexcept override;
    /// Sets the value at \a row_ndx to be NULL.
    /// \throw LogicError Thrown if this column is not nullable.
    void set_null(size_t row_ndx) override;
    void insert_rows(size_t row_ndx, size_t num_rows_to_insert, size_t prior_num_rows, bool nullable) override;
    void erase_rows(size_t row_ndx, size_t num_rows_to_erase, size_t prior_num_rows,
                    bool broken_reciprocal_backlinks) override;
    void move_last_row_over(size_t row_ndx, size_t prior_num_rows,
                            bool broken_reciprocal_backlinks) override;
    void clear(size_t num_rows, bool broken_reciprocal_backlinks) override;
    void swap_rows(size_t row_ndx_1, size_t row_ndx_2) override;
    void destroy() noexcept override;
    StringData get_index_data(size_t, StringIndex::StringConversionBuffer& buffer) const noexcept override;
    MemRef clone_deep(Allocator& alloc) const override;
    ref_type write(size_t slice_offset, size_t slice_size, size_t table_size, _impl::OutputStream&) const override;
    void update_from_parent(size_t old_baseline) noexcept override;
    void refresh_accessor_tree(size_t new_col_ndx, const Spec&) override;
#ifdef REALM_DEBUG
    void verify() const override;
    void to_dot(std::ostream&, StringData title = StringData()) const override;
    void do_dump_node_structure(std::ostream&, int level) const override;
    void leaf_to_dot(MemRef, ArrayParent*, size_t ndx_in_parent, std::ostream&) const override;
#endif
    void add(const NewDate& ndt = NewDate{});
    NewDate get(size_t row_ndx) const noexcept;
    void set(size_t row_ndx, const NewDate& ndt);
private:

    IntNullColumn m_seconds;
    IntegerColumn m_nanoseconds;

};

} // namespace realm

#endif // REALM_COLUMN_DATETIME_HPP
<|endoftext|>