<commit_before>
#include "astclass.h"

#include "core/defines.h"

#include "yasc/compiler/scope/scope.h"
#include "yasc/compiler/scope/scopevariable.h"
#include "libraries/libcil/cil/class.h"

#include "astfunction.h"
#include "asttype.h"
#include "asttypevariables.h"
#include "astvariable.h"
#include "astfield.h"
#include "astvisitor.h"

ASTClass::ASTClass():
   ASTNode(),
   mKind(eClass),
   mModifiers(),
   mpBaseType(nullptr),
   mInterfaces(),
   mpTypeVariables(nullptr),
   mFunctions(),
   mFunctionTable(),
   mName(),
   mFullName(),
   mStatics(),
   mFields(),
   mpCompiledClass(nullptr)
{
}

ASTClass::~ASTClass()
{
   setBaseType(nullptr);
   setTypeVariables(nullptr);
   setCompiledClass(nullptr);
}

// - Get/set

ASTClass::Kind ASTClass::getKind() const
{
   return mKind;
}

void ASTClass::setKind(Kind kind)
{
   mKind = kind;
}

bool ASTClass::hasBaseType() const
{
   return mpBaseType != nullptr;
}

const ASTType& ASTClass::getBaseType() const
{
   return *mpBaseType;
}

ASTType& ASTClass::getBaseType()
{
   return *mpBaseType;
}

void ASTClass::setBaseType(ASTType* pbasetype)
{
   delete mpBaseType;
   mpBaseType = pbasetype;
}

bool ASTClass::hasBaseClass() const
{
   return hasBaseType() && !getBaseType().isUnknown();
}

const ASTClass& ASTClass::getBaseClass() const
{
   ASSERT_PTR(mpBaseType);
   ASSERT(mpBaseType->hasObjectClass());
   return mpBaseType->getObjectClass();
}

ASTClass& ASTClass::getBaseClass()
{
   ASSERT_PTR(mpBaseType);
   return mpBaseType->getObjectClass();
}

void ASTClass::setBaseClass(ASTClass& baseclass)
{
   ASSERT_PTR(mpBaseType);
   mpBaseType->setObjectClass(baseclass);
}

const String& ASTClass::getName() const
{
   return mName;
}

void ASTClass::setName(const String& name)
{
   mName = name;
}

const String& ASTClass::getFullName() const
{
   return mFullName;
}

void ASTClass::setFullName(const String& name)
{
   mFullName = name;
}

const ASTModifiers& ASTClass::getModifiers() const
{
   return mModifiers;
}

ASTModifiers& ASTClass::getModifiers()
{
   return mModifiers;
}

const ASTTypeVariables& ASTClass::getTypeVariables() const
{
   ASSERT_PTR(mpTypeVariables);
   return *mpTypeVariables;
}

ASTTypeVariables& ASTClass::getTypeVariables()
{
   ASSERT_PTR(mpTypeVariables);
   return *mpTypeVariables;
}

void ASTClass::setTypeVariables(ASTTypeVariables* pinfo)
{
   delete mpTypeVariables;
   mpTypeVariables = pinfo;
}

const ASTFunctionMap& ASTClass::getFunctions() const
{
   return mFunctions;
}

ASTFunctionMap& ASTClass::getFunctions()
{
   return mFunctions;
}

const ASTFunctionTable& ASTClass::getFunctionTable() const
{
   return mFunctionTable;
}

ASTFunctionTable& ASTClass::getFunctionTable()
{
   return mFunctionTable;
}

const ASTTypeList& ASTClass::getInterfaces() const
{
   return mInterfaces;
}

ASTTypeList& ASTClass::getInterfaces()
{
   return mInterfaces;
}

const ASTClass::Fields& ASTClass::getStatics() const
{
   return mStatics;
}

const ASTClass::Fields& ASTClass::getFields() const
{
   return mFields;
}

CIL::Class& ASTClass::getCompiledClass()
{
   ASSERT_PTR(mpCompiledClass);
   return *mpCompiledClass;
}

CIL::Class* ASTClass::useCompiledClass()
{
   CIL::Class* presult = mpCompiledClass;
   mpCompiledClass = nullptr;
   return presult;
}

void ASTClass::setCompiledClass(CIL::Class* pclass)
{
   delete mpCompiledClass;
   mpCompiledClass = pclass;
}

// - Query

bool ASTClass::isClass() const
{
   return mKind == eClass;
}

bool ASTClass::isInterface() const
{
   return mKind == eInterface;
}

bool ASTClass::isBase(const ASTClass& base) const
{
   if ( this == &base )
   {
      return true;
   }
   else if ( hasBaseClass() )
   {
      const ASTClass& baseclass = getBaseClass();

      if ( &baseclass == &base )
      {
         return true;
      }
      else
      {
         return baseclass.isBase(base);
      }
   }
   return false;
}

bool ASTClass::isImplementing(const ASTClass& intrface) const
{
   if ( mInterfaces.contains(intrface) )
   {
      return true;
   }
   else if ( hasBaseClass() )
   {
      return getBaseClass().isImplementing(intrface);
   }

   return false;
}

bool ASTClass::isLocal(const ASTFunction& function) const
{
   return &function.getClass() == this;
}

bool ASTClass::isNative() const
{
   return mModifiers.isNative() || hasNativeFunction();
}

bool ASTClass::isGeneric() const
{
   return mpTypeVariables != nullptr;
}

bool ASTClass::isTypeName(const String& name) const
{
   return isGeneric() && mpTypeVariables->contains(name);
}

bool ASTClass::hasConstructor() const
{
   return mFunctions.hasConstructor();
}

bool ASTClass::hasAbstractFunction() const
{
   return mFunctions.hasAbstractFunction();
}

bool ASTClass::hasNativeFunction() const
{
   return mFunctions.hasNativeFunction();
}

bool ASTClass::hasNativeConstructor() const
{
   return mFunctions.hasNativeConstructor();
}

int ASTClass::getTotalStatics() const
{
   return mStatics.size();
}

int ASTClass::getTotalVariables() const
{
   return mFields.size() + (hasBaseClass() ? getBaseClass().getTotalVariables() : 0);
}

const ASTField& ASTClass::getField(int var) const
{
   if ( mFields.empty() || mFields[0]->getVariable().getResourceIndex() > var )
   {
      return getBaseClass().getField(var);
   }

   std::size_t index = var - mFields[0]->getVariable().getResourceIndex();
   ASSERT(index < mFields.size());
   return *mFields[index];
}

// - Operations

void ASTClass::addInterface(ASTType* ptype)
{
   mInterfaces.append(ptype);
}

bool ASTClass::isMember(const String& name) const
{
   const ASTMember* pmember = findField(name);
   if ( pmember == nullptr )
   {
      pmember = findStatic(name);
      if ( pmember == nullptr )
      {
         return mFunctions.hasFunction(name);
      }
   }

   return true;
}

void ASTClass::addMember(ASTMember* pmember)
{
   if ( pmember->getKind() == ASTMember::eField )
   {
      ASTField* pfield = dynamic_cast<ASTField*>(pmember);

      if ( pfield->getVariable().getModifiers().isStatic() )
      {
         mStatics.push_back(pfield);
      }
      else
      {
         mFields.push_back(pfield);
      }
   }
   else
   {
      ASTFunction* pfunction = dynamic_cast<ASTFunction*>(pmember);
      pfunction->setClass(*this);

      mFunctions.insert(pfunction);
   }

   pmember->setClass(*this);
   addChild(pmember);
}

void ASTClass::insertFunction(int index, ASTFunction* pfunction)
{
   mFunctions.insert(pfunction);
   mFunctionTable.set(index, *pfunction);

   insertChild(index, pfunction);
}

void ASTClass::ensureDefaultConstructor()
{
   if ( isClass() && !hasConstructor() )
   {
      ASTFunction* pconstructor = new ASTFunction(ASTMember::eConstructor);
      pconstructor->setName(mName);
      pconstructor->setType(new ASTType(ASTType::eVoid));
      pconstructor->getModifiers().setVisibility(ASTModifiers::ePublic);

      addMember(pconstructor);
   }
}

ASTType* ASTClass::createThisType() const
{
   ASTType* presult = new ASTType(ASTType::eObject);
   presult->setObjectName(getFullName());
   presult->setObjectClass(const_cast<ASTClass&>(*this));
   return presult;
}

void ASTClass::collectInterfaces(ASTTypeList& interfaces) const
{
   interfaces.append(mInterfaces);

   if ( hasBaseClass() )
   {
      getBaseClass().collectInterfaces(interfaces);
   }
}

void ASTClass::registerVariables(Scope& scope) const
{
   if ( hasBaseClass() )
   {
      getBaseClass().registerVariables(scope);
   }

   for ( std::size_t index = 0; index < mStatics.size(); index++ )
   {
      ASTField* pstatic = mStatics[index];
      scope.add(ScopeVariable::fromVariable(pstatic->getVariable()));
   }

   for ( std::size_t index = 0; index < mFields.size(); index++ )
   {
      ASTField* pvariable = mFields[index];
      scope.add(ScopeVariable::fromVariable(pvariable->getVariable()));
   }
}

void ASTClass::calculateResources()
{
   indexStatics();
   indexVariables();
   indexFunctions();
}

void ASTClass::indexStatics()
{
   for ( std::size_t index = 0; index < mStatics.size(); index++ )
   {
      ASTField* pstatic = mStatics[index];
      pstatic->getVariable().setResourceIndex(index);
   }
}

void ASTClass::indexVariables()
{
   int base = hasBaseClass() ? getBaseClass().getTotalVariables() : 0;

   for ( std::size_t index = 0; index < mFields.size(); index++ )
   {
      ASTField* pvariable = mFields[index];
      pvariable->getVariable().setResourceIndex(base + index);
   }
}

void ASTClass::indexFunctions()
{
   if ( isClass() )
   {
      if ( hasBaseClass() )
      {
         mFunctionTable = getBaseClass().getFunctionTable();
      }
   }

   mFunctionTable.build(mFunctions);
}

// - Search

const ASTField* ASTClass::findStatic(const String& name, SearchScope scope) const
{
   return const_cast<ASTClass&>(*this).findStatic(name, scope);
}

ASTField* ASTClass::findStatic(const String& name, SearchScope scope)
{
   for ( std::size_t index = 0; index < mStatics.size(); index++ )
   {
      ASTField* pstatic = mStatics[index];
      if ( pstatic->getVariable().getName() == name )
      {
         return pstatic;
      }
   }
   return scope == eAll && hasBaseClass() ? getBaseClass().findStatic(name, eAll) : nullptr;
}

const ASTField* ASTClass::findField(const String& name, SearchScope scope) const
{
   return const_cast<ASTClass&>(*this).findField(name, scope);
}

ASTField* ASTClass::findField(const String& name, SearchScope scope)
{
   for ( std::size_t index = 0; index < mFields.size(); index++ )
   {
      ASTField* pvariable = mFields[index];
      if ( pvariable->getVariable().getName() == name )
      {
         return pvariable;
      }
   }
   return scope == eAll && hasBaseClass() ? getBaseClass().findField(name) : nullptr;
}

const ASTFunction* ASTClass::findBestMatch(const String& name, const ASTSignature& signature, const ASTTypeList& types) const
{
   return const_cast<ASTClass&>(*this).findBestMatch(name, signature, types);
}

ASTFunction* ASTClass::findBestMatch(const String& name, const ASTSignature& signature, const ASTTypeList& types)
{
   ASTFunction* pfunction = mFunctions.findBestMatch(name, signature, types);
   if ( pfunction == nullptr && hasBaseClass() )
   {
      pfunction = getBaseClass().findBestMatch(name, signature, types);
   }
   return pfunction;
}

const ASTFunction* ASTClass::findExactMatch(const String& name, const ASTSignature& signature) const
{
   return const_cast<ASTClass&>(*this).findExactMatch(name, signature);
}

ASTFunction* ASTClass::findExactMatch(const String& name, const ASTSignature& signature)
{
   ASTFunction* pfunction = mFunctions.findExactMatch(name, signature);
   if ( pfunction == nullptr && hasBaseClass() )
   {
      pfunction = getBaseClass().findExactMatch(name, signature);
   }
   return pfunction;
}

// - Visitor

ACCEPT_IMPL(ASTClass)<commit_msg>Fix coverity issues 33966 & 33967<commit_after>
#include "astclass.h"

#include "core/defines.h"

#include "yasc/compiler/scope/scope.h"
#include "yasc/compiler/scope/scopevariable.h"
#include "libraries/libcil/cil/class.h"

#include "astfunction.h"
#include "asttype.h"
#include "asttypevariables.h"
#include "astvariable.h"
#include "astfield.h"
#include "astvisitor.h"

ASTClass::ASTClass():
   ASTNode(),
   mKind(eClass),
   mModifiers(),
   mpBaseType(nullptr),
   mInterfaces(),
   mpTypeVariables(nullptr),
   mFunctions(),
   mFunctionTable(),
   mName(),
   mFullName(),
   mStatics(),
   mFields(),
   mpCompiledClass(nullptr)
{
}

ASTClass::~ASTClass()
{
   setBaseType(nullptr);
   setTypeVariables(nullptr);
   setCompiledClass(nullptr);
}

// - Get/set

ASTClass::Kind ASTClass::getKind() const
{
   return mKind;
}

void ASTClass::setKind(Kind kind)
{
   mKind = kind;
}

bool ASTClass::hasBaseType() const
{
   return mpBaseType != nullptr;
}

const ASTType& ASTClass::getBaseType() const
{
   return *mpBaseType;
}

ASTType& ASTClass::getBaseType()
{
   return *mpBaseType;
}

void ASTClass::setBaseType(ASTType* pbasetype)
{
   delete mpBaseType;
   mpBaseType = pbasetype;
}

bool ASTClass::hasBaseClass() const
{
   return hasBaseType() && !getBaseType().isUnknown();
}

const ASTClass& ASTClass::getBaseClass() const
{
   ASSERT_PTR(mpBaseType);
   ASSERT(mpBaseType->hasObjectClass());
   return mpBaseType->getObjectClass();
}

ASTClass& ASTClass::getBaseClass()
{
   ASSERT_PTR(mpBaseType);
   return mpBaseType->getObjectClass();
}

void ASTClass::setBaseClass(ASTClass& baseclass)
{
   ASSERT_PTR(mpBaseType);
   mpBaseType->setObjectClass(baseclass);
}

const String& ASTClass::getName() const
{
   return mName;
}

void ASTClass::setName(const String& name)
{
   mName = name;
}

const String& ASTClass::getFullName() const
{
   return mFullName;
}

void ASTClass::setFullName(const String& name)
{
   mFullName = name;
}

const ASTModifiers& ASTClass::getModifiers() const
{
   return mModifiers;
}

ASTModifiers& ASTClass::getModifiers()
{
   return mModifiers;
}

const ASTTypeVariables& ASTClass::getTypeVariables() const
{
   ASSERT_PTR(mpTypeVariables);
   return *mpTypeVariables;
}

ASTTypeVariables& ASTClass::getTypeVariables()
{
   ASSERT_PTR(mpTypeVariables);
   return *mpTypeVariables;
}

void ASTClass::setTypeVariables(ASTTypeVariables* pinfo)
{
   delete mpTypeVariables;
   mpTypeVariables = pinfo;
}

const ASTFunctionMap& ASTClass::getFunctions() const
{
   return mFunctions;
}

ASTFunctionMap& ASTClass::getFunctions()
{
   return mFunctions;
}

const ASTFunctionTable& ASTClass::getFunctionTable() const
{
   return mFunctionTable;
}

ASTFunctionTable& ASTClass::getFunctionTable()
{
   return mFunctionTable;
}

const ASTTypeList& ASTClass::getInterfaces() const
{
   return mInterfaces;
}

ASTTypeList& ASTClass::getInterfaces()
{
   return mInterfaces;
}

const ASTClass::Fields& ASTClass::getStatics() const
{
   return mStatics;
}

const ASTClass::Fields& ASTClass::getFields() const
{
   return mFields;
}

CIL::Class& ASTClass::getCompiledClass()
{
   ASSERT_PTR(mpCompiledClass);
   return *mpCompiledClass;
}

CIL::Class* ASTClass::useCompiledClass()
{
   CIL::Class* presult = mpCompiledClass;
   mpCompiledClass = nullptr;
   return presult;
}

void ASTClass::setCompiledClass(CIL::Class* pclass)
{
   delete mpCompiledClass;
   mpCompiledClass = pclass;
}

// - Query

bool ASTClass::isClass() const
{
   return mKind == eClass;
}

bool ASTClass::isInterface() const
{
   return mKind == eInterface;
}

bool ASTClass::isBase(const ASTClass& base) const
{
   if ( this == &base )
   {
      return true;
   }
   else if ( hasBaseClass() )
   {
      const ASTClass& baseclass = getBaseClass();

      if ( &baseclass == &base )
      {
         return true;
      }
      else
      {
         return baseclass.isBase(base);
      }
   }
   return false;
}

bool ASTClass::isImplementing(const ASTClass& intrface) const
{
   if ( mInterfaces.contains(intrface) )
   {
      return true;
   }
   else if ( hasBaseClass() )
   {
      return getBaseClass().isImplementing(intrface);
   }

   return false;
}

bool ASTClass::isLocal(const ASTFunction& function) const
{
   return &function.getClass() == this;
}

bool ASTClass::isNative() const
{
   return mModifiers.isNative() || hasNativeFunction();
}

bool ASTClass::isGeneric() const
{
   return mpTypeVariables != nullptr;
}

bool ASTClass::isTypeName(const String& name) const
{
   return isGeneric() && mpTypeVariables->contains(name);
}

bool ASTClass::hasConstructor() const
{
   return mFunctions.hasConstructor();
}

bool ASTClass::hasAbstractFunction() const
{
   return mFunctions.hasAbstractFunction();
}

bool ASTClass::hasNativeFunction() const
{
   return mFunctions.hasNativeFunction();
}

bool ASTClass::hasNativeConstructor() const
{
   return mFunctions.hasNativeConstructor();
}

int ASTClass::getTotalStatics() const
{
   return mStatics.size();
}

int ASTClass::getTotalVariables() const
{
   return mFields.size() + (hasBaseClass() ? getBaseClass().getTotalVariables() : 0);
}

const ASTField& ASTClass::getField(int var) const
{
   if ( mFields.empty() || mFields[0]->getVariable().getResourceIndex() > var )
   {
      return getBaseClass().getField(var);
   }

   std::size_t index = var - mFields[0]->getVariable().getResourceIndex();
   ASSERT(index < mFields.size());
   return *mFields[index];
}

// - Operations

void ASTClass::addInterface(ASTType* ptype)
{
   mInterfaces.append(ptype);
}

bool ASTClass::isMember(const String& name) const
{
   const ASTMember* pmember = findField(name);
   if ( pmember == nullptr )
   {
      pmember = findStatic(name);
      if ( pmember == nullptr )
      {
         return mFunctions.hasFunction(name);
      }
   }

   return true;
}

void ASTClass::addMember(ASTMember* pmember)
{
   switch ( pmember->getKind() )
   {
   case ASTMember::eField:
      {
         ASTField* pfield = static_cast<ASTField*>(pmember);

         if ( pfield->getVariable().getModifiers().isStatic() )
         {
            mStatics.push_back(pfield);
         }
         else
         {
            mFields.push_back(pfield);
         }
      }
      break;
   case ASTMember::eConstructor:
   case ASTMember::eFunction:
      {
         ASTFunction* pfunction = static_cast<ASTFunction*>(pmember);
         pfunction->setClass(*this);

         mFunctions.insert(pfunction);
      }
      break;
   case ASTMember::eProperty:
      {
         // not implemented yet
      }
      break;
   }

   pmember->setClass(*this);
   addChild(pmember);
}

void ASTClass::insertFunction(int index, ASTFunction* pfunction)
{
   mFunctions.insert(pfunction);
   mFunctionTable.set(index, *pfunction);

   insertChild(index, pfunction);
}

void ASTClass::ensureDefaultConstructor()
{
   if ( isClass() && !hasConstructor() )
   {
      ASTFunction* pconstructor = new ASTFunction(ASTMember::eConstructor);
      pconstructor->setName(mName);
      pconstructor->setType(new ASTType(ASTType::eVoid));
      pconstructor->getModifiers().setVisibility(ASTModifiers::ePublic);

      addMember(pconstructor);
   }
}

ASTType* ASTClass::createThisType() const
{
   ASTType* presult = new ASTType(ASTType::eObject);
   presult->setObjectName(getFullName());
   presult->setObjectClass(const_cast<ASTClass&>(*this));
   return presult;
}

void ASTClass::collectInterfaces(ASTTypeList& interfaces) const
{
   interfaces.append(mInterfaces);

   if ( hasBaseClass() )
   {
      getBaseClass().collectInterfaces(interfaces);
   }
}

void ASTClass::registerVariables(Scope& scope) const
{
   if ( hasBaseClass() )
   {
      getBaseClass().registerVariables(scope);
   }

   for ( std::size_t index = 0; index < mStatics.size(); index++ )
   {
      ASTField* pstatic = mStatics[index];
      scope.add(ScopeVariable::fromVariable(pstatic->getVariable()));
   }

   for ( std::size_t index = 0; index < mFields.size(); index++ )
   {
      ASTField* pvariable = mFields[index];
      scope.add(ScopeVariable::fromVariable(pvariable->getVariable()));
   }
}

void ASTClass::calculateResources()
{
   indexStatics();
   indexVariables();
   indexFunctions();
}

void ASTClass::indexStatics()
{
   for ( std::size_t index = 0; index < mStatics.size(); index++ )
   {
      ASTField* pstatic = mStatics[index];
      pstatic->getVariable().setResourceIndex(index);
   }
}

void ASTClass::indexVariables()
{
   int base = hasBaseClass() ? getBaseClass().getTotalVariables() : 0;

   for ( std::size_t index = 0; index < mFields.size(); index++ )
   {
      ASTField* pvariable = mFields[index];
      pvariable->getVariable().setResourceIndex(base + index);
   }
}

void ASTClass::indexFunctions()
{
   if ( isClass() )
   {
      if ( hasBaseClass() )
      {
         mFunctionTable = getBaseClass().getFunctionTable();
      }
   }

   mFunctionTable.build(mFunctions);
}

// - Search

const ASTField* ASTClass::findStatic(const String& name, SearchScope scope) const
{
   return const_cast<ASTClass&>(*this).findStatic(name, scope);
}

ASTField* ASTClass::findStatic(const String& name, SearchScope scope)
{
   for ( std::size_t index = 0; index < mStatics.size(); index++ )
   {
      ASTField* pstatic = mStatics[index];
      if ( pstatic->getVariable().getName() == name )
      {
         return pstatic;
      }
   }
   return scope == eAll && hasBaseClass() ? getBaseClass().findStatic(name, eAll) : nullptr;
}

const ASTField* ASTClass::findField(const String& name, SearchScope scope) const
{
   return const_cast<ASTClass&>(*this).findField(name, scope);
}

ASTField* ASTClass::findField(const String& name, SearchScope scope)
{
   for ( std::size_t index = 0; index < mFields.size(); index++ )
   {
      ASTField* pvariable = mFields[index];
      if ( pvariable->getVariable().getName() == name )
      {
         return pvariable;
      }
   }
   return scope == eAll && hasBaseClass() ? getBaseClass().findField(name) : nullptr;
}

const ASTFunction* ASTClass::findBestMatch(const String& name, const ASTSignature& signature, const ASTTypeList& types) const
{
   return const_cast<ASTClass&>(*this).findBestMatch(name, signature, types);
}

ASTFunction* ASTClass::findBestMatch(const String& name, const ASTSignature& signature, const ASTTypeList& types)
{
   ASTFunction* pfunction = mFunctions.findBestMatch(name, signature, types);
   if ( pfunction == nullptr && hasBaseClass() )
   {
      pfunction = getBaseClass().findBestMatch(name, signature, types);
   }
   return pfunction;
}

const ASTFunction* ASTClass::findExactMatch(const String& name, const ASTSignature& signature) const
{
   return const_cast<ASTClass&>(*this).findExactMatch(name, signature);
}

ASTFunction* ASTClass::findExactMatch(const String& name, const ASTSignature& signature)
{
   ASTFunction* pfunction = mFunctions.findExactMatch(name, signature);
   if ( pfunction == nullptr && hasBaseClass() )
   {
      pfunction = getBaseClass().findExactMatch(name, signature);
   }
   return pfunction;
}

// - Visitor

ACCEPT_IMPL(ASTClass)
<|endoftext|>


<commit_before>/* $Id$
 *
 * OpenMAMA: The open middleware agnostic messaging API
 * Copyright (C) 2011 NYSE Technologies, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301 USA
 */

#include <pthread.h>
#include <string>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <assert.h>
#include <errno.h>
#include <stdio.h>

#include <mama/mamacpp.h>
#include <mamda/MamdaLock.h>

using std::string;
using std::ostringstream;
using std::runtime_error;

namespace Wombat
{

    class MamdaLock::MamdaLockImpl
    {
    public:
        MamdaLockImpl           (MamdaLock::Scheme     scheme,
                                 const char*           context,
                                 int                   threads);
        ~MamdaLockImpl          ();

        bool acquire            (MamdaLock::Type       type);
        bool release            (MamdaLock::Type       type);

    private:
        MamdaLockImpl           (const MamdaLockImpl&  impl);     // No copying!

        void handlePthreadError (int                   status,
                                 const string&         context);

        bool lockMutex          (bool                  throwEx,
                                 const char*           context);

        bool unlockMutex        (bool                  throwEx,
                                 const char*           context);

        MamdaLock::Scheme       mScheme;

        pthread_mutex_t         mMutex;
        pthread_cond_t          mCond;
        pthread_mutexattr_t     mMutexAttr;

        // For rwlocking
        pthread_rwlock_t        mRwLock;
        pthread_rwlockattr_t    mRwLockAttr;

        int                     mCount;
        int                     mThreads;

        char                    mName    [129];
        char                    mContext [129];
    };

    MamdaLock::MamdaLock(
        Scheme       scheme,
        const char*  context,
        int          threads)
        : mImpl (*new MamdaLockImpl(scheme, context, threads))
    {
    }

    MamdaLock::MamdaLockImpl::MamdaLockImpl (
        MamdaLock::Scheme  scheme,
        const char*        context,
        int                threads)
        : mScheme  (scheme)
        , mCount   (0)
        , mThreads (threads)
    {
        int status = 0;

        snprintf (mName,    128, "%s",   context);
        snprintf (mContext, 128, "[%s]", context);

        if (MamdaLock::SHARED == scheme)
        {
            status = pthread_rwlockattr_init (&mRwLockAttr);
            if (0 != status)
            {
                handlePthreadError (status,
			                        "MamdaLock::MamdaLock(): Failed to init rwlock attr");
            }
            status = pthread_rwlock_init (&mRwLock, &mRwLockAttr);
            if (0 != status)
            {
                handlePthreadError (status,
			                        "MamdaLock::MamdaLock(): Failed to init rwlock attr");
            }
            return;
        }
        status = pthread_mutexattr_init (&mMutexAttr);
        if (0 != status)
        {
            handlePthreadError (status,
		                        "MamdaLock::MamdaLock(): Failed to init mutex attr");
        }
        if (MamdaLock::EXCLUSIVE == scheme)
        {

            status = pthread_mutexattr_settype(&mMutexAttr,
						    PTHREAD_MUTEX_RECURSIVE_NP);

            if (0 != status)
            {
                handlePthreadError (status,
                                    "MamdaLock::MamdaLock(): Failed to set mutex "
                                    "attr: PTHREAD_MUTEX_RECURSIVE_NP");
            }
        }

        status =  pthread_mutex_init (&mMutex, &mMutexAttr);
        if (0 != status)
        {
            handlePthreadError (status,
                                "MamdaLock::MamdaLock(): "
			                    "Failed to init mutex");
        }

        status = pthread_cond_init (&mCond, NULL);
        if (0 != status)
        {
            handlePthreadError (status,
                                "MamdaLock::Lock(): Failed to init cond");
        }
    }

    MamdaLock::~MamdaLock()
    {
        delete &mImpl;
    }

    MamdaLock::MamdaLockImpl::~MamdaLockImpl()
    {
        if (mScheme == MamdaLock::SHARED)
        {
            int status = pthread_rwlock_destroy (&mRwLock);
            if (0 == status)
            {
                handlePthreadError (status,
                                    "MamdaLock::~MamdaLock(): Failed to destroy rwlock");
            }
            status = pthread_rwlockattr_destroy (&mRwLockAttr);
            if (0 == status)
            {
                handlePthreadError (status,
                                    "MamdaLock::~MamdaLock(): Failed to destroy rwlockattr");
            }

            return;
        }
        int status = pthread_mutex_destroy (&mMutex);
        if (0 == status)
        {
            handlePthreadError (status,
                                "MamdaLock::~MamdaLock(): Failed to destroy mutex");
        }
        status = pthread_cond_destroy (&mCond);
        if (0 != status)
        {
            handlePthreadError (status,
                                "MamdaLock::MamdaLock(): Failed to destroy cond");
        }

        status = pthread_mutexattr_destroy (&mMutexAttr);
        if (0 != status)
        {
            handlePthreadError (status,
                                "MamdaLock::MamdaLock(): Failed to destroy mutex attr");
        }
    }

    bool MamdaLock::acquire (Type type)
    {
        return mImpl.acquire (type);
    }

    bool MamdaLock::MamdaLockImpl::acquire (MamdaLock::Type type)
    {
        bool isLogFinest = (MAMA_LOG_LEVEL_FINEST == mama_getLogLevel());

        if (mThreads == -1)
        {
            mCount++;
            if (mCount % 10000 == 0)
            {
                mama_log (MAMA_LOG_LEVEL_FINEST,
                          "%s: Acquired %d locks so far\n",
                          mContext,
                          mCount);
            }
            return true;
        }

        // For the EXCLUSIVE locking scheme, it just uses
        // simple mutexes
        if (mScheme == MamdaLock::SHARED)
        {
            if (isLogFinest)
            {
                mama_log (MAMA_LOG_LEVEL_FINEST,
                          "%s: Acquiring  %s lock using scheme %s PID(%d)\n",
                          mContext,
                          MamdaLock::type (type),
                          MamdaLock::scheme (mScheme),
                          (void*)pthread_self());
            }

            if (type == MamdaLock::READ)
            {
                int status = pthread_rwlock_rdlock (&mRwLock);

                if (isLogFinest)
                {
                    mama_log (MAMA_LOG_LEVEL_FINEST,
                              "%s: Acquired  %s lock using scheme %s PID(%d)\n",
                              mContext,
                              MamdaLock::type (type),
                              MamdaLock::scheme (mScheme),
                              (void*)pthread_self());
                }

                if (status)
                {
                    handlePthreadError (false, "MamdaLock::acquire() rdlock");
                    return false;
                }
                return true;
            }
            else
            {
                int status = pthread_rwlock_wrlock (&mRwLock);

                if (isLogFinest)
                {
                    mama_log (MAMA_LOG_LEVEL_FINEST,
                              "%s: Acquired  %s lock using scheme %s PID(%d)\n",
                              mContext,
                              MamdaLock::type (type),
                              MamdaLock::scheme (mScheme),
                              (void*)pthread_self());
                }
                if (status)
                {
                    handlePthreadError (false, "MamdaLock::acquire() wrlock");
                    return false;
                }
                return true;
            }
        }
        else
        {
            if (!lockMutex (false, "MamdaLock::acquire(): (1)"))
                return false;

            if (isLogFinest)
            {
                mama_log (MAMA_LOG_LEVEL_FINEST,
                          "%s: Acquired  %s lock using scheme %s PID(%d)\n",
                          mContext,
                          MamdaLock::type (type),
                          MamdaLock::scheme (mScheme),
                          (void*)pthread_self());
            }

            return true;
        }
        return true;
    }

    bool MamdaLock::release (MamdaLock::Type type)
    {
        return mImpl.release (type);
    }

    bool MamdaLock::MamdaLockImpl::release (MamdaLock::Type type)
    {
        if (mThreads == -1)
            return true;

        if (MAMA_LOG_LEVEL_FINEST == mama_getLogLevel())
        {
            mama_log (MAMA_LOG_LEVEL_FINEST,
                      "%s: Releasing  %s lock using scheme %s PID(%d)\n",
                      mContext,
                      MamdaLock::type (type),
                      MamdaLock::scheme (mScheme),
                      (void*)pthread_self());
        }

        if (mScheme == MamdaLock::SHARED)
        {
            int status = pthread_rwlock_unlock (&mRwLock);

            if (status)
            {
                handlePthreadError (false, "MamdaLock::acquire() rdlock");
                return false;
            }
            return true;
        }
        else
        {
            //Release any waiting threads
            if (!unlockMutex (true, "MamdaLock::release(): (1)"))
            {
                return false;
            }
            return true;
        }
    }

    void MamdaLock::MamdaLockImpl::handlePthreadError (
        int            status,
        const string&  context)
    {
        if (0 != status)
        {
            string errorStr;
            switch (status)
            {
                case (EINVAL):
                    errorStr =  "Mutex not properly initialized!";
                    break;
                case (EDEADLK):
                    errorStr = "Already locked by calling thread!";
                    break;
                case (EPERM):
                    errorStr = "Calling thread does not own the mutex!";
                    break;
                case (EBUSY):
                    errorStr = "thread is currently locked!";
                    break;
                default:
                    errorStr = "unrecognized failure type";
                    break;
            }
            mama_log (MAMA_LOG_LEVEL_NORMAL,
                      "%s: %s (%d)!\n",
                      mContext,
                      errorStr.c_str(),
                      status);
        }
    }

    bool MamdaLock::MamdaLockImpl::lockMutex (
        bool         throwEx,
        const char*  context)
    {
        int status = pthread_mutex_lock (&mMutex);

        if (0 != status)
        {
            string errMsg = context;
            errMsg += " lock failed";

            handlePthreadError (status, errMsg);

            if (throwEx)
                throw runtime_error (errMsg.c_str());
            return false;
        }
        return true;
    }

    bool MamdaLock::MamdaLockImpl::unlockMutex (
        bool         throwEx,
        const char*  context)
    {
        int status = pthread_mutex_unlock (&mMutex);
        if (0 != status)
        {
            string errMsg = context;
            errMsg += " unlock failed";

            handlePthreadError (status, errMsg);

            if (throwEx)
                throw runtime_error (errMsg.c_str());
            return false;
        }
        return true;
    }

    const char* MamdaLock::scheme (Scheme scheme)
    {
        switch(scheme)
        {
            case(SHARED):     return "SHARED";
            case(EXCLUSIVE):  return "EXCLUSIVE";
            default:          return "UNKNOWN SCHEME";
        }
    }

    const char* MamdaLock::type (Type type)
    {
        switch(type)
        {
            case(READ):    return "READ";
            case(WRITE):   return "WRITE";
            default:       return "UNKNOWN TYPE";
        }
    }

} // namespace Wombat
<commit_msg>MAMDA: Implement WTHREAD_MUTEX_RECURSIVE in MAMDA.<commit_after>/* $Id$
 *
 * OpenMAMA: The open middleware agnostic messaging API
 * Copyright (C) 2011 NYSE Technologies, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301 USA
 */

#include <pthread.h>
#include <string>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <assert.h>
#include <errno.h>
#include <stdio.h>

#include <mama/mamacpp.h>
#include <mamda/MamdaLock.h>

using std::string;
using std::ostringstream;
using std::runtime_error;

namespace Wombat
{

    class MamdaLock::MamdaLockImpl
    {
    public:
        MamdaLockImpl           (MamdaLock::Scheme     scheme,
                                 const char*           context,
                                 int                   threads);
        ~MamdaLockImpl          ();

        bool acquire            (MamdaLock::Type       type);
        bool release            (MamdaLock::Type       type);

    private:
        MamdaLockImpl           (const MamdaLockImpl&  impl);     // No copying!

        void handlePthreadError (int                   status,
                                 const string&         context);

        bool lockMutex          (bool                  throwEx,
                                 const char*           context);

        bool unlockMutex        (bool                  throwEx,
                                 const char*           context);

        MamdaLock::Scheme       mScheme;

        pthread_mutex_t         mMutex;
        pthread_cond_t          mCond;
        pthread_mutexattr_t     mMutexAttr;

        // For rwlocking
        pthread_rwlock_t        mRwLock;
        pthread_rwlockattr_t    mRwLockAttr;

        int                     mCount;
        int                     mThreads;

        char                    mName    [129];
        char                    mContext [129];
    };

    MamdaLock::MamdaLock(
        Scheme       scheme,
        const char*  context,
        int          threads)
        : mImpl (*new MamdaLockImpl(scheme, context, threads))
    {
    }

    MamdaLock::MamdaLockImpl::MamdaLockImpl (
        MamdaLock::Scheme  scheme,
        const char*        context,
        int                threads)
        : mScheme  (scheme)
        , mCount   (0)
        , mThreads (threads)
    {
        int status = 0;

        snprintf (mName,    128, "%s",   context);
        snprintf (mContext, 128, "[%s]", context);

        if (MamdaLock::SHARED == scheme)
        {
            status = pthread_rwlockattr_init (&mRwLockAttr);
            if (0 != status)
            {
                handlePthreadError (status,
			                        "MamdaLock::MamdaLock(): Failed to init rwlock attr");
            }
            status = pthread_rwlock_init (&mRwLock, &mRwLockAttr);
            if (0 != status)
            {
                handlePthreadError (status,
			                        "MamdaLock::MamdaLock(): Failed to init rwlock attr");
            }
            return;
        }
        status = pthread_mutexattr_init (&mMutexAttr);
        if (0 != status)
        {
            handlePthreadError (status,
		                        "MamdaLock::MamdaLock(): Failed to init mutex attr");
        }
        if (MamdaLock::EXCLUSIVE == scheme)
        {

            status = pthread_mutexattr_settype(&mMutexAttr,
						    WTHREAD_MUTEX_RECURSIVE);

            if (0 != status)
            {
                handlePthreadError (status,
                                    "MamdaLock::MamdaLock(): Failed to set mutex "
                                    "attr: PTHREAD_MUTEX_RECURSIVE_NP");
            }
        }

        status =  pthread_mutex_init (&mMutex, &mMutexAttr);
        if (0 != status)
        {
            handlePthreadError (status,
                                "MamdaLock::MamdaLock(): "
			                    "Failed to init mutex");
        }

        status = pthread_cond_init (&mCond, NULL);
        if (0 != status)
        {
            handlePthreadError (status,
                                "MamdaLock::Lock(): Failed to init cond");
        }
    }

    MamdaLock::~MamdaLock()
    {
        delete &mImpl;
    }

    MamdaLock::MamdaLockImpl::~MamdaLockImpl()
    {
        if (mScheme == MamdaLock::SHARED)
        {
            int status = pthread_rwlock_destroy (&mRwLock);
            if (0 == status)
            {
                handlePthreadError (status,
                                    "MamdaLock::~MamdaLock(): Failed to destroy rwlock");
            }
            status = pthread_rwlockattr_destroy (&mRwLockAttr);
            if (0 == status)
            {
                handlePthreadError (status,
                                    "MamdaLock::~MamdaLock(): Failed to destroy rwlockattr");
            }

            return;
        }
        int status = pthread_mutex_destroy (&mMutex);
        if (0 == status)
        {
            handlePthreadError (status,
                                "MamdaLock::~MamdaLock(): Failed to destroy mutex");
        }
        status = pthread_cond_destroy (&mCond);
        if (0 != status)
        {
            handlePthreadError (status,
                                "MamdaLock::MamdaLock(): Failed to destroy cond");
        }

        status = pthread_mutexattr_destroy (&mMutexAttr);
        if (0 != status)
        {
            handlePthreadError (status,
                                "MamdaLock::MamdaLock(): Failed to destroy mutex attr");
        }
    }

    bool MamdaLock::acquire (Type type)
    {
        return mImpl.acquire (type);
    }

    bool MamdaLock::MamdaLockImpl::acquire (MamdaLock::Type type)
    {
        bool isLogFinest = (MAMA_LOG_LEVEL_FINEST == mama_getLogLevel());

        if (mThreads == -1)
        {
            mCount++;
            if (mCount % 10000 == 0)
            {
                mama_log (MAMA_LOG_LEVEL_FINEST,
                          "%s: Acquired %d locks so far\n",
                          mContext,
                          mCount);
            }
            return true;
        }

        // For the EXCLUSIVE locking scheme, it just uses
        // simple mutexes
        if (mScheme == MamdaLock::SHARED)
        {
            if (isLogFinest)
            {
                mama_log (MAMA_LOG_LEVEL_FINEST,
                          "%s: Acquiring  %s lock using scheme %s PID(%d)\n",
                          mContext,
                          MamdaLock::type (type),
                          MamdaLock::scheme (mScheme),
                          (void*)pthread_self());
            }

            if (type == MamdaLock::READ)
            {
                int status = pthread_rwlock_rdlock (&mRwLock);

                if (isLogFinest)
                {
                    mama_log (MAMA_LOG_LEVEL_FINEST,
                              "%s: Acquired  %s lock using scheme %s PID(%d)\n",
                              mContext,
                              MamdaLock::type (type),
                              MamdaLock::scheme (mScheme),
                              (void*)pthread_self());
                }

                if (status)
                {
                    handlePthreadError (false, "MamdaLock::acquire() rdlock");
                    return false;
                }
                return true;
            }
            else
            {
                int status = pthread_rwlock_wrlock (&mRwLock);

                if (isLogFinest)
                {
                    mama_log (MAMA_LOG_LEVEL_FINEST,
                              "%s: Acquired  %s lock using scheme %s PID(%d)\n",
                              mContext,
                              MamdaLock::type (type),
                              MamdaLock::scheme (mScheme),
                              (void*)pthread_self());
                }
                if (status)
                {
                    handlePthreadError (false, "MamdaLock::acquire() wrlock");
                    return false;
                }
                return true;
            }
        }
        else
        {
            if (!lockMutex (false, "MamdaLock::acquire(): (1)"))
                return false;

            if (isLogFinest)
            {
                mama_log (MAMA_LOG_LEVEL_FINEST,
                          "%s: Acquired  %s lock using scheme %s PID(%d)\n",
                          mContext,
                          MamdaLock::type (type),
                          MamdaLock::scheme (mScheme),
                          (void*)pthread_self());
            }

            return true;
        }
        return true;
    }

    bool MamdaLock::release (MamdaLock::Type type)
    {
        return mImpl.release (type);
    }

    bool MamdaLock::MamdaLockImpl::release (MamdaLock::Type type)
    {
        if (mThreads == -1)
            return true;

        if (MAMA_LOG_LEVEL_FINEST == mama_getLogLevel())
        {
            mama_log (MAMA_LOG_LEVEL_FINEST,
                      "%s: Releasing  %s lock using scheme %s PID(%d)\n",
                      mContext,
                      MamdaLock::type (type),
                      MamdaLock::scheme (mScheme),
                      (void*)pthread_self());
        }

        if (mScheme == MamdaLock::SHARED)
        {
            int status = pthread_rwlock_unlock (&mRwLock);

            if (status)
            {
                handlePthreadError (false, "MamdaLock::acquire() rdlock");
                return false;
            }
            return true;
        }
        else
        {
            //Release any waiting threads
            if (!unlockMutex (true, "MamdaLock::release(): (1)"))
            {
                return false;
            }
            return true;
        }
    }

    void MamdaLock::MamdaLockImpl::handlePthreadError (
        int            status,
        const string&  context)
    {
        if (0 != status)
        {
            string errorStr;
            switch (status)
            {
                case (EINVAL):
                    errorStr =  "Mutex not properly initialized!";
                    break;
                case (EDEADLK):
                    errorStr = "Already locked by calling thread!";
                    break;
                case (EPERM):
                    errorStr = "Calling thread does not own the mutex!";
                    break;
                case (EBUSY):
                    errorStr = "thread is currently locked!";
                    break;
                default:
                    errorStr = "unrecognized failure type";
                    break;
            }
            mama_log (MAMA_LOG_LEVEL_NORMAL,
                      "%s: %s (%d)!\n",
                      mContext,
                      errorStr.c_str(),
                      status);
        }
    }

    bool MamdaLock::MamdaLockImpl::lockMutex (
        bool         throwEx,
        const char*  context)
    {
        int status = pthread_mutex_lock (&mMutex);

        if (0 != status)
        {
            string errMsg = context;
            errMsg += " lock failed";

            handlePthreadError (status, errMsg);

            if (throwEx)
                throw runtime_error (errMsg.c_str());
            return false;
        }
        return true;
    }

    bool MamdaLock::MamdaLockImpl::unlockMutex (
        bool         throwEx,
        const char*  context)
    {
        int status = pthread_mutex_unlock (&mMutex);
        if (0 != status)
        {
            string errMsg = context;
            errMsg += " unlock failed";

            handlePthreadError (status, errMsg);

            if (throwEx)
                throw runtime_error (errMsg.c_str());
            return false;
        }
        return true;
    }

    const char* MamdaLock::scheme (Scheme scheme)
    {
        switch(scheme)
        {
            case(SHARED):     return "SHARED";
            case(EXCLUSIVE):  return "EXCLUSIVE";
            default:          return "UNKNOWN SCHEME";
        }
    }

    const char* MamdaLock::type (Type type)
    {
        switch(type)
        {
            case(READ):    return "READ";
            case(WRITE):   return "WRITE";
            default:       return "UNKNOWN TYPE";
        }
    }

} // namespace Wombat
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015 - The zScale Authors <legal@zscale.io>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include "stx/stdtypes.h"
#include "stx/test/unittest.h"
#include "zbase/core/ReplicationScheme.h"

using namespace stx;
using namespace zbase;

UNIT_TEST(ReplicationSchemeTest);

TEST_CASE(ReplicationSchemeTest, TestHostAssignmentWithTwoNodes, [] () {
  ClusterConfig cc;
  cc.set_dht_num_copies(3);

  {
    auto node = cc.add_dht_nodes();
    node->set_status(DHTNODE_LIVE);
    node->set_name("nodeA");
    node->set_addr("1.1.1.1:1234");
    *node->add_sha1_tokens() = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    *node->add_sha1_tokens() = "6666666666666666666666666666666666666666";
  }

  {
    auto node = cc.add_dht_nodes();
    node->set_status(DHTNODE_LIVE);
    node->set_name("nodeB");
    node->set_addr("2.2.2.2:1234");
    *node->add_sha1_tokens() = "3333333333333333333333333333333333333333";
  }

  DHTReplicationScheme rscheme(cc);

  {
    auto replicas = rscheme.replicasFor(
        SHA1Hash::fromHexString("1111111111111111111111111111111111111111"));

    EXPECT_EQ(replicas.size(), 2);
    EXPECT_EQ(
        replicas[0].unique_id.toString(),
        "3333333333333333333333333333333333333333");
    EXPECT_EQ(replicas[0].addr.ipAndPort(), "2.2.2.2:1234");
    EXPECT_EQ(
        replicas[1].unique_id.toString(),
        "6666666666666666666666666666666666666666");
    EXPECT_EQ(replicas[1].addr.ipAndPort(), "1.1.1.1:1234");
  }

  {
    auto replicas = rscheme.replicasFor(
        SHA1Hash::fromHexString("8888888888888888888888888888888888888888"));

    EXPECT_EQ(replicas.size(), 2);
    EXPECT_EQ(
        replicas[0].unique_id.toString(),
        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
    EXPECT_EQ(replicas[0].addr.ipAndPort(), "1.1.1.1:1234");
    EXPECT_EQ(
        replicas[1].unique_id.toString(),
        "3333333333333333333333333333333333333333");
    EXPECT_EQ(replicas[1].addr.ipAndPort(), "2.2.2.2:1234");
  }

  {
    auto replicas = rscheme.replicasFor(
        SHA1Hash::fromHexString("dddddddddddddddddddddddddddddddddddddddd"));

    EXPECT_EQ(replicas.size(), 2);
    EXPECT_EQ(
        replicas[0].unique_id.toString(),
        "3333333333333333333333333333333333333333");
    EXPECT_EQ(replicas[0].addr.ipAndPort(), "2.2.2.2:1234");
    EXPECT_EQ(
        replicas[1].unique_id.toString(),
        "6666666666666666666666666666666666666666");
    EXPECT_EQ(replicas[1].addr.ipAndPort(), "1.1.1.1:1234");
  }
});

<commit_msg>ReplicationSchemeTest...<commit_after>/**
 * Copyright (c) 2015 - The zScale Authors <legal@zscale.io>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include "stx/stdtypes.h"
#include "stx/test/unittest.h"
#include "zbase/core/ReplicationScheme.h"

using namespace stx;
using namespace zbase;

UNIT_TEST(ReplicationSchemeTest);

TEST_CASE(ReplicationSchemeTest, TestHostAssignmentWithTwoNodes, [] () {
  ClusterConfig cc;
  cc.set_dht_num_copies(3);

  {
    auto node = cc.add_dht_nodes();
    node->set_status(DHTNODE_LIVE);
    node->set_name("nodeA");
    node->set_addr("1.1.1.1:1234");
    *node->add_sha1_tokens() = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    *node->add_sha1_tokens() = "6666666666666666666666666666666666666666";
  }

  {
    auto node = cc.add_dht_nodes();
    node->set_status(DHTNODE_LIVE);
    node->set_name("nodeB");
    node->set_addr("2.2.2.2:1234");
    *node->add_sha1_tokens() = "3333333333333333333333333333333333333333";
  }

  DHTReplicationScheme rscheme(cc);

  {
    auto replicas = rscheme.replicasFor(
        SHA1Hash::fromHexString("1111111111111111111111111111111111111111"));

    EXPECT_EQ(replicas.size(), 2);
    EXPECT_EQ(
        replicas[0].unique_id.toString(),
        "3333333333333333333333333333333333333333");
    EXPECT_EQ(replicas[0].addr.ipAndPort(), "2.2.2.2:1234");
    EXPECT_EQ(
        replicas[1].unique_id.toString(),
        "6666666666666666666666666666666666666666");
    EXPECT_EQ(replicas[1].addr.ipAndPort(), "1.1.1.1:1234");
  }

  {
    auto replicas = rscheme.replicasFor(
        SHA1Hash::fromHexString("8888888888888888888888888888888888888888"));

    EXPECT_EQ(replicas.size(), 2);
    EXPECT_EQ(
        replicas[0].unique_id.toString(),
        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
    EXPECT_EQ(replicas[0].addr.ipAndPort(), "1.1.1.1:1234");
    EXPECT_EQ(
        replicas[1].unique_id.toString(),
        "3333333333333333333333333333333333333333");
    EXPECT_EQ(replicas[1].addr.ipAndPort(), "2.2.2.2:1234");
  }

  {
    auto replicas = rscheme.replicasFor(
        SHA1Hash::fromHexString("dddddddddddddddddddddddddddddddddddddddd"));

    EXPECT_EQ(replicas.size(), 2);
    EXPECT_EQ(
        replicas[0].unique_id.toString(),
        "3333333333333333333333333333333333333333");
    EXPECT_EQ(replicas[0].addr.ipAndPort(), "2.2.2.2:1234");
    EXPECT_EQ(
        replicas[1].unique_id.toString(),
        "6666666666666666666666666666666666666666");
    EXPECT_EQ(replicas[1].addr.ipAndPort(), "1.1.1.1:1234");
  }
});

TEST_CASE(ReplicationSchemeTest, TestHostAssignmentWithThreeNodes, [] () {
  ClusterConfig cc;
  cc.set_dht_num_copies(3);

  {
    auto node = cc.add_dht_nodes();
    node->set_status(DHTNODE_LIVE);
    node->set_name("nodeA");
    node->set_addr("1.1.1.1:1234");
    *node->add_sha1_tokens() = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    *node->add_sha1_tokens() = "6666666666666666666666666666666666666666";
  }

  {
    auto node = cc.add_dht_nodes();
    node->set_status(DHTNODE_LIVE);
    node->set_name("nodeB");
    node->set_addr("2.2.2.2:1234");
    *node->add_sha1_tokens() = "3333333333333333333333333333333333333333";
  }

  {
    auto node = cc.add_dht_nodes();
    node->set_status(DHTNODE_LIVE);
    node->set_name("nodeC");
    node->set_addr("3.3.3.3:1234");
    *node->add_sha1_tokens() = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
    *node->add_sha1_tokens() = "fcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfc";
  }

  DHTReplicationScheme rscheme(cc);

  {
    auto replicas = rscheme.replicasFor(
        SHA1Hash::fromHexString("1111111111111111111111111111111111111111"));

    EXPECT_EQ(replicas.size(), 3);
    EXPECT_EQ(
        replicas[0].unique_id.toString(),
        "3333333333333333333333333333333333333333");
    EXPECT_EQ(replicas[0].addr.ipAndPort(), "2.2.2.2:1234");
    EXPECT_EQ(
        replicas[1].unique_id.toString(),
        "6666666666666666666666666666666666666666");
    EXPECT_EQ(replicas[1].addr.ipAndPort(), "1.1.1.1:1234");
    EXPECT_EQ(
        replicas[2].unique_id.toString(),
        "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
    EXPECT_EQ(replicas[2].addr.ipAndPort(), "3.3.3.3:1234");
  }

  {
    auto replicas = rscheme.replicasFor(
        SHA1Hash::fromHexString("8888888888888888888888888888888888888888"));

    EXPECT_EQ(replicas.size(), 3);
    EXPECT_EQ(
        replicas[0].unique_id.toString(),
        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
    EXPECT_EQ(replicas[0].addr.ipAndPort(), "1.1.1.1:1234");
    EXPECT_EQ(
        replicas[1].unique_id.toString(),
        "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
    EXPECT_EQ(replicas[1].addr.ipAndPort(), "3.3.3.3:1234");
    EXPECT_EQ(
        replicas[2].unique_id.toString(),
        "3333333333333333333333333333333333333333");
    EXPECT_EQ(replicas[2].addr.ipAndPort(), "2.2.2.2:1234");
  }

  {
    auto replicas = rscheme.replicasFor(
        SHA1Hash::fromHexString("dddddddddddddddddddddddddddddddddddddddd"));

    EXPECT_EQ(replicas.size(), 3);
    EXPECT_EQ(
        replicas[0].unique_id.toString(),
        "fcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfcfc");
    EXPECT_EQ(replicas[0].addr.ipAndPort(), "3.3.3.3:1234");
    EXPECT_EQ(
        replicas[1].unique_id.toString(),
        "3333333333333333333333333333333333333333");
    EXPECT_EQ(replicas[1].addr.ipAndPort(), "2.2.2.2:1234");
    EXPECT_EQ(
        replicas[2].unique_id.toString(),
        "6666666666666666666666666666666666666666");
    EXPECT_EQ(replicas[2].addr.ipAndPort(), "1.1.1.1:1234");
  }

  {
    auto replicas = rscheme.replicasFor(
        SHA1Hash::fromHexString("fdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfd"));

    EXPECT_EQ(replicas.size(), 3);
    EXPECT_EQ(
        replicas[0].unique_id.toString(),
        "3333333333333333333333333333333333333333");
    EXPECT_EQ(replicas[0].addr.ipAndPort(), "2.2.2.2:1234");
    EXPECT_EQ(
        replicas[1].unique_id.toString(),
        "6666666666666666666666666666666666666666");
    EXPECT_EQ(replicas[1].addr.ipAndPort(), "1.1.1.1:1234");
    EXPECT_EQ(
        replicas[2].unique_id.toString(),
        "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
    EXPECT_EQ(replicas[2].addr.ipAndPort(), "3.3.3.3:1234");
  }
});

<|endoftext|>


<commit_before>// Copyright 2011 Google Inc.
//
// 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 "syzygy/relink/order_relinker.h"
#include "syzygy/reorder/random_order_generator.h"
#include "base/file_util.h"
#include "gtest/gtest.h"
#include "syzygy/pe/decomposer.h"
#include "syzygy/pe/pe_file.h"
#include "syzygy/pe/unittest_util.h"

class OrderRelinkerTest : public testing::PELibUnitTest {
 protected:
  static const FilePath kInstrDllName;
  static const FilePath kOrderFileName;
  static const FilePath kTestDataDir;
};

const FilePath OrderRelinkerTest::kOrderFileName(L"order_file.json");
const FilePath OrderRelinkerTest::kInstrDllName(L"instrumented_test_dll.dll");
const FilePath OrderRelinkerTest::kTestDataDir(L"test_data");

using reorder::RandomOrderGenerator;
using reorder::Reorderer;

TEST_F(OrderRelinkerTest, Relink) {
  FilePath temp_dir;
  ASSERT_NO_FATAL_FAILURE(CreateTemporaryDir(&temp_dir));
  FilePath output_dll_path = temp_dir.Append(kDllName);
  FilePath output_pdb_path = temp_dir.Append(kDllPdbName);
  FilePath order_file_path = temp_dir.Append(kOrderFileName);

  FilePath test_data_dir = GetExeRelativePath(kTestDataDir.value().c_str());
  FilePath input_dll_path = test_data_dir.Append(kDllName);
  FilePath input_pdb_path = test_data_dir.Append(kDllPdbName);
  FilePath instr_dll_path = test_data_dir.Append(kInstrDllName);

  pe::PEFile pe_file;
  pe::Decomposer::DecomposedImage decomposed;
  reorder::Reorderer::Order order(pe_file, decomposed);
  reorder::RandomOrderGenerator order_generator(12345);
  std::vector<FilePath> trace_paths;
  reorder::Reorderer::Flags flags = 0;
  Reorderer reorderer(input_dll_path,
                      instr_dll_path,
                      trace_paths,
                      flags);
  ASSERT_TRUE(reorderer.Reorder(&order_generator, &order));
  ASSERT_TRUE(order.SerializeToJSON(order_file_path, true));

  relink::OrderRelinker relinker(order_file_path);
  ASSERT_TRUE(relinker.Relink(input_dll_path,
                              input_pdb_path,
                              output_dll_path,
                              output_pdb_path));
  ASSERT_NO_FATAL_FAILURE(CheckTestDll(output_dll_path));
}

TEST_F(OrderRelinkerTest, RelinkWithPadding) {
  FilePath temp_dir;
  ASSERT_NO_FATAL_FAILURE(CreateTemporaryDir(&temp_dir));
  FilePath output_dll_path = temp_dir.Append(kDllName);
  FilePath output_pdb_path = temp_dir.Append(kDllPdbName);
  FilePath order_file_path = temp_dir.Append(kOrderFileName);

  FilePath test_data_dir = GetExeRelativePath(kTestDataDir.value().c_str());
  FilePath input_dll_path = test_data_dir.Append(kDllName);
  FilePath input_pdb_path = test_data_dir.Append(kDllPdbName);
  FilePath instr_dll_path = test_data_dir.Append(kInstrDllName);

  pe::PEFile pe_file;
  pe::Decomposer::DecomposedImage decomposed;
  reorder::Reorderer::Order order(pe_file, decomposed);
  reorder::RandomOrderGenerator order_generator(12345);
  std::vector<FilePath> trace_paths;
  reorder::Reorderer::Flags flags = 0;
  Reorderer reorderer(input_dll_path,
                      instr_dll_path,
                      trace_paths,
                      flags);
  ASSERT_TRUE(reorderer.Reorder(&order_generator, &order));
  ASSERT_TRUE(order.SerializeToJSON(order_file_path, true));

  relink::OrderRelinker relinker(order_file_path);
  relinker.set_padding_length(32);
  ASSERT_TRUE(relinker.Relink(input_dll_path,
                              input_pdb_path,
                              output_dll_path,
                              output_pdb_path));
  ASSERT_NO_FATAL_FAILURE(CheckTestDll(output_dll_path));
}
<commit_msg>Fix a noop unittest<commit_after>// Copyright 2011 Google Inc.
//
// 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 "syzygy/relink/order_relinker.h"
#include "syzygy/reorder/random_order_generator.h"
#include "base/file_util.h"
#include "gtest/gtest.h"
#include "syzygy/pe/decomposer.h"
#include "syzygy/pe/pe_file.h"
#include "syzygy/pe/unittest_util.h"

class OrderRelinkerTest : public testing::PELibUnitTest {
 protected:
  static const FilePath kInstrDllName;
  static const FilePath kOrderFileName;
  static const FilePath kTestDataDir;
};

const FilePath OrderRelinkerTest::kOrderFileName(L"order_file.json");
const FilePath OrderRelinkerTest::kInstrDllName(L"instrumented_test_dll.dll");
const FilePath OrderRelinkerTest::kTestDataDir(L"test_data");

using reorder::RandomOrderGenerator;
using reorder::Reorderer;

TEST_F(OrderRelinkerTest, Relink) {
  FilePath temp_dir;
  ASSERT_NO_FATAL_FAILURE(CreateTemporaryDir(&temp_dir));
  FilePath output_dll_path = temp_dir.Append(kDllName);
  FilePath output_pdb_path = temp_dir.Append(kDllPdbName);
  FilePath order_file_path = temp_dir.Append(kOrderFileName);

  FilePath test_data_dir = GetExeRelativePath(kTestDataDir.value().c_str());
  FilePath input_dll_path = test_data_dir.Append(kDllName);
  FilePath input_pdb_path = test_data_dir.Append(kDllPdbName);
  FilePath instr_dll_path = test_data_dir.Append(kInstrDllName);

  pe::PEFile pe_file;
  pe::Decomposer::DecomposedImage decomposed;
  reorder::Reorderer::Order order(pe_file, decomposed);
  reorder::RandomOrderGenerator order_generator(12345);
  std::vector<FilePath> trace_paths;
  reorder::Reorderer::Flags flags = reorder::Reorderer::kFlagReorderCode |
      reorder::Reorderer::kFlagReorderData;
  Reorderer reorderer(input_dll_path,
                      instr_dll_path,
                      trace_paths,
                      flags);
  ASSERT_TRUE(reorderer.Reorder(&order_generator, &order));
  ASSERT_TRUE(order.SerializeToJSON(order_file_path, true));

  relink::OrderRelinker relinker(order_file_path);
  ASSERT_TRUE(relinker.Relink(input_dll_path,
                              input_pdb_path,
                              output_dll_path,
                              output_pdb_path));
  ASSERT_NO_FATAL_FAILURE(CheckTestDll(output_dll_path));
}

TEST_F(OrderRelinkerTest, RelinkWithPadding) {
  FilePath temp_dir;
  ASSERT_NO_FATAL_FAILURE(CreateTemporaryDir(&temp_dir));
  FilePath output_dll_path = temp_dir.Append(kDllName);
  FilePath output_pdb_path = temp_dir.Append(kDllPdbName);
  FilePath order_file_path = temp_dir.Append(kOrderFileName);

  FilePath test_data_dir = GetExeRelativePath(kTestDataDir.value().c_str());
  FilePath input_dll_path = test_data_dir.Append(kDllName);
  FilePath input_pdb_path = test_data_dir.Append(kDllPdbName);
  FilePath instr_dll_path = test_data_dir.Append(kInstrDllName);

  pe::PEFile pe_file;
  pe::Decomposer::DecomposedImage decomposed;
  reorder::Reorderer::Order order(pe_file, decomposed);
  reorder::RandomOrderGenerator order_generator(12345);
  std::vector<FilePath> trace_paths;
  reorder::Reorderer::Flags flags = reorder::Reorderer::kFlagReorderCode |
      reorder::Reorderer::kFlagReorderData;
  Reorderer reorderer(input_dll_path,
                      instr_dll_path,
                      trace_paths,
                      flags);
  ASSERT_TRUE(reorderer.Reorder(&order_generator, &order));
  ASSERT_TRUE(order.SerializeToJSON(order_file_path, true));

  relink::OrderRelinker relinker(order_file_path);
  relinker.set_padding_length(32);
  ASSERT_TRUE(relinker.Relink(input_dll_path,
                              input_pdb_path,
                              output_dll_path,
                              output_pdb_path));
  ASSERT_NO_FATAL_FAILURE(CheckTestDll(output_dll_path));
}
<|endoftext|>


<commit_before><commit_msg>hacker rank<commit_after><|endoftext|>


<commit_before><commit_msg>Fixed some bugs.<commit_after><|endoftext|>


<commit_before>/**
 *  @copyright Copyright 2017 The J-PET Framework Authors. 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 find a copy of the License in the LICENCE file.
 *
 * 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.
 *
 *  @file SinogramCreator.cpp
 */

#include "SinogramCreator.h"

SinogramCreator::SinogramCreator(const char* name) : JPetUserTask(name) {}

SinogramCreator::~SinogramCreator() {}

bool SinogramCreator::init()
{
  auto opts = getOptions();
  fOutputEvents = new JPetTimeWindow("JPetEvent");

  return true;
}

bool SinogramCreator::exec()
{
  assert(kNumberOfScintillatorsInReconstructionLayer % 2 == 0); // number of scintillators always should be parzysta

  int numberOfScintillatorsInHalf = kNumberOfScintillatorsInReconstructionLayer / 2;
  float reconstructionAngleDiff = kReconstructionEndAngle - kReconstructionStartAngle;
  float reconstructionAngleStep = (reconstructionAngleDiff) / static_cast<float>(numberOfScintillatorsInHalf);

  int maxThetaNumber = (reconstructionAngleDiff / reconstructionAngleStep) + 1;
  int maxDistanceNumber = std::floor(kReconstructionLayerRadius * 2 * (1.f / kReconstructionDistanceAccuracy)) + 1;
  if (fSinogram == nullptr) {
    fSinogram = new SinogramResultType(maxDistanceNumber, (std::vector<int>(maxThetaNumber)));
  }
  if (const auto& timeWindow = dynamic_cast<const JPetTimeWindow* const>(fEvent)) {
    unsigned int numberOfEventsInTimeWindow = timeWindow->getNumberOfEvents();
    for (unsigned int i = 0; i < numberOfEventsInTimeWindow; i++) {
      auto event = dynamic_cast<const JPetEvent&>(timeWindow->operator[](static_cast<int>(i)));
      auto hits = event.getHits();
      if (hits.size() == 2) {
        const auto& firstHit = hits[0];
        const auto& secondHit = hits[1];
        if (checkLayer(firstHit) && checkLayer(secondHit)) {
          for (float theta = kReconstructionStartAngle; theta < kReconstructionEndAngle; theta += reconstructionAngleStep) {
            float x = kReconstructionLayerRadius * std::cos(theta * (M_PI / 180));
            float y = kReconstructionLayerRadius * std::sin(theta * (M_PI / 180));
            std::pair<float, float> intersectionPoint = SinogramCreatorTools::lineIntersection(std::make_pair(-x, -y), std::make_pair(x, y),
                std::make_pair(firstHit.getPosX(), firstHit.getPosY()), std::make_pair(secondHit.getPosX(), secondHit.getPosY()));
            if (intersectionPoint.first != std::numeric_limits<float>::max() && intersectionPoint.second != std::numeric_limits<float>::max()) {
              float distance = SinogramCreatorTools::length2D(intersectionPoint.first, intersectionPoint.second);
              if (intersectionPoint.first < 0.f)
                distance = -distance;
              int distanceRound = std::floor((kReconstructionLayerRadius / kReconstructionDistanceAccuracy)
                                             + kReconstructionDistanceAccuracy)
                                  + std::floor((distance / kReconstructionDistanceAccuracy) + kReconstructionDistanceAccuracy);
              int thetaNumber = theta / reconstructionAngleStep;
              //if (thetaNumber >= maxThetaNumber || distanceRound >= maxDistanceNumber) {
              std::cout << "Theta: " << thetaNumber << " maxTheta: " << maxThetaNumber << " distanceRound: " << distanceRound << " maxDistanceRound: " << maxDistanceNumber << " distance: " << distance << " ix: " << intersectionPoint.first << " iy: " << intersectionPoint.second << " x1: " << firstHit.getPosX() << " y1: " << firstHit.getPosY() << " x2: " << secondHit.getPosX() << " y2: " << secondHit.getPosY() << std::endl;
              //}
              fSinogram->at(distanceRound).at(thetaNumber)++;
            }
          }
        }
      }
    }
  } else {
    ERROR("Returned event is not TimeWindow");
    return false;
  }
  return true;
}

bool SinogramCreator::checkLayer(const JPetHit& hit)
{
  return hit.getBarrelSlot().getLayer().getID() == 1;
}

bool SinogramCreator::terminate()
{
  const auto outFile = "sinogram.ppm";
  std::ofstream res(outFile);
  res << "P2" << std::endl;
  res << (*fSinogram)[0].size() << " " << fSinogram->size() << std::endl;
  res << "255" << std::endl;
  for (unsigned int i = 0; i < fSinogram->size(); i++) {
    for (unsigned int j = 0; j < (*fSinogram)[0].size(); j++) {
      res << static_cast<int>((*fSinogram)[i][j]) << " ";
    }
    res << std::endl;
  }
  res.close();
  return true;
}
<commit_msg>Add condition to filter events with radius greather then reconstruction layer<commit_after>/**
 *  @copyright Copyright 2017 The J-PET Framework Authors. 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 find a copy of the License in the LICENCE file.
 *
 * 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.
 *
 *  @file SinogramCreator.cpp
 */

#include "SinogramCreator.h"

SinogramCreator::SinogramCreator(const char* name) : JPetUserTask(name) {}

SinogramCreator::~SinogramCreator() {}

bool SinogramCreator::init()
{
  auto opts = getOptions();
  fOutputEvents = new JPetTimeWindow("JPetEvent");

  return true;
}

bool SinogramCreator::exec()
{
  assert(kNumberOfScintillatorsInReconstructionLayer % 2 == 0); // number of scintillators always should be parzysta

  int numberOfScintillatorsInHalf = kNumberOfScintillatorsInReconstructionLayer / 2;
  float reconstructionAngleDiff = kReconstructionEndAngle - kReconstructionStartAngle;
  float reconstructionAngleStep = (reconstructionAngleDiff) / static_cast<float>(numberOfScintillatorsInHalf);

  int maxThetaNumber = (reconstructionAngleDiff / reconstructionAngleStep) + 1;
  int maxDistanceNumber = std::floor(kReconstructionLayerRadius * 2 * (1.f / kReconstructionDistanceAccuracy)) + 1;
  if (fSinogram == nullptr) {
    fSinogram = new SinogramResultType(maxDistanceNumber, (std::vector<int>(maxThetaNumber)));
  }
  if (const auto& timeWindow = dynamic_cast<const JPetTimeWindow* const>(fEvent)) {
    unsigned int numberOfEventsInTimeWindow = timeWindow->getNumberOfEvents();
    for (unsigned int i = 0; i < numberOfEventsInTimeWindow; i++) {
      auto event = dynamic_cast<const JPetEvent&>(timeWindow->operator[](static_cast<int>(i)));
      auto hits = event.getHits();
      if (hits.size() == 2) {
        const auto& firstHit = hits[0];
        const auto& secondHit = hits[1];
        if (checkLayer(firstHit) && checkLayer(secondHit)) {
          for (float theta = kReconstructionStartAngle; theta < kReconstructionEndAngle; theta += reconstructionAngleStep) {
            float x = kReconstructionLayerRadius * std::cos(theta * (M_PI / 180));
            float y = kReconstructionLayerRadius * std::sin(theta * (M_PI / 180));
            std::pair<float, float> intersectionPoint = SinogramCreatorTools::lineIntersection(std::make_pair(-x, -y), std::make_pair(x, y),
                std::make_pair(firstHit.getPosX(), firstHit.getPosY()), std::make_pair(secondHit.getPosX(), secondHit.getPosY()));
            if (intersectionPoint.first != std::numeric_limits<float>::max() && intersectionPoint.second != std::numeric_limits<float>::max()) {
              float distance = SinogramCreatorTools::length2D(intersectionPoint.first, intersectionPoint.second);
              if (distance >= kReconstructionLayerRadius) // if distance is greather then our max reconstuction layer radius, it cant be placed in sinogram
                continue;
              if (intersectionPoint.first < 0.f)
                distance = -distance;
              int distanceRound = std::floor((kReconstructionLayerRadius / kReconstructionDistanceAccuracy)
                                             + kReconstructionDistanceAccuracy)
                                  + std::floor((distance / kReconstructionDistanceAccuracy) + kReconstructionDistanceAccuracy);
              int thetaNumber = theta / reconstructionAngleStep;
              //if (thetaNumber >= maxThetaNumber || distanceRound >= maxDistanceNumber) {
              std::cout << "Theta: " << thetaNumber << " maxTheta: " << maxThetaNumber << " distanceRound: " << distanceRound << " maxDistanceRound: " << maxDistanceNumber << " distance: " << distance << " ix: " << intersectionPoint.first << " iy: " << intersectionPoint.second << " x1: " << firstHit.getPosX() << " y1: " << firstHit.getPosY() << " x2: " << secondHit.getPosX() << " y2: " << secondHit.getPosY() << std::endl;
              //}
              fSinogram->at(distanceRound).at(thetaNumber)++;
            }
          }
        }
      }
    }
  } else {
    ERROR("Returned event is not TimeWindow");
    return false;
  }
  return true;
}

bool SinogramCreator::checkLayer(const JPetHit& hit)
{
  return hit.getBarrelSlot().getLayer().getID() == 1;
}

bool SinogramCreator::terminate()
{
  const auto outFile = "sinogram.ppm";
  std::ofstream res(outFile);
  res << "P2" << std::endl;
  res << (*fSinogram)[0].size() << " " << fSinogram->size() << std::endl;
  res << "255" << std::endl;
  for (unsigned int i = 0; i < fSinogram->size(); i++) {
    for (unsigned int j = 0; j < (*fSinogram)[0].size(); j++) {
      res << static_cast<int>((*fSinogram)[i][j]) << " ";
    }
    res << std::endl;
  }
  res.close();
  return true;
}
<|endoftext|>


<commit_before>#include <Poco/Exception.h>

#include "ui/PlaceHandler.h"
#include "ui/Serializing.h"

using namespace std;
using namespace Poco;
using namespace BeeeOn;
using namespace BeeeOn::UI;

PlaceHandler::PlaceHandler()
{
	injector<PlaceHandler, PlaceService>("placeService",
			&PlaceHandler::setPlaceService);
	injector<PlaceHandler, IdentityService>("identityService",
			&PlaceHandler::setIdentityService);
	injector<PlaceHandler, PlaceAccessPolicy>("accessPolicy",
			&PlaceHandler::setAccessPolicy);
}

const string PlaceHandler::handleCreate(istream &in,
		const VerifiedIdentityID &identityID)
{
	VerifiedIdentity identity(identityID);
	if (!m_identityService->fetch(identity))
		throw InvalidAccessException("no such identity");

	Place place;
	deserialize(in, place);

	m_placeService->create(place, identity.identity());
	return serialize(place);
}

const string PlaceHandler::handleUpdate(istream &in,
		const UserID &userId,
		const string &placeId)
{
	Place place(PlaceID::parse(placeId));
	User user(userId);

	m_accessPolicy->assureUpdate(user, place);

	if (!m_placeService->fetch(place))
		return "";

	deserialize(in, place);

	if (!m_placeService->update(place)) {
		throw Exception("failed to update place: "
				+ place.id().toString());
	}

	return serialize(place);
}

const string PlaceHandler::handleGet(const UserID &userId,
		const string &placeId)
{
	Place place(PlaceID::parse(placeId));
	User user(userId);

	m_accessPolicy->assureGet(user, place);

	if (!m_placeService->fetch(place)) {
		return "";
	}

	return serialize(place);
}

const string PlaceHandler::handleDelete(const UserID &userId,
		const string &placeId)
{
	Place place(PlaceID::parse(placeId));
	User user(userId);

	m_accessPolicy->assureRemove(user, place);

	if (!m_placeService->fetch(place))
		return "";

	if (!m_placeService->remove(place, user))
		return "";

	return serialize(place);
}

const string PlaceHandler::handleGetAll(const UserID &userId)
{
	User user(userId);
	std::vector<Place> places;

	m_placeService->fetchAccessible(places, user);
	return serialize(places);
}

BEEEON_OBJECT(PlaceHandler, BeeeOn::UI::PlaceHandler)
<commit_msg>PlaceHandler: avoid redundant fetch<commit_after>#include <Poco/Exception.h>

#include "ui/PlaceHandler.h"
#include "ui/Serializing.h"

using namespace std;
using namespace Poco;
using namespace BeeeOn;
using namespace BeeeOn::UI;

PlaceHandler::PlaceHandler()
{
	injector<PlaceHandler, PlaceService>("placeService",
			&PlaceHandler::setPlaceService);
	injector<PlaceHandler, IdentityService>("identityService",
			&PlaceHandler::setIdentityService);
	injector<PlaceHandler, PlaceAccessPolicy>("accessPolicy",
			&PlaceHandler::setAccessPolicy);
}

const string PlaceHandler::handleCreate(istream &in,
		const VerifiedIdentityID &identityID)
{
	VerifiedIdentity identity(identityID);
	if (!m_identityService->fetch(identity))
		throw InvalidAccessException("no such identity");

	Place place;
	deserialize(in, place);

	m_placeService->create(place, identity.identity());
	return serialize(place);
}

const string PlaceHandler::handleUpdate(istream &in,
		const UserID &userId,
		const string &placeId)
{
	Place place(PlaceID::parse(placeId));
	User user(userId);

	m_accessPolicy->assureUpdate(user, place);

	if (!m_placeService->fetch(place))
		return "";

	deserialize(in, place);

	if (!m_placeService->update(place)) {
		throw Exception("failed to update place: "
				+ place.id().toString());
	}

	return serialize(place);
}

const string PlaceHandler::handleGet(const UserID &userId,
		const string &placeId)
{
	Place place(PlaceID::parse(placeId));
	User user(userId);

	m_accessPolicy->assureGet(user, place);

	if (!m_placeService->fetch(place)) {
		return "";
	}

	return serialize(place);
}

const string PlaceHandler::handleDelete(const UserID &userId,
		const string &placeId)
{
	Place place(PlaceID::parse(placeId));
	User user(userId);

	m_accessPolicy->assureRemove(user, place);

	if (!m_placeService->remove(place, user))
		return "";

	return serialize(place);
}

const string PlaceHandler::handleGetAll(const UserID &userId)
{
	User user(userId);
	std::vector<Place> places;

	m_placeService->fetchAccessible(places, user);
	return serialize(places);
}

BEEEON_OBJECT(PlaceHandler, BeeeOn::UI::PlaceHandler)
<|endoftext|>


<commit_before><commit_msg>Replace random feature id generation with deterministic<commit_after><|endoftext|>