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

  Program:   Medical Imaging & Interaction Toolkit
  Module:    $RCSfile$
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/ for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkDisplayVectorInteractor.h"
#include "mitkOperation.h"
#include "mitkDisplayCoordinateOperation.h"
#include "mitkDisplayPositionEvent.h"
#include "mitkInteractionConst.h"
#include "mitkAction.h"

//##ModelId=3EF222410127
void mitk::DisplayVectorInteractor::ExecuteOperation(Operation* operation)
{
  DisplayCoordinateOperation* dcOperation = static_cast<DisplayCoordinateOperation*>(operation);
  if(dcOperation==NULL) return;

  switch(operation->GetOperationType())
  {
  case OpSELECTPOINT:
    m_Sender=dcOperation->GetRenderer();
    m_StartDisplayCoordinate=dcOperation->GetStartDisplayCoordinate();
    m_LastDisplayCoordinate=dcOperation->GetLastDisplayCoordinate();
    m_CurrentDisplayCoordinate=dcOperation->GetCurrentDisplayCoordinate();
    std::cout << m_CurrentDisplayCoordinate << std::endl;

    std::cout<<"Message from DisplayVectorInteractor.cpp::ExecuteOperation() : "
      << "StartDisplayCoordinate:" <<     m_StartDisplayCoordinate
      << "LastDisplayCoordinate:" <<      m_LastDisplayCoordinate
      << "CurrentDisplayCoordinate:" <<   m_CurrentDisplayCoordinate
      << std::endl;

    break;
  }

}

//##ModelId=3EF2224401CB
bool mitk::DisplayVectorInteractor::ExecuteAction(Action* action, mitk::StateEvent const* stateEvent)
{
  bool ok=false;

  const DisplayPositionEvent* posEvent=dynamic_cast<const DisplayPositionEvent*>(stateEvent->GetEvent());
  if(posEvent==NULL) return false;

  int actionId = action->GetActionId();
  //initzoom and initmove is the same!
  if (actionId == AcINITZOOM)
    actionId = AcINITMOVE;
  switch(actionId)
  {
  //case 0:
  //  {
  //    DisplayCoordinateOperation* doOp = new mitk::DisplayCoordinateOperation(OpTEST,  posEvent->GetSender(), posEvent->GetDisplayPosition(), posEvent->GetDisplayPosition(), posEvent->GetDisplayPosition());
  //    if (m_UndoEnabled)	//write to UndoMechanism
  //    {
  //      DisplayCoordinateOperation* undoOp = new DisplayCoordinateOperation(OpTEST, m_Sender, m_StartDisplayCoordinate, m_LastDisplayCoordinate, m_CurrentDisplayCoordinate);
  //
  //
  //      OperationEvent *operationEvent = new OperationEvent(this, doOp, undoOp);
  //      m_UndoController->SetOperationEvent(operationEvent);
  //    }
  //
  //    //execute the Operation
  //    m_Destination->ExecuteOperation(doOp);
  //    ok = true;
  //    break;
  //  }
  case AcINITMOVE:
    {
      DisplayCoordinateOperation* doOp = new mitk::DisplayCoordinateOperation(OpSELECTPOINT,  posEvent->GetSender(), posEvent->GetDisplayPosition(), posEvent->GetDisplayPosition(), posEvent->GetDisplayPosition());
      if (m_UndoEnabled)	//write to UndoMechanism
      {
        DisplayCoordinateOperation* undoOp = new DisplayCoordinateOperation(OpSELECTPOINT, m_Sender, m_StartDisplayCoordinate, m_LastDisplayCoordinate, m_CurrentDisplayCoordinate);

        OperationEvent *operationEvent = new OperationEvent(this, doOp, undoOp);
        m_UndoController->SetOperationEvent(operationEvent);
      }

      //execute the Operation
      this->ExecuteOperation(doOp);
      ok = true;
      break;
    }
  case AcMOVE:
    {
      DisplayCoordinateOperation* doOp = new DisplayCoordinateOperation(OpMOVE,  m_Sender, m_StartDisplayCoordinate, m_CurrentDisplayCoordinate, posEvent->GetDisplayPosition());
      if (m_UndoEnabled)	//write to UndoMechanism
      {
        DisplayCoordinateOperation* undoOp = new mitk::DisplayCoordinateOperation(OpMOVE,  posEvent->GetSender(), m_StartDisplayCoordinate, m_LastDisplayCoordinate, m_CurrentDisplayCoordinate);

        OperationEvent *operationEvent = new OperationEvent(m_Destination, doOp, undoOp);
        m_UndoController->SetOperationEvent(operationEvent);
      }

      //make Operation
      m_LastDisplayCoordinate=m_CurrentDisplayCoordinate;
      m_CurrentDisplayCoordinate=posEvent->GetDisplayPosition();
      std::cout << m_CurrentDisplayCoordinate << std::endl;

      //execute the Operation
      m_Destination->ExecuteOperation(doOp);
      ok = true;
      break;
    }
  case AcZOOM:
    {
      DisplayCoordinateOperation* doOp = new DisplayCoordinateOperation(OpZOOM,  m_Sender, m_StartDisplayCoordinate, m_CurrentDisplayCoordinate, posEvent->GetDisplayPosition());
      if (m_UndoEnabled)	//write to UndoMechanism
      {
        DisplayCoordinateOperation* undoOp = new mitk::DisplayCoordinateOperation(OpZOOM,  posEvent->GetSender(), m_StartDisplayCoordinate, m_LastDisplayCoordinate, m_CurrentDisplayCoordinate);

        OperationEvent *operationEvent = new OperationEvent(m_Destination, doOp, undoOp);
        m_UndoController->SetOperationEvent(operationEvent);
      }

      //make Operation
      m_LastDisplayCoordinate=m_CurrentDisplayCoordinate;
      m_CurrentDisplayCoordinate=posEvent->GetDisplayPosition();
      std::cout << m_CurrentDisplayCoordinate << std::endl;

      //execute the Operation
      m_Destination->ExecuteOperation(doOp);
      ok = true;
      break;
    }
  default:
    ok = false;
    break;
  }
  return ok;
}

//##ModelId=3EF2229F00F0
mitk::DisplayVectorInteractor::DisplayVectorInteractor(const char * type, mitk::OperationActor* destination)
  : mitk::StateMachine(type), m_Sender(NULL), m_Destination(destination)
{
  m_StartDisplayCoordinate.Fill(0);
  m_LastDisplayCoordinate.Fill(0);
  m_CurrentDisplayCoordinate.Fill(0);

  if(m_Destination==NULL)
    m_Destination=this;
}

//##ModelId=3EF2229F010E
mitk::DisplayVectorInteractor::~DisplayVectorInteractor()
{
}

<commit_msg>added action sendcoordinates<commit_after>/*=========================================================================

  Program:   Medical Imaging & Interaction Toolkit
  Module:    $RCSfile$
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/ for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkDisplayVectorInteractor.h"
#include "mitkOperation.h"
#include "mitkDisplayCoordinateOperation.h"
#include "mitkDisplayPositionEvent.h"
#include "mitkInteractionConst.h"
#include "mitkAction.h"

//##ModelId=3EF222410127
void mitk::DisplayVectorInteractor::ExecuteOperation(Operation* operation)
{
  DisplayCoordinateOperation* dcOperation = static_cast<DisplayCoordinateOperation*>(operation);
  if(dcOperation==NULL) return;

  switch(operation->GetOperationType())
  {
  case OpSELECTPOINT:
    m_Sender=dcOperation->GetRenderer();
    m_StartDisplayCoordinate=dcOperation->GetStartDisplayCoordinate();
    m_LastDisplayCoordinate=dcOperation->GetLastDisplayCoordinate();
    m_CurrentDisplayCoordinate=dcOperation->GetCurrentDisplayCoordinate();
    std::cout << m_CurrentDisplayCoordinate << std::endl;

    std::cout<<"Message from DisplayVectorInteractor.cpp::ExecuteOperation() : "
      << "StartDisplayCoordinate:" <<     m_StartDisplayCoordinate
      << "LastDisplayCoordinate:" <<      m_LastDisplayCoordinate
      << "CurrentDisplayCoordinate:" <<   m_CurrentDisplayCoordinate
      << std::endl;

    break;
  }

}

//##ModelId=3EF2224401CB
bool mitk::DisplayVectorInteractor::ExecuteAction(Action* action, mitk::StateEvent const* stateEvent)
{
  bool ok=false;

  const DisplayPositionEvent* posEvent=dynamic_cast<const DisplayPositionEvent*>(stateEvent->GetEvent());
  if(posEvent==NULL) return false;

  int actionId = action->GetActionId();
  //initzoom and initmove is the same!
  if (actionId == AcINITZOOM)
    actionId = AcINITMOVE;
  switch(actionId)
  {
  //case 0:
  //  {
  //    DisplayCoordinateOperation* doOp = new mitk::DisplayCoordinateOperation(OpTEST,  posEvent->GetSender(), posEvent->GetDisplayPosition(), posEvent->GetDisplayPosition(), posEvent->GetDisplayPosition());
  //    if (m_UndoEnabled)	//write to UndoMechanism
  //    {
  //      DisplayCoordinateOperation* undoOp = new DisplayCoordinateOperation(OpTEST, m_Sender, m_StartDisplayCoordinate, m_LastDisplayCoordinate, m_CurrentDisplayCoordinate);
  //
  //
  //      OperationEvent *operationEvent = new OperationEvent(this, doOp, undoOp);
  //      m_UndoController->SetOperationEvent(operationEvent);
  //    }
  //
  //    //execute the Operation
  //    m_Destination->ExecuteOperation(doOp);
  //    ok = true;
  //    break;
  //  }
  case AcSENDCOORDINATES:
    {
      DisplayCoordinateOperation* doOp = new mitk::DisplayCoordinateOperation(OpSENDCOORDINATES,  posEvent->GetSender(), posEvent->GetDisplayPosition(), posEvent->GetDisplayPosition(), posEvent->GetDisplayPosition());
      m_Destination->ExecuteOperation(doOp);
      ok = true;
      break;
    }
  case AcINITMOVE:
    {
      DisplayCoordinateOperation* doOp = new mitk::DisplayCoordinateOperation(OpSELECTPOINT,  posEvent->GetSender(), posEvent->GetDisplayPosition(), posEvent->GetDisplayPosition(), posEvent->GetDisplayPosition());
      if (m_UndoEnabled)	//write to UndoMechanism
      {
        DisplayCoordinateOperation* undoOp = new DisplayCoordinateOperation(OpSELECTPOINT, m_Sender, m_StartDisplayCoordinate, m_LastDisplayCoordinate, m_CurrentDisplayCoordinate);

        OperationEvent *operationEvent = new OperationEvent(this, doOp, undoOp);
        m_UndoController->SetOperationEvent(operationEvent);
      }

      //execute the Operation
      this->ExecuteOperation(doOp);
      ok = true;
      break;
    }
  case AcMOVE:
    {
      DisplayCoordinateOperation* doOp = new DisplayCoordinateOperation(OpMOVE,  m_Sender, m_StartDisplayCoordinate, m_CurrentDisplayCoordinate, posEvent->GetDisplayPosition());
      if (m_UndoEnabled)	//write to UndoMechanism
      {
        DisplayCoordinateOperation* undoOp = new mitk::DisplayCoordinateOperation(OpMOVE,  posEvent->GetSender(), m_StartDisplayCoordinate, m_LastDisplayCoordinate, m_CurrentDisplayCoordinate);

        OperationEvent *operationEvent = new OperationEvent(m_Destination, doOp, undoOp);
        m_UndoController->SetOperationEvent(operationEvent);
      }

      //make Operation
      m_LastDisplayCoordinate=m_CurrentDisplayCoordinate;
      m_CurrentDisplayCoordinate=posEvent->GetDisplayPosition();
      std::cout << m_CurrentDisplayCoordinate << std::endl;

      //execute the Operation
      m_Destination->ExecuteOperation(doOp);
      ok = true;
      break;
    }
  case AcZOOM:
    {
      DisplayCoordinateOperation* doOp = new DisplayCoordinateOperation(OpZOOM,  m_Sender, m_StartDisplayCoordinate, m_CurrentDisplayCoordinate, posEvent->GetDisplayPosition());
      if (m_UndoEnabled)	//write to UndoMechanism
      {
        DisplayCoordinateOperation* undoOp = new mitk::DisplayCoordinateOperation(OpZOOM,  posEvent->GetSender(), m_StartDisplayCoordinate, m_LastDisplayCoordinate, m_CurrentDisplayCoordinate);

        OperationEvent *operationEvent = new OperationEvent(m_Destination, doOp, undoOp);
        m_UndoController->SetOperationEvent(operationEvent);
      }

      //make Operation
      m_LastDisplayCoordinate=m_CurrentDisplayCoordinate;
      m_CurrentDisplayCoordinate=posEvent->GetDisplayPosition();
      std::cout << m_CurrentDisplayCoordinate << std::endl;

      //execute the Operation
      m_Destination->ExecuteOperation(doOp);
      ok = true;
      break;
    }
  default:
    ok = false;
    break;
  }
  return ok;
}

//##ModelId=3EF2229F00F0
mitk::DisplayVectorInteractor::DisplayVectorInteractor(const char * type, mitk::OperationActor* destination)
  : mitk::StateMachine(type), m_Sender(NULL), m_Destination(destination)
{
  m_StartDisplayCoordinate.Fill(0);
  m_LastDisplayCoordinate.Fill(0);
  m_CurrentDisplayCoordinate.Fill(0);

  if(m_Destination==NULL)
    m_Destination=this;
}

//##ModelId=3EF2229F010E
mitk::DisplayVectorInteractor::~DisplayVectorInteractor()
{
}

<|endoftext|>


<commit_before>/*!
 * \file reference_count_atomic.cpp
 * \brief file reference_count_atomic.cpp
 *
 * Copyright 2016 by Intel.
 *
 * Contact: kevin.rogovin@intel.com
 *
 * 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 Kevin Rogovin <kevin.rogovin@intel.com>
 *
 */

#ifdef _WIN32
  #define FASTUIDRAW_USE_DETAIL_ATOMIC
#endif

#ifndef FASTUIDRAW_USE_DETAIL_ATOMIC
  #include <boost/atomic.hpp>
  typedef boost::atomic<int> atomic_int;
#else
  #include <boost/detail/atomic_count.hpp>
  typedef boost::detail::atomic_count atomic_int;
#endif

#include <fastuidraw/util/fastuidraw_memory.hpp>
#include <fastuidraw/util/reference_count_atomic.hpp>

namespace
{
  class ReferenceCountAtomicPrivate
  {
  public:
    ReferenceCountAtomicPrivate(void):
      m_reference_count(0)
    {}

    atomic_int m_reference_count;
  };
}

//////////////////////////////////
// fastuidraw::reference_count_atomic methods
fastuidraw::reference_count_atomic::
reference_count_atomic(void)
{
  m_d = FASTUIDRAWnew ReferenceCountAtomicPrivate();
}

fastuidraw::reference_count_atomic::
~reference_count_atomic()
{
  ReferenceCountAtomicPrivate *d;

  d = reinterpret_cast<ReferenceCountAtomicPrivate*>(m_d);
  FASTUIDRAWdelete(d);
  m_d = NULL;
}

void
fastuidraw::reference_count_atomic::
add_reference(void)
{
  ReferenceCountAtomicPrivate *d;

  d = reinterpret_cast<ReferenceCountAtomicPrivate*>(m_d);
  #ifndef FASTUIDRAW_USE_DETAIL_ATOMIC
    {
      d->m_reference_count.fetch_add(1, boost::memory_order_relaxed);
    }
  #else
    {
      ++(d->m_reference_count);
    }
  #endif
}

bool
fastuidraw::reference_count_atomic::
remove_reference(void)
{
  ReferenceCountAtomicPrivate *d;
  bool return_value;

  d = reinterpret_cast<ReferenceCountAtomicPrivate*>(m_d);
  #ifndef FASTUIDRAW_USE_DETAIL_ATOMIC
    {
      if (d->m_reference_count.fetch_sub(1, boost::memory_order_release) == 1)
        {
          boost::atomic_thread_fence(boost::memory_order_acquire);
          return_value = true;
        }
      else
        {
          return_value = false;
        }
    }
  #else
    {
      long v;
      v = --(d->m_reference_count);
      return_value = (v == 0);
    }
  #endif

  return return_value;
}
<commit_msg>fastuidraw/util: use BOOST_VERSION to decide if boost::atomic is available<commit_after>/*!
 * \file reference_count_atomic.cpp
 * \brief file reference_count_atomic.cpp
 *
 * Copyright 2016 by Intel.
 *
 * Contact: kevin.rogovin@intel.com
 *
 * 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 Kevin Rogovin <kevin.rogovin@intel.com>
 *
 */

#include <boost/version.hpp>

#if (BOOST_VERSION < 105300)
  #define FASTUIDRAW_USE_DETAIL_ATOMIC
#endif

#ifndef FASTUIDRAW_USE_DETAIL_ATOMIC
  #include <boost/atomic.hpp>
  typedef boost::atomic<int> atomic_int;
#else
  #include <boost/detail/atomic_count.hpp>
  typedef boost::detail::atomic_count atomic_int;
#endif

#include <fastuidraw/util/fastuidraw_memory.hpp>
#include <fastuidraw/util/reference_count_atomic.hpp>

namespace
{
  class ReferenceCountAtomicPrivate
  {
  public:
    ReferenceCountAtomicPrivate(void):
      m_reference_count(0)
    {}

    atomic_int m_reference_count;
  };
}

//////////////////////////////////
// fastuidraw::reference_count_atomic methods
fastuidraw::reference_count_atomic::
reference_count_atomic(void)
{
  m_d = FASTUIDRAWnew ReferenceCountAtomicPrivate();
}

fastuidraw::reference_count_atomic::
~reference_count_atomic()
{
  ReferenceCountAtomicPrivate *d;

  d = reinterpret_cast<ReferenceCountAtomicPrivate*>(m_d);
  FASTUIDRAWdelete(d);
  m_d = NULL;
}

void
fastuidraw::reference_count_atomic::
add_reference(void)
{
  ReferenceCountAtomicPrivate *d;

  d = reinterpret_cast<ReferenceCountAtomicPrivate*>(m_d);
  #ifndef FASTUIDRAW_USE_DETAIL_ATOMIC
    {
      d->m_reference_count.fetch_add(1, boost::memory_order_relaxed);
    }
  #else
    {
      ++(d->m_reference_count);
    }
  #endif
}

bool
fastuidraw::reference_count_atomic::
remove_reference(void)
{
  ReferenceCountAtomicPrivate *d;
  bool return_value;

  d = reinterpret_cast<ReferenceCountAtomicPrivate*>(m_d);
  #ifndef FASTUIDRAW_USE_DETAIL_ATOMIC
    {
      if (d->m_reference_count.fetch_sub(1, boost::memory_order_release) == 1)
        {
          boost::atomic_thread_fence(boost::memory_order_acquire);
          return_value = true;
        }
      else
        {
          return_value = false;
        }
    }
  #else
    {
      long v;
      v = --(d->m_reference_count);
      return_value = (v == 0);
    }
  #endif

  return return_value;
}
<|endoftext|>


<commit_before>/* -*- mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */

/* linbox/fflapack/fflapack_charpoly_kgfast.inl
 * Copyright (C) 2004 Clement Pernet
 *
 * Written by Clement Pernet <Clement.Pernet@imag.fr>
 *
 * See COPYING for license information.
 */

#ifndef MIN
#define MIN(a,b) (a<b)?a:b
#endif

//---------------------------------------------------------------------
// CharPoly: Compute the characteristic polynomial of A using
// Keller-Gehrig's fast algorithm. A must be generic.
//---------------------------------------------------------------------
using namespace std;
template <class Field, class Polynomial>
int
LinBox::FFLAPACK::KGFast ( const Field& F, std::list<Polynomial>& charp,
			   const size_t N,
			   typename Field::Element * A, const size_t lda ){

	static typename Field::Element one, zero, mone;
	F.init(one, 1UL);
	F.neg(mone, one);
	F.init(zero, 0UL);
	size_t mc=N>>1; // Matrix A is transformed into a mc_Frobenius form
        size_t mb=N-mc;
	size_t r;
	typename Field::Element * C, *B;

	while ( mc > 0 ) {
// 		cerr<<"Boucle1: mc,mb,N="<<mc<<" "<<mb<<" "<<N<<endl;
// 		write_field( F, cerr, A, N, N, lda );
		size_t j=0;
		C = A + (N-mc);
		cerr<<endl<<"mc="<<mc<<":";
		while ( (j+1)*mc < N ) {
			mb = MIN ( mb, N-(j+1)*mc );
// 			cerr<<"Boucle2: j,mb="<<j<<" "<<mb<<endl;
// 			write_field( F, cerr, A, N, N, lda );
			B = A + (N-mc-mb);

			// B1 <- C1^-1.B1
			typename Field::Element * LUP = new typename Field::Element[mc*mc];
			for (size_t i=0; i<mc; ++i)
				fcopy( F, mc, LUP+i*mc, 1, C+i*lda, 1);
			size_t * P = new size_t[mc];
			size_t * Q = new size_t[mc];

			if ( r = LUdivine( F, FflasNonUnit, mc, mc,
				      LUP, mc, P, FflapackLQUP, Q ) < mc )
				return -1;
// 			cerr<<"LUP="<<endl;
// 			write_field( F, cerr, LUP, mc, mc, mc );
                        cerr<<" "<<r;
			ftrsm(F, FflasLeft, FflasLower, FflasNoTrans, FflasUnit,
			      mc, mb, one, LUP, mc , B, lda);
			ftrsm(F, FflasLeft, FflasUpper, FflasNoTrans, FflasNonUnit,
			      mc, mb, one, LUP, mc , B, lda);
			delete[] LUP;
			applyP( F, FflasLeft, FflasTrans, mb, 0, mc, B, lda, P );

// 			cerr<<"Apres B1<-C1^-1"<<endl;
// 			write_field( F, cerr, A, N, N, lda );

			// B2 <- B2 - C2.B1
			fgemm(F, FflasNoTrans, FflasNoTrans, N-mc, mb, mc,
			      mone, C+mc*lda, lda, B, lda,
			      one, B+mc*lda, lda);

// 			cerr<<"Apres B2<-B2-C2.B1"<<endl;
//                         write_field( F, cerr, A, N, N, lda );

			// Shifting B: B1;B2 -> B2;B1
			typename Field::Element * tmp = new typename Field::Element[mc*mb];
			for (size_t i=0; i<mc; ++i)
				fcopy( F, mb, tmp+i*mb, 1, B+i*lda, 1);
			for (size_t i=mc; i<N; ++i)
				fcopy( F, mb, B+(i-mc)*lda, 1, B+i*lda, 1);
			for (size_t i=0; i<mc; ++i)
				fcopy( F, mb, B+(i+N-mc)*lda, 1, tmp+i*mb, 1);
			delete[] tmp;
// 			cerr<<"Apres shift de B"<<endl;
//                         write_field( F, cerr, A, N, N, lda );

			// C3 <- B3.C1 + C3
			fgemm(F, FflasNoTrans, FflasNoTrans, (j+1)*mc, mc, mb,
			      one, B+(N-(j+1)*mc)*lda, lda, C+(N-(j+1)*mc-mb)*lda, lda,
			      one, C+(N-(j+1)*mc)*lda, lda);
			// cerr<<"C3 <- B3.C1 + C3: B3="<<endl;
//                         write_field( F, cerr, B+(N-(j+1)*mc)*lda, (j+1)*mc, mb, lda );
// 			cerr<<"C3 <- B3.C1 + C3: C1"<<endl;
//                         write_field( F, cerr,  C+(N-(j+1)*mc-mb)*lda, mb, mc, lda );
// 			cerr<<"C3 <- B3.C1 + C3: C3="<<endl;
//                         write_field( F, cerr, C+(N-(j+1)*mc)*lda, (j+1)*mc, mc, lda );

			int lambda = N - mb - (j+1)*mc;
			if ( int(mb) < lambda ){

// 				cerr<<"mb<lambda"<<endl;
				typename Field::Element * tmp = new typename Field::Element[lambda*mc];

				// tmp <- C1
				for (int i=0; i<lambda; ++i)
					fcopy( F, mc, tmp+i*mc, 1, C+i*lda, 1);

				// C1' <- B1.C2
				fgemm(F, FflasNoTrans, FflasNoTrans, mb, mc, mb,
				      one, B, lda, C+lambda*lda, lda,
				      zero, C, lda);

				// tmp <- B2.C2 + tmp
				fgemm(F, FflasNoTrans, FflasNoTrans, lambda, mc, mb,
				      one, B+mb*lda, lda, C+lambda*lda, lda,
				      one, tmp, mc);

				// C2' <- tmp
				for (int i=0; i<lambda; ++i)
					fcopy( F, mc, C+mb*lda+i*lda, 1, tmp+i*mc, 1);
				delete[] tmp;
			}
			else if ( lambda > 0 ){
// 				cerr<<"lambda>0"<<endl;

				typename Field::Element * tmp = new typename Field::Element[mb*mc];
				// C1 <- B2.C2 + C1
				fgemm(F, FflasNoTrans, FflasNoTrans, lambda, mc, mb,
				      one, B+mb*lda, lda, C+lambda*lda, lda,
				      one, C, lda);

				// tmp <-B1.C2
				fgemm(F, FflasNoTrans, FflasNoTrans, mb, mc, mb,
				      one, B, lda, C+lambda*lda, lda,
				      zero, tmp, mc);

				// C2' <- C1
				for (int i=0; i<lambda; ++i)
					fcopy( F, mc, C+mb*lda+i*lda, 1, C+i*lda, 1);

				// C1' <- tmp
				for (size_t i=0; i<mb; ++i)
					fcopy( F, mc, C+i*lda, 1, tmp+i*mc, 1);
				delete[] tmp;
			}
			else{
// 				cerr<<"lambda<0"<<endl;
				mb = N - (j+1)*mc;
				typename Field::Element * tmp = new typename Field::Element[mb*mc];

				// tmp <-B1.C1
				fgemm(F, FflasNoTrans, FflasNoTrans, mb, mc, mb,
				      one, B, lda, C, lda,
				      zero, tmp, mc);

				// C1' <- tmp
				for (size_t i=0; i<mb; ++i)
					fcopy( F, mc, C+i*lda, 1, tmp+i*mc, 1);
				delete[] tmp;
			}

			j++;
		}
		mb = mc;
	        mc>>=1;
		mb -= mc;
	}

	Polynomial *minP = new Polynomial();
	minP->resize(N+1);
	minP->operator[](N) = one;
	typename Polynomial::iterator it = minP->begin();
	for (size_t j=0; j<N; ++j, it++){
		F.neg(*it, *(A+N-1+j*lda));
	}
	charp.clear();
	charp.push_front(*minP);
	return 0;
}
<commit_msg>*** empty log message ***<commit_after>/* -*- mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */

/* linbox/fflapack/fflapack_charpoly_kgfast.inl
 * Copyright (C) 2004 Clement Pernet
 *
 * Written by Clement Pernet <Clement.Pernet@imag.fr>
 *
 * See COPYING for license information.
 */

#ifndef MIN
#define MIN(a,b) (a<b)?a:b
#endif

//---------------------------------------------------------------------
// CharPoly: Compute the characteristic polynomial of A using
// Keller-Gehrig's fast algorithm. A must be generic.
//---------------------------------------------------------------------
using namespace std;
template <class Field, class Polynomial>
int
LinBox::FFLAPACK::KGFast ( const Field& F, std::list<Polynomial>& charp,
			   const size_t N,
			   typename Field::Element * A, const size_t lda ){

	static typename Field::Element one, zero, mone;
	F.init(one, 1UL);
	F.neg(mone, one);
	F.init(zero, 0UL);
	size_t mc=N>>1; // Matrix A is transformed into a mc_Frobenius form
        size_t mb=N-mc;
	size_t r;
	typename Field::Element * C, *B;

	while ( mc > 0 ) {
// 		cerr<<"Boucle1: mc,mb,N="<<mc<<" "<<mb<<" "<<N<<endl;
// 		write_field( F, cerr, A, N, N, lda );
		size_t j=0;
		C = A + (N-mc);
		cerr<<endl<<"mc="<<mc<<":";
		while ( (j+1)*mc < N ) {
			mb = MIN ( mb, N-(j+1)*mc );
// 			cerr<<"Boucle2: j,mb="<<j<<" "<<mb<<endl;
// 			write_field( F, cerr, A, N, N, lda );
			B = A + (N-mc-mb);

			// B1 <- C1^-1.B1
			typename Field::Element * LUP = new typename Field::Element[mc*mc];
			for (size_t i=0; i<mc; ++i)
				fcopy( F, mc, LUP+i*mc, 1, C+i*lda, 1);
			size_t * P = new size_t[mc];
			size_t * Q = new size_t[mc];

			if ( (r = LUdivine( F, FflasNonUnit, mc, mc,
				      LUP, mc, P, FflapackLQUP, Q )) < mc )
				return -1;
// 			cerr<<"LUP="<<endl;
// 			write_field( F, cerr, LUP, mc, mc, mc );
                        cerr<<" "<<r;
			ftrsm(F, FflasLeft, FflasLower, FflasNoTrans, FflasUnit,
			      mc, mb, one, LUP, mc , B, lda);
			ftrsm(F, FflasLeft, FflasUpper, FflasNoTrans, FflasNonUnit,
			      mc, mb, one, LUP, mc , B, lda);
			delete[] LUP;
			applyP( F, FflasLeft, FflasTrans, mb, 0, mc, B, lda, P );

// 			cerr<<"Apres B1<-C1^-1"<<endl;
// 			write_field( F, cerr, A, N, N, lda );

			// B2 <- B2 - C2.B1
			fgemm(F, FflasNoTrans, FflasNoTrans, N-mc, mb, mc,
			      mone, C+mc*lda, lda, B, lda,
			      one, B+mc*lda, lda);

// 			cerr<<"Apres B2<-B2-C2.B1"<<endl;
//                         write_field( F, cerr, A, N, N, lda );

			// Shifting B: B1;B2 -> B2;B1
			typename Field::Element * tmp = new typename Field::Element[mc*mb];
			for (size_t i=0; i<mc; ++i)
				fcopy( F, mb, tmp+i*mb, 1, B+i*lda, 1);
			for (size_t i=mc; i<N; ++i)
				fcopy( F, mb, B+(i-mc)*lda, 1, B+i*lda, 1);
			for (size_t i=0; i<mc; ++i)
				fcopy( F, mb, B+(i+N-mc)*lda, 1, tmp+i*mb, 1);
			delete[] tmp;
// 			cerr<<"Apres shift de B"<<endl;
//                         write_field( F, cerr, A, N, N, lda );

			// C3 <- B3.C1 + C3
			fgemm(F, FflasNoTrans, FflasNoTrans, (j+1)*mc, mc, mb,
			      one, B+(N-(j+1)*mc)*lda, lda, C+(N-(j+1)*mc-mb)*lda, lda,
			      one, C+(N-(j+1)*mc)*lda, lda);
			// cerr<<"C3 <- B3.C1 + C3: B3="<<endl;
//                         write_field( F, cerr, B+(N-(j+1)*mc)*lda, (j+1)*mc, mb, lda );
// 			cerr<<"C3 <- B3.C1 + C3: C1"<<endl;
//                         write_field( F, cerr,  C+(N-(j+1)*mc-mb)*lda, mb, mc, lda );
// 			cerr<<"C3 <- B3.C1 + C3: C3="<<endl;
//                         write_field( F, cerr, C+(N-(j+1)*mc)*lda, (j+1)*mc, mc, lda );

			int lambda = N - mb - (j+1)*mc;
			if ( int(mb) < lambda ){

// 				cerr<<"mb<lambda"<<endl;
				typename Field::Element * tmp = new typename Field::Element[lambda*mc];

				// tmp <- C1
				for (int i=0; i<lambda; ++i)
					fcopy( F, mc, tmp+i*mc, 1, C+i*lda, 1);

				// C1' <- B1.C2
				fgemm(F, FflasNoTrans, FflasNoTrans, mb, mc, mb,
				      one, B, lda, C+lambda*lda, lda,
				      zero, C, lda);

				// tmp <- B2.C2 + tmp
				fgemm(F, FflasNoTrans, FflasNoTrans, lambda, mc, mb,
				      one, B+mb*lda, lda, C+lambda*lda, lda,
				      one, tmp, mc);

				// C2' <- tmp
				for (int i=0; i<lambda; ++i)
					fcopy( F, mc, C+mb*lda+i*lda, 1, tmp+i*mc, 1);
				delete[] tmp;
			}
			else if ( lambda > 0 ){
// 				cerr<<"lambda>0"<<endl;

				typename Field::Element * tmp = new typename Field::Element[mb*mc];
				// C1 <- B2.C2 + C1
				fgemm(F, FflasNoTrans, FflasNoTrans, lambda, mc, mb,
				      one, B+mb*lda, lda, C+lambda*lda, lda,
				      one, C, lda);

				// tmp <-B1.C2
				fgemm(F, FflasNoTrans, FflasNoTrans, mb, mc, mb,
				      one, B, lda, C+lambda*lda, lda,
				      zero, tmp, mc);

				// C2' <- C1
				for (int i=0; i<lambda; ++i)
					fcopy( F, mc, C+mb*lda+i*lda, 1, C+i*lda, 1);

				// C1' <- tmp
				for (size_t i=0; i<mb; ++i)
					fcopy( F, mc, C+i*lda, 1, tmp+i*mc, 1);
				delete[] tmp;
			}
			else{
// 				cerr<<"lambda<0"<<endl;
				mb = N - (j+1)*mc;
				typename Field::Element * tmp = new typename Field::Element[mb*mc];

				// tmp <-B1.C1
				fgemm(F, FflasNoTrans, FflasNoTrans, mb, mc, mb,
				      one, B, lda, C, lda,
				      zero, tmp, mc);

				// C1' <- tmp
				for (size_t i=0; i<mb; ++i)
					fcopy( F, mc, C+i*lda, 1, tmp+i*mc, 1);
				delete[] tmp;
			}

			j++;
		}
		mb = mc;
	        mc>>=1;
		mb -= mc;
	}

	Polynomial *minP = new Polynomial();
	minP->resize(N+1);
	minP->operator[](N) = one;
	typename Polynomial::iterator it = minP->begin();
	for (size_t j=0; j<N; ++j, it++){
		F.neg(*it, *(A+N-1+j*lda));
	}
	charp.clear();
	charp.push_front(*minP);
	cerr<<endl;
	return 0;
}
<|endoftext|>


<commit_before>#include "sipfieldcomposing.h"

#include "sipconversions.h"

#include "common.h"

#include <QDebug>

// a function used within this file to add a parameter
bool tryAddParameter(SIPField& field, QString parameterName, QString parameterValue);
bool tryAddParameter(SIPField& field, QString parameterName);

QString composeUritype(ConnectionType type);

QString composeUritype(ConnectionType type)
{
  if (type == TCP)
  {
    return "sip:";
  }
  else if (type == TLS)
  {
    return "sips:";
  }
  else if (type == TEL)
  {
    return "tel:";
  }
  else
  {
    qDebug() << "ERROR:  Unset connection type detected while composing SIP message";
  }

  return "";
}

QString composePortString(uint16_t port)
{
  QString portString = "";

  if (port != 0)
  {
    portString = ":" + QString::number(port);
  }
  return portString;
}

QString composeSIPUri(SIP_URI& uri)
{
  QString message = composeUritype(uri.connectionType);
  if (message != "")
  {
    message += uri.username + "@" + uri.host + composePortString(uri.port);
  }
  return message;
}

bool getFirstRequestLine(QString& line, SIPRequest& request, QString lineEnding)
{
  if(request.requestURI.host == "")
  {
    printDebug(DEBUG_PROGRAM_ERROR, "SIPComposing", DC_SEND_SIP_REQUEST,
               "Request URI host is empty when comprising the first line.");
  }

  if(request.type == SIP_NO_REQUEST)
  {
    printDebug(DEBUG_PROGRAM_ERROR, "SIPComposing",
               DC_SEND_SIP_REQUEST, "SIP_NO_REQUEST given.");
    return false;
  }

  QString type = "";
  QString target = "";

  if(request.type != SIP_REGISTER)
  {
    type = composeUritype(request.message->to.connectionType);
    target = request.message->to.username + "@" + request.message->to.host;
  }
  else // REGISTER first line does not contain username.
  {
    type = composeUritype(request.requestURI.connectionType);
    target = request.requestURI.host;
  }

  line = requestToString(request.type) + " " + type
      + target + " SIP/" + request.message->version + lineEnding;

  return true;
}

bool getFirstResponseLine(QString& line, SIPResponse& response,
                          QString lineEnding)
{
  if(response.type == SIP_UNKNOWN_RESPONSE)
  {
    qDebug() << "WARNING: First response line failed";
    return false;
  }
  line = "SIP/" + response.message->version + " "
      + QString::number(responseToCode(response.type)) + " "
      + responseToPhrase(response.type) + lineEnding;
  return true;
}

bool includeToField(QList<SIPField> &fields,
                    std::shared_ptr<SIPMessageInfo> message)
{
  Q_ASSERT(message->to.username != "" && message->to.host != "");
  if(message->to.username == "" ||  message->to.host == "")
  {
    qDebug() << "WARNING: Composing To-field failed because host is:"
             << message->to.host << "and" << message->to.username;
    return false;
  }

  SIPField field;
  field.name = "To";
  if(message->to.realname != "")
  {
    field.values = message->to.realname + " ";
  }

  QString uri = composeSIPUri(message->to);
  if (uri == "")
  {
    return false;
  }

  field.values += "<" + uri + ">";
  field.parameters = nullptr;

  tryAddParameter(field, "tag", message->dialog->toTag);

  fields.push_back(field);
  return true;
}

bool includeFromField(QList<SIPField> &fields,
                      std::shared_ptr<SIPMessageInfo> message)
{
  Q_ASSERT(message->from.username != "" && message->from.host != "");
  if(message->from.username == "" ||  message->from.host == "")
  {
    qDebug() << "WARNING: From field failed";
    return false;
  }

  SIPField field;
  field.name = "From";
  if(message->from.realname != "")
  {
    field.values = message->from.realname + " ";
  }

  QString uri = composeSIPUri(message->from);

  if (uri == "")
  {
    return false;
  }

  field.values += "<" + uri + ">";
  field.parameters = nullptr;

  tryAddParameter(field, "tag", message->dialog->fromTag);

  fields.push_back(field);
  return true;
}

bool includeCSeqField(QList<SIPField> &fields,
                      std::shared_ptr<SIPMessageInfo> message)
{
  Q_ASSERT(message->cSeq != 0 && message->transactionRequest != SIP_NO_REQUEST);
  if(message->cSeq == 0 || message->transactionRequest == SIP_NO_REQUEST)
  {
    qDebug() << "WARNING: cSeq field failed";
    return false;
  }

  SIPField field;
  field.name = "CSeq";

  field.values = QString::number(message->cSeq) + " " + requestToString(message->transactionRequest);
  field.parameters = nullptr;

  fields.push_back(field);
  return true;
}

bool includeCallIDField(QList<SIPField> &fields,
                        std::shared_ptr<SIPMessageInfo> message)
{
  Q_ASSERT(message->dialog->callID != "");
  if(message->dialog->callID == "")
  {
    qDebug() << "WARNING: Call-ID field failed";
    return false;
  }

  fields.push_back({"Call-ID", message->dialog->callID, nullptr});
  return true;
}

bool includeViaFields(QList<SIPField> &fields,
                      std::shared_ptr<SIPMessageInfo> message)
{
  Q_ASSERT(!message->vias.empty());
  if(message->vias.empty())
  {
    qDebug() << "WARNING: Via field failed";
    return false;
  }

  for(ViaInfo via : message->vias)
  {
    Q_ASSERT(via.connectionType != NONE);
    Q_ASSERT(via.branch != "");
    Q_ASSERT(via.address != "");

    SIPField field;
    field.name = "Via";

    field.values = "SIP/" + via.version +"/" + connectionToString(via.connectionType)
        + " " + via.address + composePortString(via.port); //";alias;rport";

    if(!tryAddParameter(field, "branch", via.branch))
    {
      qDebug() << "WARNING: Via field failed";
      return false;
    }

    if(via.alias && !tryAddParameter(field, "alias"))
    {
      qDebug() << "WARNING: Via field failed";
      return false;
    }

    if(via.rport && !tryAddParameter(field, "rport"))
    {
      qDebug() << "WARNING: Via field failed";
      return false;
    }

    fields.push_back(field);
  }
  return true;
}

bool includeMaxForwardsField(QList<SIPField> &fields,
                             std::shared_ptr<SIPMessageInfo> message)
{
  Q_ASSERT(message->maxForwards != 0);
  if(message->maxForwards == 0)
  {
    qDebug() << "WARNING: Max-forwards field failed";
    return false;
  }

  fields.push_back({"Max-Forwards", QString::number(message->maxForwards), nullptr});
  return true;
}

bool includeContactField(QList<SIPField> &fields,
                         std::shared_ptr<SIPMessageInfo> message)
{
  Q_ASSERT(message->contact.username != "" && message->contact.host != "");
  if(message->contact.username == "" ||  message->contact.host == "")
  {
    qDebug() << "WARNING: Contact field failed";
    return false;
  }

  SIPField field;
  field.name = "Contact";

  QString portString = "";

  if (message->contact.port != 0)
  {
    portString = ":" + QString::number(message->contact.port);
  }

  field.values = "<sip:" + message->contact.username + "@" + message->contact.host + portString + ">";
  field.parameters = nullptr;

  if (message->contact.connectionType == TCP)
  {
    tryAddParameter(field, "transport", "tcp");
  }

  fields.push_back(field);
  return true;
}

bool includeContentTypeField(QList<SIPField> &fields,
                             QString contentType)
{
  Q_ASSERT(contentType != "");
  if(contentType == "")
  {
    qDebug() << "WARNING: Content-type field failed";
    return false;
  }
  fields.push_back({"Content-Type", contentType, nullptr});
  return true;
}

bool includeContentLengthField(QList<SIPField> &fields,
                               uint32_t contentLenght)
{
  fields.push_back({"Content-Length", QString::number(contentLenght), nullptr});
  return true;
}

bool includeExpiresField(QList<SIPField>& fields,
                         uint32_t expires)
{
  fields.push_back({"Expires", QString::number(expires), nullptr});
  return true;
}

bool tryAddParameter(SIPField& field, QString parameterName, QString parameterValue)
{
  if(parameterValue == "" || parameterName == "")
  {
    return false;
  }

  if(field.parameters == nullptr)
  {
    field.parameters = std::shared_ptr<QList<SIPParameter>> (new QList<SIPParameter>);
  }
  field.parameters->append({parameterName, parameterValue});

  return true;
}

bool tryAddParameter(SIPField& field, QString parameterName)
{
  if(parameterName == "")
  {
    return false;
  }

  if(field.parameters == nullptr)
  {
    field.parameters = std::shared_ptr<QList<SIPParameter>> (new QList<SIPParameter>);
  }
  field.parameters->append({parameterName, ""});

  return true;
}
<commit_msg>feature(Transport): Add transport=tcp parameter to contact-field.<commit_after>#include "sipfieldcomposing.h"

#include "sipconversions.h"

#include "common.h"

#include <QDebug>

// a function used within this file to add a parameter
bool tryAddParameter(SIPField& field, QString parameterName, QString parameterValue);
bool tryAddParameter(SIPField& field, QString parameterName);

QString composeUritype(ConnectionType type);

QString composeUritype(ConnectionType type)
{
  if (type == TCP)
  {
    return "sip:";
  }
  else if (type == TLS)
  {
    return "sips:";
  }
  else if (type == TEL)
  {
    return "tel:";
  }
  else
  {
    qDebug() << "ERROR:  Unset connection type detected while composing SIP message";
  }

  return "";
}

QString composePortString(uint16_t port)
{
  QString portString = "";

  if (port != 0)
  {
    portString = ":" + QString::number(port);
  }
  return portString;
}

QString composeSIPUri(SIP_URI& uri)
{
  QString message = composeUritype(uri.connectionType);
  if (message != "")
  {
    message += uri.username + "@" + uri.host + composePortString(uri.port);
  }
  return message;
}

bool getFirstRequestLine(QString& line, SIPRequest& request, QString lineEnding)
{
  if(request.requestURI.host == "")
  {
    printDebug(DEBUG_PROGRAM_ERROR, "SIPComposing", DC_SEND_SIP_REQUEST,
               "Request URI host is empty when comprising the first line.");
  }

  if(request.type == SIP_NO_REQUEST)
  {
    printDebug(DEBUG_PROGRAM_ERROR, "SIPComposing",
               DC_SEND_SIP_REQUEST, "SIP_NO_REQUEST given.");
    return false;
  }

  QString type = "";
  QString target = "";

  if(request.type != SIP_REGISTER)
  {
    type = composeUritype(request.message->to.connectionType);
    target = request.message->to.username + "@" + request.message->to.host;
  }
  else // REGISTER first line does not contain username.
  {
    type = composeUritype(request.requestURI.connectionType);
    target = request.requestURI.host;
  }

  line = requestToString(request.type) + " " + type
      + target + " SIP/" + request.message->version + lineEnding;

  return true;
}

bool getFirstResponseLine(QString& line, SIPResponse& response,
                          QString lineEnding)
{
  if(response.type == SIP_UNKNOWN_RESPONSE)
  {
    qDebug() << "WARNING: First response line failed";
    return false;
  }
  line = "SIP/" + response.message->version + " "
      + QString::number(responseToCode(response.type)) + " "
      + responseToPhrase(response.type) + lineEnding;
  return true;
}

bool includeToField(QList<SIPField> &fields,
                    std::shared_ptr<SIPMessageInfo> message)
{
  Q_ASSERT(message->to.username != "" && message->to.host != "");
  if(message->to.username == "" ||  message->to.host == "")
  {
    qDebug() << "WARNING: Composing To-field failed because host is:"
             << message->to.host << "and" << message->to.username;
    return false;
  }

  SIPField field;
  field.name = "To";
  if(message->to.realname != "")
  {
    field.values = message->to.realname + " ";
  }

  QString uri = composeSIPUri(message->to);
  if (uri == "")
  {
    return false;
  }

  field.values += "<" + uri + ">";
  field.parameters = nullptr;

  tryAddParameter(field, "tag", message->dialog->toTag);

  fields.push_back(field);
  return true;
}

bool includeFromField(QList<SIPField> &fields,
                      std::shared_ptr<SIPMessageInfo> message)
{
  Q_ASSERT(message->from.username != "" && message->from.host != "");
  if(message->from.username == "" ||  message->from.host == "")
  {
    qDebug() << "WARNING: From field failed";
    return false;
  }

  SIPField field;
  field.name = "From";
  if(message->from.realname != "")
  {
    field.values = message->from.realname + " ";
  }

  QString uri = composeSIPUri(message->from);

  if (uri == "")
  {
    return false;
  }

  field.values += "<" + uri + ">";
  field.parameters = nullptr;

  tryAddParameter(field, "tag", message->dialog->fromTag);

  fields.push_back(field);
  return true;
}

bool includeCSeqField(QList<SIPField> &fields,
                      std::shared_ptr<SIPMessageInfo> message)
{
  Q_ASSERT(message->cSeq != 0 && message->transactionRequest != SIP_NO_REQUEST);
  if(message->cSeq == 0 || message->transactionRequest == SIP_NO_REQUEST)
  {
    qDebug() << "WARNING: cSeq field failed";
    return false;
  }

  SIPField field;
  field.name = "CSeq";

  field.values = QString::number(message->cSeq) + " " + requestToString(message->transactionRequest);
  field.parameters = nullptr;

  fields.push_back(field);
  return true;
}

bool includeCallIDField(QList<SIPField> &fields,
                        std::shared_ptr<SIPMessageInfo> message)
{
  Q_ASSERT(message->dialog->callID != "");
  if(message->dialog->callID == "")
  {
    qDebug() << "WARNING: Call-ID field failed";
    return false;
  }

  fields.push_back({"Call-ID", message->dialog->callID, nullptr});
  return true;
}

bool includeViaFields(QList<SIPField> &fields,
                      std::shared_ptr<SIPMessageInfo> message)
{
  Q_ASSERT(!message->vias.empty());
  if(message->vias.empty())
  {
    qDebug() << "WARNING: Via field failed";
    return false;
  }

  for(ViaInfo via : message->vias)
  {
    Q_ASSERT(via.connectionType != NONE);
    Q_ASSERT(via.branch != "");
    Q_ASSERT(via.address != "");

    SIPField field;
    field.name = "Via";

    field.values = "SIP/" + via.version +"/" + connectionToString(via.connectionType)
        + " " + via.address + composePortString(via.port); //";alias;rport";

    if(!tryAddParameter(field, "branch", via.branch))
    {
      qDebug() << "WARNING: Via field failed";
      return false;
    }

    if(via.alias && !tryAddParameter(field, "alias"))
    {
      qDebug() << "WARNING: Via field failed";
      return false;
    }

    if(via.rport && !tryAddParameter(field, "rport"))
    {
      qDebug() << "WARNING: Via field failed";
      return false;
    }

    fields.push_back(field);
  }
  return true;
}

bool includeMaxForwardsField(QList<SIPField> &fields,
                             std::shared_ptr<SIPMessageInfo> message)
{
  Q_ASSERT(message->maxForwards != 0);
  if(message->maxForwards == 0)
  {
    qDebug() << "WARNING: Max-forwards field failed";
    return false;
  }

  fields.push_back({"Max-Forwards", QString::number(message->maxForwards), nullptr});
  return true;
}

bool includeContactField(QList<SIPField> &fields,
                         std::shared_ptr<SIPMessageInfo> message)
{
  Q_ASSERT(message->contact.username != "" && message->contact.host != "");
  if(message->contact.username == "" ||  message->contact.host == "")
  {
    qDebug() << "WARNING: Contact field failed";
    return false;
  }

  SIPField field;
  field.name = "Contact";

  QString portString = "";

  if (message->contact.port != 0)
  {
    portString = ":" + QString::number(message->contact.port);
  }

  QString transportString = "";

  if (message->contact.connectionType == TCP)
  {
    transportString = ";transport=tcp";
  }

  field.values = "<sip:" + message->contact.username + "@"
      + message->contact.host + portString + transportString + ">";

  field.parameters = nullptr;

  fields.push_back(field);
  return true;
}

bool includeContentTypeField(QList<SIPField> &fields,
                             QString contentType)
{
  Q_ASSERT(contentType != "");
  if(contentType == "")
  {
    qDebug() << "WARNING: Content-type field failed";
    return false;
  }
  fields.push_back({"Content-Type", contentType, nullptr});
  return true;
}

bool includeContentLengthField(QList<SIPField> &fields,
                               uint32_t contentLenght)
{
  fields.push_back({"Content-Length", QString::number(contentLenght), nullptr});
  return true;
}

bool includeExpiresField(QList<SIPField>& fields,
                         uint32_t expires)
{
  fields.push_back({"Expires", QString::number(expires), nullptr});
  return true;
}

bool tryAddParameter(SIPField& field, QString parameterName, QString parameterValue)
{
  if(parameterValue == "" || parameterName == "")
  {
    return false;
  }

  if(field.parameters == nullptr)
  {
    field.parameters = std::shared_ptr<QList<SIPParameter>> (new QList<SIPParameter>);
  }
  field.parameters->append({parameterName, parameterValue});

  return true;
}

bool tryAddParameter(SIPField& field, QString parameterName)
{
  if(parameterName == "")
  {
    return false;
  }

  if(field.parameters == nullptr)
  {
    field.parameters = std::shared_ptr<QList<SIPParameter>> (new QList<SIPParameter>);
  }
  field.parameters->append({parameterName, ""});

  return true;
}
<|endoftext|>


<commit_before>/****************************************************************/
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*          All contents are licensed under LGPL V2.1           */
/*             See LICENSE for full restrictions                */
/****************************************************************/

#include "AEFVSlopeLimitingOneD.h"

template<>
InputParameters validParams<AEFVSlopeLimitingOneD>()
{
  InputParameters params = validParams<SlopeLimitingBase>();
  params.addClassDescription("One-dimensional slope limiting to get the limited slope of cell average variable for the advection equation using a cell-centered finite volume method.");
  params.addRequiredCoupledVar("u", "constant monomial variable");
  MooseEnum scheme("none minmod mc superbee", "none");
  params.addParam<MooseEnum>("scheme", scheme, "TVD-type slope limiting scheme");
  return params;
}

AEFVSlopeLimitingOneD::AEFVSlopeLimitingOneD(const InputParameters & parameters) :
    SlopeLimitingBase(parameters),
    _u(getVar("u", 0)),
    _scheme(getParam<MooseEnum>("scheme"))
{
}

std::vector<RealGradient>
AEFVSlopeLimitingOneD::limitElementSlope() const
{
  // you should know how many equations you are solving and assign this number
  // e.g. = 1 (for the advection equation)
  unsigned int nvars = 1;

  const Elem* elem = _current_elem;

  // index of conserved variable
  unsigned int iv;

  // index of sides around an element
  unsigned int is;

  // index of the neighbor element
  unsigned int in;

  // number of sides surrounding an element = 2 in 1D
  unsigned int nside = elem->n_sides();

  // number of reconstruction stencils = 3 in 1D
  unsigned int nsten = nside + 1;

  // vector for the gradients of primitive variables
  std::vector<RealGradient> ugrad(nvars, RealGradient(0., 0., 0.));

  // array to store center coordinates of this cell and its neighbor cells
  std::vector<Real> xc(nsten, 0.);

  // the first always stores the current cell
  xc[0] = elem->centroid()(0);

  // array for the cell-average values in the current cell and its neighbors
  std::vector <std::vector<Real> > ucell(nsten, std::vector<Real>(nvars, 0.));

  // central slope:
  //                  u_{i+1} - u {i-1}
  //                  -----------------
  //                  x_{i+1} - x_{i-1}

  // left-side slope:
  //                  u_{i} - u {i-1}
  //                  ---------------
  //                  x_{i} - x_{i-1}

  // right-side slope:
  //                  u_{i+1} - u {i}
  //                  ---------------
  //                  x_{i+1} - x_{i}

  // array to store the central and one-sided slopes, where the first should be central slope
  std::vector <std::vector<Real> > sigma(nsten, std::vector<Real>(nvars, 0.));

  // get the cell-average variable in the central cell
  ucell[0][0] = _u->getElementalValue(elem);

  // a flag to indicate the boundary side of the current cell

  unsigned int bflag = 0;

  // loop over the sides to compute the one-sided slopes

  for (is = 0; is < nside; is++)
  {
    in = is + 1;

    // when the current element is an internal cell
    if (elem->neighbor(is) != NULL)
    {
      const Elem* neig = elem->neighbor(is);

      xc[in] = neig->centroid()(0);

      // get the cell-average variable in this neighbor cell
      ucell[in][0] = _u->getElementalValue(neig);

      // calculate the one-sided slopes of primitive variables

      for (iv = 0; iv < nvars; iv++)
        sigma[in][iv] = (ucell[0][iv] - ucell[in][iv]) / (xc[0] - xc[in]);
    }
    // when the current element is at the boundary,
    // we choose not to construct the slope in 1D just for convenience.
    else
    {
      bflag = in;
    }
  }

  // calculate the slope of the current element
  // according to the choice of the slope limiter algorithm

  switch (_scheme)
  {
    // first-order, zero slope
    case 0:
      break;

    // ==============
    // minmod limiter
    // ==============
    case 1:

      if (bflag == 0)
      {
        for (iv = 0; iv < nvars; iv++)
        {
          if ((sigma[1][iv] * sigma[2][iv]) > 0.)
          {
            if (std::abs(sigma[1][iv]) < std::abs(sigma[2][iv]))
              ugrad[iv](0) = sigma[1][iv];
            else
              ugrad[iv](0) = sigma[2][iv];
          }
        }
      }
      break;

    // ===========================================
    // MC (monotonized central-difference limiter)
    // ===========================================
    case 2:

      if (bflag == 0)
      {
        for (iv = 0; iv < nvars; iv++)
          sigma[0][iv] = (ucell[1][iv] - ucell[2][iv]) / (xc[1] - xc[2]);

        for (iv = 0; iv < nvars; iv++)
        {
          if (sigma[0][iv] > 0. && sigma[1][iv] > 0. && sigma[2][iv] > 0.)
            ugrad[iv](0) = std::min(sigma[0][iv], 2. * std::min(sigma[1][iv], sigma[2][iv]));
          else if (sigma[0][iv] < 0. && sigma[1][iv] < 0. && sigma[2][iv] < 0.)
            ugrad[iv](0) = std::max(sigma[0][iv], 2. * std::max(sigma[1][iv], sigma[2][iv]));
        }
      }
      break;

    // ================
    // Superbee limiter
    // ================
    case 3:

      if (bflag == 0)
      {
        for (iv = 0; iv < nvars; iv++)
        {
          Real sigma1 = 0.;
          Real sigma2 = 0.;

          // calculate sigma1 with minmod
          if (sigma[2][iv] > 0. && sigma[1][iv] > 0.)
            sigma1 = std::min(sigma[2][iv], 2. * sigma[1][iv]);
          else if (sigma[2][iv] < 0. && sigma[1][iv] < 0.)
            sigma1 = std::max(sigma[2][iv], 2. * sigma[1][iv]);

          // calculate sigma2 with minmod
          if (sigma[2][iv] > 0. && sigma[1][iv] > 0.)
            sigma2 = std::min(2. * sigma[2][iv], sigma[1][iv]);
          else if (sigma[2][iv] < 0. && sigma[1][iv] < 0.)
            sigma2 = std::max(2. * sigma[2][iv], sigma[1][iv]);

          // calculate sigma with maxmod
          if (sigma1 > 0. && sigma2 > 0.)
            ugrad[iv](0) = std::max(sigma1, sigma2);
          else if (sigma1 < 0. && sigma2 < 0.)
            ugrad[iv](0) = std::min(sigma1, sigma2);
        }
      }
      break;

    default:
      mooseError("Unknown 1D TVD-type slope limiter scheme");
      break;
  }

  return ugrad;
}
<commit_msg>Don't do slope limiting when neighbor is in a subdomain not encompassed by the AEFVSlopeLimitingOneD object.<commit_after>/****************************************************************/
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*          All contents are licensed under LGPL V2.1           */
/*             See LICENSE for full restrictions                */
/****************************************************************/

#include "AEFVSlopeLimitingOneD.h"

template<>
InputParameters validParams<AEFVSlopeLimitingOneD>()
{
  InputParameters params = validParams<SlopeLimitingBase>();
  params.addClassDescription("One-dimensional slope limiting to get the limited slope of cell average variable for the advection equation using a cell-centered finite volume method.");
  params.addRequiredCoupledVar("u", "constant monomial variable");
  MooseEnum scheme("none minmod mc superbee", "none");
  params.addParam<MooseEnum>("scheme", scheme, "TVD-type slope limiting scheme");
  return params;
}

AEFVSlopeLimitingOneD::AEFVSlopeLimitingOneD(const InputParameters & parameters) :
    SlopeLimitingBase(parameters),
    _u(getVar("u", 0)),
    _scheme(getParam<MooseEnum>("scheme"))
{
}

std::vector<RealGradient>
AEFVSlopeLimitingOneD::limitElementSlope() const
{
  // you should know how many equations you are solving and assign this number
  // e.g. = 1 (for the advection equation)
  unsigned int nvars = 1;

  const Elem* elem = _current_elem;

  // index of conserved variable
  unsigned int iv;

  // index of sides around an element
  unsigned int is;

  // index of the neighbor element
  unsigned int in;

  // number of sides surrounding an element = 2 in 1D
  unsigned int nside = elem->n_sides();

  // number of reconstruction stencils = 3 in 1D
  unsigned int nsten = nside + 1;

  // vector for the gradients of primitive variables
  std::vector<RealGradient> ugrad(nvars, RealGradient(0., 0., 0.));

  // array to store center coordinates of this cell and its neighbor cells
  std::vector<Real> xc(nsten, 0.);

  // the first always stores the current cell
  xc[0] = elem->centroid()(0);

  // array for the cell-average values in the current cell and its neighbors
  std::vector <std::vector<Real> > ucell(nsten, std::vector<Real>(nvars, 0.));

  // central slope:
  //                  u_{i+1} - u {i-1}
  //                  -----------------
  //                  x_{i+1} - x_{i-1}

  // left-side slope:
  //                  u_{i} - u {i-1}
  //                  ---------------
  //                  x_{i} - x_{i-1}

  // right-side slope:
  //                  u_{i+1} - u {i}
  //                  ---------------
  //                  x_{i+1} - x_{i}

  // array to store the central and one-sided slopes, where the first should be central slope
  std::vector <std::vector<Real> > sigma(nsten, std::vector<Real>(nvars, 0.));

  // get the cell-average variable in the central cell
  ucell[0][0] = _u->getElementalValue(elem);

  // a flag to indicate the boundary side of the current cell

  unsigned int bflag = 0;

  // loop over the sides to compute the one-sided slopes

  for (is = 0; is < nside; is++)
  {
    in = is + 1;

    // when the current element is an internal cell
    if (elem->neighbor(is) != NULL)
    {
      const Elem* neig = elem->neighbor(is);
      if (this->hasBlocks(neig->subdomain_id()))
      {
        xc[in] = neig->centroid()(0);

        // get the cell-average variable in this neighbor cell
        ucell[in][0] = _u->getElementalValue(neig);

        // calculate the one-sided slopes of primitive variables

        for (iv = 0; iv < nvars; iv++)
          sigma[in][iv] = (ucell[0][iv] - ucell[in][iv]) / (xc[0] - xc[in]);
      }
      else
        bflag = in;
    }
    // when the current element is at the boundary,
    // we choose not to construct the slope in 1D just for convenience.
    else
    {
      bflag = in;
    }
  }

  // calculate the slope of the current element
  // according to the choice of the slope limiter algorithm

  switch (_scheme)
  {
    // first-order, zero slope
    case 0:
      break;

    // ==============
    // minmod limiter
    // ==============
    case 1:

      if (bflag == 0)
      {
        for (iv = 0; iv < nvars; iv++)
        {
          if ((sigma[1][iv] * sigma[2][iv]) > 0.)
          {
            if (std::abs(sigma[1][iv]) < std::abs(sigma[2][iv]))
              ugrad[iv](0) = sigma[1][iv];
            else
              ugrad[iv](0) = sigma[2][iv];
          }
        }
      }
      break;

    // ===========================================
    // MC (monotonized central-difference limiter)
    // ===========================================
    case 2:

      if (bflag == 0)
      {
        for (iv = 0; iv < nvars; iv++)
          sigma[0][iv] = (ucell[1][iv] - ucell[2][iv]) / (xc[1] - xc[2]);

        for (iv = 0; iv < nvars; iv++)
        {
          if (sigma[0][iv] > 0. && sigma[1][iv] > 0. && sigma[2][iv] > 0.)
            ugrad[iv](0) = std::min(sigma[0][iv], 2. * std::min(sigma[1][iv], sigma[2][iv]));
          else if (sigma[0][iv] < 0. && sigma[1][iv] < 0. && sigma[2][iv] < 0.)
            ugrad[iv](0) = std::max(sigma[0][iv], 2. * std::max(sigma[1][iv], sigma[2][iv]));
        }
      }
      break;

    // ================
    // Superbee limiter
    // ================
    case 3:

      if (bflag == 0)
      {
        for (iv = 0; iv < nvars; iv++)
        {
          Real sigma1 = 0.;
          Real sigma2 = 0.;

          // calculate sigma1 with minmod
          if (sigma[2][iv] > 0. && sigma[1][iv] > 0.)
            sigma1 = std::min(sigma[2][iv], 2. * sigma[1][iv]);
          else if (sigma[2][iv] < 0. && sigma[1][iv] < 0.)
            sigma1 = std::max(sigma[2][iv], 2. * sigma[1][iv]);

          // calculate sigma2 with minmod
          if (sigma[2][iv] > 0. && sigma[1][iv] > 0.)
            sigma2 = std::min(2. * sigma[2][iv], sigma[1][iv]);
          else if (sigma[2][iv] < 0. && sigma[1][iv] < 0.)
            sigma2 = std::max(2. * sigma[2][iv], sigma[1][iv]);

          // calculate sigma with maxmod
          if (sigma1 > 0. && sigma2 > 0.)
            ugrad[iv](0) = std::max(sigma1, sigma2);
          else if (sigma1 < 0. && sigma2 < 0.)
            ugrad[iv](0) = std::min(sigma1, sigma2);
        }
      }
      break;

    default:
      mooseError("Unknown 1D TVD-type slope limiter scheme");
      break;
  }

  return ugrad;
}
<|endoftext|>


<commit_before>// Tests for the RooProxy
// Author: Stephan Hageboeck, CERN  01/2019

#include "RooProxy.h"
#include "RooCategoryProxy.h"

#include "RooRealVar.h"
#include "RooAbsPdf.h"
#include "RooCategory.h"
#include "RooDataSet.h"
#include "RooGenericPdf.h"

#include "gtest/gtest.h"

struct DummyClass : public RooAbsPdf {
    DummyClass(RooAbsCategory& theCat, RooRealVar& theVar, RooAbsPdf* thePdf = nullptr) :
      cat("catProxy", "Stores categories", this, theCat),
      var("varProxy", "Stores variables", this, theVar),
      pdf("pdfProxy", "Stores pdfs", this) {
      if (thePdf) {
        pdf.setArg(*thePdf);
      }
    }

    double evaluate() const {
      return 1.;
    }

    void clear() {
      clearValueAndShapeDirty();
    }

    TObject* clone(const char*) const {
      return new TObject();
    }

    RooCategoryProxy cat;
    RooProxy<RooRealVar> var;
    RooProxy<RooAbsPdf>  pdf;
};

TEST(RooProxy, CategoryProxy) {
  RooCategory myCat("myCat", "A category");
  myCat.defineType("A", 1);
  myCat.defineType("B", 2);
  myCat.defineType("NotA", -1);
  std::string longStr(500, '*');
  myCat.defineType(longStr.c_str(), 500);

  RooRealVar x("x", "x", -10, 10);

  DummyClass dummy(myCat, x);
  dummy.clear();

  dummy.cat = 2;
  EXPECT_TRUE(dummy.isValueDirty());
  dummy.clear();
  EXPECT_TRUE(dummy.cat == 2);
  EXPECT_STREQ(dummy.cat.label(), "B");

  dummy.cat = longStr.c_str();
  EXPECT_TRUE(dummy.isValueDirty());
  dummy.clear();
  EXPECT_TRUE(dummy.cat == 500);
  EXPECT_STREQ(dummy.cat.label(), longStr.c_str());

  dummy.cat = std::string("NotA");
  EXPECT_TRUE(dummy.isValueDirty());
  dummy.clear();
  EXPECT_TRUE(dummy.cat == -1);
  EXPECT_STREQ(dummy.cat.label(), "NotA");

  dummy.var = 2.;
  EXPECT_TRUE(dummy.isValueDirty());
  dummy.clear();
  EXPECT_TRUE(dummy.var == 2.);
}

TEST(RooProxy, CategoryProxyBatchAccess) {
  RooCategory myCat("myCat", "A category");
  myCat.defineType("A", 1);
  myCat.defineType("B", 2);
  myCat.defineType("NotA", -1);
  std::string longStr(500, '*');
  myCat.defineType(longStr.c_str(), 500);

  RooRealVar x("x", "x", -10, 10);

  DummyClass dummy(myCat, x);

  RooDataSet data("data", "data", RooArgSet(x, myCat));
  auto& xData = dynamic_cast<RooRealVar&>((*data.get())["x"]);
  auto& catData = dynamic_cast<RooAbsCategoryLValue&>((*data.get())["myCat"]);
  for (unsigned int i=0; i < 9; ++i) {
    xData = i;
    catData = i%2 + 1;
    data.fill();
  }
  xData = 9;
  catData = -1;
  data.fill();

  data.attachBuffers(*dummy.getVariables());

  auto theBatch = dummy.cat->getValBatch(0, 10);
  ASSERT_FALSE(theBatch.empty());
  EXPECT_EQ(theBatch.size(), 10ul);
  EXPECT_EQ(theBatch[0], 1);
  EXPECT_EQ(theBatch[1], 2);
  EXPECT_EQ(theBatch[8], 1);
  EXPECT_EQ(theBatch[9], -1);
}

TEST(RooProxy, RealProxy) {
  RooCategory myCat("myCat", "A category");
  RooRealVar x("x", "x", -10, 10);
  DummyClass dummy(myCat, x);

  RooDataSet data("data", "data", x);
  RooRealVar& xData = dynamic_cast<RooRealVar&>((*data.get())["x"]);
  for (unsigned int i=0; i < 10; ++i) {
    xData = i;
    data.fill();
  }
  data.attachBuffers(dummy);

  auto theBatch = dummy.var->getValBatch(0, 100);
  ASSERT_FALSE(theBatch.empty());
  EXPECT_EQ(theBatch.size(), 10ul);
  EXPECT_EQ(theBatch[2], 2.);
}

TEST(RooProxy, PdfProxy) {
  RooCategory myCat("myCat", "A category");
  RooRealVar x("x", "x", -10, 10);
  RooGenericPdf generic("generic", "generic", "1.+x", x);
  DummyClass dummy(myCat, x, &generic);
  dummy.Print("T");

  RooDataSet data("data", "data", x);
  for (unsigned int i=0; i < 10; ++i) {
    x = i;
    data.fill();
  }
  data.attachBuffers(dummy);

  auto theBatch = dummy.pdf->getValBatch(0, 100);
  ASSERT_FALSE(theBatch.empty());
  EXPECT_EQ(theBatch.size(), 10ul);
  EXPECT_EQ(theBatch[2], 3.);
}
<commit_msg>[RF] Add tests for batch access features of RooProxy.<commit_after>// Tests for the RooProxy
// Author: Stephan Hageboeck, CERN  01/2019

#include "RooProxy.h"
#include "RooCategoryProxy.h"

#include "RooRealVar.h"
#include "RooAbsPdf.h"
#include "RooCategory.h"
#include "RooDataSet.h"
#include "RooGenericPdf.h"

#include "gtest/gtest.h"

struct DummyClass : public RooAbsPdf {
    DummyClass(RooAbsCategory& theCat, RooRealVar& theVar, RooAbsPdf* thePdf = nullptr) :
      cat("catProxy", "Stores categories", this, theCat),
      var("varProxy", "Stores variables", this, theVar),
      pdf("pdfProxy", "Stores pdfs", this) {
      if (thePdf) {
        pdf.setArg(*thePdf);
      }
    }

    double evaluate() const {
      return 1.;
    }

    void clear() {
      clearValueAndShapeDirty();
    }

    TObject* clone(const char*) const {
      return new TObject();
    }

    RooCategoryProxy cat;
    RooProxy<RooRealVar> var;
    RooProxy<RooAbsPdf>  pdf;
};

TEST(RooProxy, CategoryProxy) {
  RooCategory myCat("myCat", "A category");
  myCat.defineType("A", 1);
  myCat.defineType("B", 2);
  myCat.defineType("NotA", -1);
  std::string longStr(500, '*');
  myCat.defineType(longStr.c_str(), 500);

  RooRealVar x("x", "x", -10, 10);

  DummyClass dummy(myCat, x);
  dummy.clear();

  dummy.cat = 2;
  EXPECT_TRUE(dummy.isValueDirty());
  dummy.clear();
  EXPECT_TRUE(dummy.cat == 2);
  EXPECT_STREQ(dummy.cat.label(), "B");

  dummy.cat = longStr.c_str();
  EXPECT_TRUE(dummy.isValueDirty());
  dummy.clear();
  EXPECT_TRUE(dummy.cat == 500);
  EXPECT_STREQ(dummy.cat.label(), longStr.c_str());

  dummy.cat = std::string("NotA");
  EXPECT_TRUE(dummy.isValueDirty());
  dummy.clear();
  EXPECT_TRUE(dummy.cat == -1);
  EXPECT_STREQ(dummy.cat.label(), "NotA");

  dummy.var = 2.;
  EXPECT_TRUE(dummy.isValueDirty());
  dummy.clear();
  EXPECT_TRUE(dummy.var == 2.);
}

TEST(RooProxy, CategoryProxyBatchAccess) {
  RooCategory myCat("myCat", "A category");
  myCat.defineType("A", 1);
  myCat.defineType("B", 2);
  myCat.defineType("NotA", -1);
  std::string longStr(500, '*');
  myCat.defineType(longStr.c_str(), 500);

  RooRealVar x("x", "x", -10, 10);

  DummyClass dummy(myCat, x);

  RooDataSet data("data", "data", RooArgSet(x, myCat));
  auto& xData = dynamic_cast<RooRealVar&>((*data.get())["x"]);
  auto& catData = dynamic_cast<RooAbsCategoryLValue&>((*data.get())["myCat"]);
  for (unsigned int i=0; i < 9; ++i) {
    xData = i;
    catData = i%2 + 1;
    data.fill();
  }
  xData = 9;
  catData = -1;
  data.fill();

  data.attachBuffers(*dummy.getVariables());

  auto theBatch = dummy.cat->getValBatch(0, 10);
  ASSERT_FALSE(theBatch.empty());
  EXPECT_EQ(theBatch.size(), 10ul);
  EXPECT_EQ(theBatch[0], 1);
  EXPECT_EQ(theBatch[1], 2);
  EXPECT_EQ(theBatch[8], 1);
  EXPECT_EQ(theBatch[9], -1);
}

TEST(RooProxy, RealProxyBatchAccess) {
  RooCategory myCat("myCat", "A category");
  RooRealVar x("x", "x", -10, 10);
  DummyClass dummy(myCat, x);

  RooDataSet data("data", "data", x);
  RooRealVar& xData = dynamic_cast<RooRealVar&>((*data.get())["x"]);
  for (unsigned int i=0; i < 10; ++i) {
    xData = i;
    data.fill();
  }

  auto dummyObservables = dummy.getObservables(data);
  data.attachBuffers(*dummyObservables);

  auto theBatch = dummy.var->getValBatch(0, 10);
  ASSERT_FALSE(theBatch.empty());
  EXPECT_EQ(theBatch.size(), 10ul);
  EXPECT_EQ(theBatch[2], 2.);
  EXPECT_EQ(theBatch[9], 9.);

  auto largerBatch = dummy.var.getValBatch(0, 100);
  EXPECT_EQ(largerBatch.size(), 10ul);

  dummy.var = 1.337;
  EXPECT_EQ(dummy.var * 1., 1.337);
}

TEST(RooProxy, PdfProxyBatchAccess) {
  RooCategory myCat("myCat", "A category");
  RooRealVar x("x", "x", -10, 10);
  RooGenericPdf generic("generic", "generic", "1.+x", x);
  DummyClass dummy(myCat, x, &generic);

  RooDataSet data("data", "data", x);
  RooRealVar& xData = dynamic_cast<RooRealVar&>((*data.get())["x"]);
  for (unsigned int i=0; i < 10; ++i) {
    xData = i;
    data.fill();
  }
  data.attachBuffers(*dummy.getVariables());

  auto theBatch = dummy.pdf->getValBatch(0, 10);
  ASSERT_FALSE(theBatch.empty());
  EXPECT_EQ(theBatch.size(), 10ul);
  EXPECT_EQ(theBatch[2], 3.);
  EXPECT_EQ(theBatch[9], 10.);
}
<|endoftext|>


<commit_before>/* -*- coding: utf-8; mode: c++; tab-width: 3; indent-tabs-mode: nil -*-

Copyright 2015
Raffaello D. Di Napoli

This file is part of Abaclade.

Abaclade is free software: you can redistribute it and/or modify it under the terms of the GNU
General Public License as published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

Abaclade is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
Public License for more details.

You should have received a copy of the GNU General Public License along with Abaclade. If not, see
<http://www.gnu.org/licenses/>.
--------------------------------------------------------------------------------------------------*/

#include <abaclade.hxx>
#include <abaclade/coroutine.hxx>
#include <abaclade/collections/list.hxx>
#include <abaclade/collections/map.hxx>
#include <abaclade/thread.hxx>

#if ABC_HOST_API_POSIX
   #if ABC_HOST_API_DARWIN
      #define _XOPEN_SOURCE
   #endif
   #include <ucontext.h>
#endif

////////////////////////////////////////////////////////////////////////////////////////////////////
// abc::coroutine::scheduler

namespace abc {

class coroutine::scheduler : public noncopyable {
private:
   friend std::shared_ptr<coroutine::scheduler> const & this_thread::attach_coroutine_scheduler(
      std::shared_ptr<coroutine::scheduler> pcorosched /*= nullptr*/
   );
   friend std::shared_ptr<coroutine::scheduler> const & this_thread::get_coroutine_scheduler();
   friend coroutine::id_type this_coroutine::id();

public:
   //! Constructor.
   scheduler();

   //! Destructor.
   ~scheduler();

   /*! Adds a coroutine to those ready to start.

   @param coro
      Coroutine to add.
   */
   void add(coroutine const & coro);

   /*! Allows other coroutines to run, preventing the calling coroutine from being rescheduled until
   at least iMillisecs milliseconds have passed.

   @param iMillisecs
      Minimum duration for which to yield to other coroutines.
   */
   void block_active_for_ms(unsigned iMillisecs);

   /*! Allows other coroutines to run while the asynchronous I/O operation completes, as an
   alternative to blocking while waiting for its completion.

   @param fd
      File descriptor that the calling coroutine is waiting for I/O on.
   @param bWrite
      true if the coroutine is waiting to write to fd, or false if it’s waiting to read from it.
   */
   void block_active_until_fd_ready(io::filedesc_t fd, bool bWrite);

   //! Switches context to the current thread’s own context.
   void return_to_scheduler();

   /*! Begins scheduling and running coroutines on the current thread. Only returns after every
   coroutine added with add_coroutine() returns. */
   void run();

private:
   /*! Finds a coroutine ready to execute; if none are, but there are blocked coroutines, it blocks
   the current thread until one of them becomes ready.

   @return
      Pointer to the context of a coroutine that’s ready to execute.
   */
   std::shared_ptr<coroutine::context> find_coroutine_to_activate();

   /*! Switches context from the coroutine context pointed to by pcoroctxLastActive to the current
   thread’s own context.

   @param pcoroctxLastActive
      Pointer to the coroutine context that is being inactivated.
   */
   void switch_to_scheduler(coroutine::context * pcoroctxLastActive);

private:
#if ABC_HOST_API_BSD
   //! File descriptor of the internal kqueue.
   io::filedesc m_fdKqueue;
   /*! Coroutines that are blocked on a timer wait. The keys are the same as the values, but this
   can’t be changed into a set<shared_ptr<context>> because we need it to hold a strong reference to
   the coroutine context while allowing lookups without having a shared_ptr. */
   collections::map<std::uintptr_t, std::shared_ptr<coroutine::context>> m_mapCorosBlockedByTimer;
#elif ABC_HOST_API_LINUX
   //! File descriptor of the internal epoll.
   io::filedesc m_fdEpoll;
   /*! Timers currently being waited for. The key is the same as the value, but this can’t be
   changed into a set<io::filedesc> until io::filedesc is hashable. */
   collections::map<io::filedesc_t, io::filedesc> m_mapActiveTimers;
#else
   #error "TODO: HOST_API"
#endif
   //! Coroutines that are blocked on a fd wait.
   collections::map<io::filedesc_t, std::shared_ptr<coroutine::context>> m_mapCorosBlockedByFD;
   /*! List of coroutines that are ready to run. Includes coroutines that have been scheduled, but
   have not been started yet. */
   collections::list<std::shared_ptr<coroutine::context>> m_listReadyCoros;
   //! Pointer to the active (current) coroutine, or nullptr if none is active.
   static thread_local_value<std::shared_ptr<coroutine::context>> sm_pcoroctxActive;
   //! Pointer to the coroutine scheduler for the current thread.
   static thread_local_value<std::shared_ptr<scheduler>> sm_pcorosched;
#if ABC_HOST_API_POSIX
   //! Pointer to the context of every thread running a coroutine scheduler.
   static thread_local_value< ::ucontext_t *> sm_puctxReturn;
#endif
};

} //namespace abc

////////////////////////////////////////////////////////////////////////////////////////////////////
<commit_msg>Remove unnecessary friend declarations<commit_after>/* -*- coding: utf-8; mode: c++; tab-width: 3; indent-tabs-mode: nil -*-

Copyright 2015
Raffaello D. Di Napoli

This file is part of Abaclade.

Abaclade is free software: you can redistribute it and/or modify it under the terms of the GNU
General Public License as published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

Abaclade is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
Public License for more details.

You should have received a copy of the GNU General Public License along with Abaclade. If not, see
<http://www.gnu.org/licenses/>.
--------------------------------------------------------------------------------------------------*/

#include <abaclade.hxx>
#include <abaclade/coroutine.hxx>
#include <abaclade/collections/list.hxx>
#include <abaclade/collections/map.hxx>
#include <abaclade/thread.hxx>

#if ABC_HOST_API_POSIX
   #if ABC_HOST_API_DARWIN
      #define _XOPEN_SOURCE
   #endif
   #include <ucontext.h>
#endif

////////////////////////////////////////////////////////////////////////////////////////////////////
// abc::coroutine::scheduler

namespace abc {

class coroutine::scheduler : public noncopyable {
private:
   friend coroutine::id_type this_coroutine::id();

public:
   //! Constructor.
   scheduler();

   //! Destructor.
   ~scheduler();

   /*! Adds a coroutine to those ready to start.

   @param coro
      Coroutine to add.
   */
   void add(coroutine const & coro);

   /*! Allows other coroutines to run, preventing the calling coroutine from being rescheduled until
   at least iMillisecs milliseconds have passed.

   @param iMillisecs
      Minimum duration for which to yield to other coroutines.
   */
   void block_active_for_ms(unsigned iMillisecs);

   /*! Allows other coroutines to run while the asynchronous I/O operation completes, as an
   alternative to blocking while waiting for its completion.

   @param fd
      File descriptor that the calling coroutine is waiting for I/O on.
   @param bWrite
      true if the coroutine is waiting to write to fd, or false if it’s waiting to read from it.
   */
   void block_active_until_fd_ready(io::filedesc_t fd, bool bWrite);

   //! Switches context to the current thread’s own context.
   void return_to_scheduler();

   /*! Begins scheduling and running coroutines on the current thread. Only returns after every
   coroutine added with add_coroutine() returns. */
   void run();

private:
   /*! Finds a coroutine ready to execute; if none are, but there are blocked coroutines, it blocks
   the current thread until one of them becomes ready.

   @return
      Pointer to the context of a coroutine that’s ready to execute.
   */
   std::shared_ptr<coroutine::context> find_coroutine_to_activate();

   /*! Switches context from the coroutine context pointed to by pcoroctxLastActive to the current
   thread’s own context.

   @param pcoroctxLastActive
      Pointer to the coroutine context that is being inactivated.
   */
   void switch_to_scheduler(coroutine::context * pcoroctxLastActive);

private:
#if ABC_HOST_API_BSD
   //! File descriptor of the internal kqueue.
   io::filedesc m_fdKqueue;
   /*! Coroutines that are blocked on a timer wait. The keys are the same as the values, but this
   can’t be changed into a set<shared_ptr<context>> because we need it to hold a strong reference to
   the coroutine context while allowing lookups without having a shared_ptr. */
   collections::map<std::uintptr_t, std::shared_ptr<coroutine::context>> m_mapCorosBlockedByTimer;
#elif ABC_HOST_API_LINUX
   //! File descriptor of the internal epoll.
   io::filedesc m_fdEpoll;
   /*! Timers currently being waited for. The key is the same as the value, but this can’t be
   changed into a set<io::filedesc> until io::filedesc is hashable. */
   collections::map<io::filedesc_t, io::filedesc> m_mapActiveTimers;
#else
   #error "TODO: HOST_API"
#endif
   //! Coroutines that are blocked on a fd wait.
   collections::map<io::filedesc_t, std::shared_ptr<coroutine::context>> m_mapCorosBlockedByFD;
   /*! List of coroutines that are ready to run. Includes coroutines that have been scheduled, but
   have not been started yet. */
   collections::list<std::shared_ptr<coroutine::context>> m_listReadyCoros;
   //! Pointer to the active (current) coroutine, or nullptr if none is active.
   static thread_local_value<std::shared_ptr<coroutine::context>> sm_pcoroctxActive;
   //! Pointer to the coroutine scheduler for the current thread.
   static thread_local_value<std::shared_ptr<scheduler>> sm_pcorosched;
#if ABC_HOST_API_POSIX
   //! Pointer to the context of every thread running a coroutine scheduler.
   static thread_local_value< ::ucontext_t *> sm_puctxReturn;
#endif
};

} //namespace abc

////////////////////////////////////////////////////////////////////////////////////////////////////
<|endoftext|>


<commit_before>/* This file is part of Zanshin

   Copyright 2014 Kevin Ottens <ervin@kde.org>
   Copyright 2014 Franck Arrecot <franck.arrecot@gmail.com>

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of
   the License or (at your option) version 3 or any later version
   accepted by the membership of KDE e.V. (or its successor approved
   by the membership of KDE e.V.), which shall act as a proxy
   defined in Section 14 of version 3 of the license.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
   USA.
*/

#include "akonaditagrepository.h"

#include "akonadiitemfetchjobinterface.h"
#include "akonadiserializer.h"
#include "akonadistorage.h"

#include "utils/compositejob.h"

using namespace Akonadi;

TagRepository::TagRepository(QObject *parent)
    : QObject(parent),
      m_storage(new Storage),
      m_serializer(new Serializer),
      m_ownInterfaces(true)
{
}

TagRepository::TagRepository(StorageInterface *storage, SerializerInterface *serializer)
    : m_storage(storage),
      m_serializer(serializer),
      m_ownInterfaces(false)
{
}

TagRepository::~TagRepository()
{
    if (m_ownInterfaces) {
        delete m_storage;
        delete m_serializer;
    }
}

KJob *TagRepository::create(Domain::Tag::Ptr tag)
{
    auto akonadiTag = m_serializer->createAkonadiTagFromTag(tag);
    Q_ASSERT(!akonadiTag.isValid());
    return m_storage->createTag(akonadiTag);
}

KJob *TagRepository::remove(Domain::Tag::Ptr tag)
{
   auto akonadiTag = m_serializer->createAkonadiTagFromTag(tag);
   Q_ASSERT(akonadiTag.isValid());
   return m_storage->removeTag(akonadiTag);
}

KJob *TagRepository::associate(Domain::Tag::Ptr parent, Domain::Artifact::Ptr child)
{
    auto akonadiTag = m_serializer->createAkonadiTagFromTag(parent);
    Q_ASSERT(akonadiTag.isValid());

    Item childItem;
    if (auto task = child.objectCast<Domain::Task>())
        childItem = m_serializer->createItemFromTask(task);
    else if (auto note = child.objectCast<Domain::Note>())
        childItem = m_serializer->createItemFromNote(note);

    Q_ASSERT(childItem.isValid());

    auto job = new Utils::CompositeJob();
    ItemFetchJobInterface *fetchItemJob = m_storage->fetchItem(childItem);
    job->install(fetchItemJob->kjob(), [akonadiTag, fetchItemJob, parent, job, this] {
        if (fetchItemJob->kjob()->error() != KJob::NoError)
            return;

        Q_ASSERT(fetchItemJob->items().size() == 1);
        auto childItem = fetchItemJob->items().first();
        childItem.setTag(akonadiTag);

        auto updateJob = m_storage->updateItem(childItem);
        job->addSubjob(updateJob);
        updateJob->start();
    });
    return job;
}

KJob *TagRepository::dissociate(Domain::Tag::Ptr parent, Domain::Artifact::Ptr child)
{
    Q_UNUSED(parent);
    Q_UNUSED(child);
    qFatal("not impl yet");
    return 0;
}
<commit_msg>Dissociate a task from a tag, implementation within TagRepository<commit_after>/* This file is part of Zanshin

   Copyright 2014 Kevin Ottens <ervin@kde.org>
   Copyright 2014 Franck Arrecot <franck.arrecot@gmail.com>

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of
   the License or (at your option) version 3 or any later version
   accepted by the membership of KDE e.V. (or its successor approved
   by the membership of KDE e.V.), which shall act as a proxy
   defined in Section 14 of version 3 of the license.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
   USA.
*/

#include "akonaditagrepository.h"

#include "akonadiitemfetchjobinterface.h"
#include "akonadiserializer.h"
#include "akonadistorage.h"

#include "utils/compositejob.h"

using namespace Akonadi;

TagRepository::TagRepository(QObject *parent)
    : QObject(parent),
      m_storage(new Storage),
      m_serializer(new Serializer),
      m_ownInterfaces(true)
{
}

TagRepository::TagRepository(StorageInterface *storage, SerializerInterface *serializer)
    : m_storage(storage),
      m_serializer(serializer),
      m_ownInterfaces(false)
{
}

TagRepository::~TagRepository()
{
    if (m_ownInterfaces) {
        delete m_storage;
        delete m_serializer;
    }
}

KJob *TagRepository::create(Domain::Tag::Ptr tag)
{
    auto akonadiTag = m_serializer->createAkonadiTagFromTag(tag);
    Q_ASSERT(!akonadiTag.isValid());
    return m_storage->createTag(akonadiTag);
}

KJob *TagRepository::remove(Domain::Tag::Ptr tag)
{
   auto akonadiTag = m_serializer->createAkonadiTagFromTag(tag);
   Q_ASSERT(akonadiTag.isValid());
   return m_storage->removeTag(akonadiTag);
}

KJob *TagRepository::associate(Domain::Tag::Ptr parent, Domain::Artifact::Ptr child)
{
    auto akonadiTag = m_serializer->createAkonadiTagFromTag(parent);
    Q_ASSERT(akonadiTag.isValid());

    Item childItem;
    if (auto task = child.objectCast<Domain::Task>())
        childItem = m_serializer->createItemFromTask(task);
    else if (auto note = child.objectCast<Domain::Note>())
        childItem = m_serializer->createItemFromNote(note);

    Q_ASSERT(childItem.isValid());

    auto job = new Utils::CompositeJob();
    ItemFetchJobInterface *fetchItemJob = m_storage->fetchItem(childItem);
    job->install(fetchItemJob->kjob(), [akonadiTag, fetchItemJob, parent, job, this] {
        if (fetchItemJob->kjob()->error() != KJob::NoError)
            return;

        Q_ASSERT(fetchItemJob->items().size() == 1);
        auto childItem = fetchItemJob->items().first();
        childItem.setTag(akonadiTag);

        auto updateJob = m_storage->updateItem(childItem);
        job->addSubjob(updateJob);
        updateJob->start();
    });
    return job;
}

KJob *TagRepository::dissociate(Domain::Tag::Ptr parent, Domain::Artifact::Ptr child)
{
    Item childItem;

    if (Domain::Task::Ptr task = child.dynamicCast<Domain::Task>())
        childItem = m_serializer->createItemFromTask(task);
    else if (Domain::Note::Ptr note= child.dynamicCast<Domain::Note>())
        childItem = m_serializer->createItemFromNote(note);

    Q_ASSERT(childItem.isValid());

    auto job = new Utils::CompositeJob();
    ItemFetchJobInterface *fetchItemJob = m_storage->fetchItem(childItem);
    job->install(fetchItemJob->kjob(), [fetchItemJob, parent, job, this] {
        if (fetchItemJob->kjob()->error() != KJob::NoError)
            return;

        Q_ASSERT(fetchItemJob->items().size() == 1);
        auto childItem = fetchItemJob->items().first();
        auto tag = m_serializer->createAkonadiTagFromTag(parent);
        Q_ASSERT(tag.isValid());
        childItem.clearTag(tag);

        auto updateJob = m_storage->updateItem(childItem);
        job->addSubjob(updateJob);
        updateJob->start();
    });

    return job;
}
<|endoftext|>


<commit_before>#pragma once

#include <stdint.h>

/* Comment out this line for a non-test network */
#define BTS_TEST_NETWORK

#define BTS_TEST_NETWORK_VERSION                            62 // autogenerated

/** @file bts/blockchain/config.hpp
 *  @brief Defines global constants that determine blockchain behavior
 */
#define BTS_BLOCKCHAIN_VERSION                              109
#define BTS_BLOCKCHAIN_DATABASE_VERSION                     164

/**
 *  The address prepended to string representation of
 *  addresses.
 *
 *  Changing these parameters will result in a hard fork.
 */
#define BTS_ADDRESS_PREFIX                                  "XTS"
#define BTS_BLOCKCHAIN_SYMBOL                               "XTS"
#define BTS_BLOCKCHAIN_NAME                                 "BitShares XTS"
#define BTS_BLOCKCHAIN_DESCRIPTION                          "BitShares Test Network"
#define BTS_BLOCKCHAIN_PRECISION                            100000
#define BTS_BLOCKCHAIN_MAX_TRANSACTION_EXPIRATION_SEC       (60*60*24*2)
#define BTS_BLOCKCHAIN_MIN_YIELD_PERIOD_SEC                 (60*60*24) // 24 hours

#define BTS_BLOCKCHAIN_MIN_BURN_FEE                         BTS_BLOCKCHAIN_PRECISION * 1 // 1 XTS
#define BTS_BLOCKCHAIN_DEFAULT_RELAY_FEE                    10000 // XTS
#define BTS_BLOCKCHAIN_MINIMUM_SHORT_ORDER_SIZE             (BTS_BLOCKCHAIN_PRECISION*100)
#define BTS_BLOCKCHAIN_MAX_SHORT_PERIOD_SEC                 (2*60*60) // 2 hours for test network

/**
 * The number of delegates that the blockchain is designed to support
 */
#define BTS_BLOCKCHAIN_NUM_DELEGATES                        uint32_t(101)
#define BTS_BLOCKCHAIN_MAX_SLATE_SIZE                       (BTS_BLOCKCHAIN_NUM_DELEGATES + (BTS_BLOCKCHAIN_NUM_DELEGATES/10))
#define BTS_BLOCKCHAIN_MIN_FEEDS                            ((BTS_BLOCKCHAIN_NUM_DELEGATES/2) + 1)
#define BTS_BLOCKCHAIN_MAX_UNDO_HISTORY                     (BTS_BLOCKCHAIN_NUM_DELEGATES*4)

#define BTS_BLOCKCHAIN_ENABLE_NEGATIVE_VOTES                false

#define BTS_MAX_DELEGATE_PAY_PER_BLOCK                      int64_t( 50 * BTS_BLOCKCHAIN_PRECISION ) // 50 XTS

/**
 * To prevent a delegate from producing blocks on split network,
 * we check the connection count.  This means no blocks get produced
 * until at least a minimum number of clients are on line.
 */
#define BTS_MIN_DELEGATE_CONNECTION_COUNT                   1

/**
 * Defines the number of seconds that should elapse between blocks
 */
#define BTS_BLOCKCHAIN_BLOCK_INTERVAL_SEC                   int64_t(10)

/**
 *  The maximum size of the raw data contained in the blockchain, this size is
 *  notional based upon the serilized size of all user-generated transactions in
 *  all blocks for one year.
 *
 *  Actual size on disk will likely be 2 or 3x this size due to indexes and other
 *  storeage overhead.
 *
 *  Adjusting this value will change the effective fee charged on transactions
 */
#define BTS_BLOCKCHAIN_MAX_SIZE                             (1024*1024*1024*int64_t(100)) // 100 GB
#define BTS_BLOCKCHAIN_MIN_NAME_SIZE                        1
#define BTS_BLOCKCHAIN_MAX_NAME_SIZE                        63
#define BTS_BLOCKCHAIN_MAX_NAME_DATA_SIZE                   (1024*64)
#define BTS_BLOCKCHAIN_MAX_MEMO_SIZE                        19 // bytes
#define BTS_BLOCKCHAIN_MAX_SYMBOL_SIZE                      8 // characters
#define BTS_BLOCKCHAIN_MIN_SYMBOL_SIZE                      3 // characters

/**
 *  The maximum amount that can be issued for user assets.
 *
 *  10^18 / 2^63 < 1  however, to support representing all share values as a double in
 *  languages like java script, we must stay within the epsilon so
 *
 *  10^15 / 2^53 < 1 allows all values to be represented as a double or an int64
 */
#define BTS_BLOCKCHAIN_MAX_SHARES                           (1000*1000*int64_t(1000)*1000*int64_t(1000))

/**
 * Initial shares read from the genesis block are scaled to this number. It is divided
 * by 100 so that new shares may be issued without exceeding BTS_BLOCKCHAIN_MAX_SHARES
 */
#define BTS_BLOCKCHAIN_INITIAL_SHARES                       (BTS_BLOCKCHAIN_MAX_SHARES/5)

/**
 *  The number of blocks expected per hour based upon the BTS_BLOCKCHAIN_BLOCK_INTERVAL_SEC
 */
#define BTS_BLOCKCHAIN_BLOCKS_PER_HOUR                      ((60*60)/BTS_BLOCKCHAIN_BLOCK_INTERVAL_SEC)

/**
 *  The number of blocks expected per day based upon the BTS_BLOCKCHAIN_BLOCK_INTERVAL_SEC
 */
#define BTS_BLOCKCHAIN_BLOCKS_PER_DAY                       (BTS_BLOCKCHAIN_BLOCKS_PER_HOUR*int64_t(24))

/**
 * The number of blocks expected per year based upon the BTS_BLOCKCHAIN_BLOCK_INTERVAL_SEC
 */
#define BTS_BLOCKCHAIN_BLOCKS_PER_YEAR                      (BTS_BLOCKCHAIN_BLOCKS_PER_DAY*int64_t(365))

#define BTS_BLOCKCHAIN_AVERAGE_TRX_SIZE                     512 // just a random assumption used to calibrate TRX per SEC
#define BTS_BLOCKCHAIN_MAX_TRX_PER_SECOND                   1  // (10)
#define BTS_BLOCKCHAIN_MAX_PENDING_QUEUE_SIZE               10 // (BTS_BLOCKCHAIN_MAX_TRX_PER_SECOND * BTS_BLOCKCHAIN_BLOCK_INTERVAL_SEC)

/** defines the maximum block size allowed, 2 MB per hour */
#define BTS_BLOCKCHAIN_MAX_BLOCK_SIZE                       (10 * BTS_BLOCKCHAIN_AVERAGE_TRX_SIZE * BTS_BLOCKCHAIN_MAX_PENDING_QUEUE_SIZE )

/**
    This constant defines the number of blocks a delegate must produce before
    they are expected to break even on registration costs with their earned income.

 *   Currently set to 2 hours of active block production to break even.
 */
#define BTS_BLOCKCHAIN_DELEGATE_REGISTRATION_FEE            (BTS_BLOCKCHAIN_BLOCKS_PER_DAY/12)

/**
    If you are going to create an asset, you expect that it will be used in transactions.  We would
    like to limit the issuance of assets that have no demand for transactions, so we charge a fee
    proportional to average transaction fees included in a block (AKA delegate pay).  This constant
    defines the number of blocks worth of transactions that justify the creation of a new asset.

    The fee is set such that the transactions of this asset alone could justify filling up 2 full weeks of
    block production.
 */
#define BTS_BLOCKCHAIN_ASSET_REGISTRATION_FEE               (BTS_BLOCKCHAIN_BLOCKS_PER_DAY * 14)
<commit_msg>we will test with 2 second blocks now<commit_after>#pragma once

#include <stdint.h>

/* Comment out this line for a non-test network */
#define BTS_TEST_NETWORK

#define BTS_TEST_NETWORK_VERSION                            62 // autogenerated

/** @file bts/blockchain/config.hpp
 *  @brief Defines global constants that determine blockchain behavior
 */
#define BTS_BLOCKCHAIN_VERSION                              109
#define BTS_BLOCKCHAIN_DATABASE_VERSION                     164

/**
 *  The address prepended to string representation of
 *  addresses.
 *
 *  Changing these parameters will result in a hard fork.
 */
#define BTS_ADDRESS_PREFIX                                  "XTS"
#define BTS_BLOCKCHAIN_SYMBOL                               "XTS"
#define BTS_BLOCKCHAIN_NAME                                 "BitShares XTS"
#define BTS_BLOCKCHAIN_DESCRIPTION                          "BitShares Test Network"
#define BTS_BLOCKCHAIN_PRECISION                            100000
#define BTS_BLOCKCHAIN_MAX_TRANSACTION_EXPIRATION_SEC       (60*60*24*2)
#define BTS_BLOCKCHAIN_MIN_YIELD_PERIOD_SEC                 (60*60*24) // 24 hours

#define BTS_BLOCKCHAIN_MIN_BURN_FEE                         BTS_BLOCKCHAIN_PRECISION * 1 // 1 XTS
#define BTS_BLOCKCHAIN_DEFAULT_RELAY_FEE                    10000 // XTS
#define BTS_BLOCKCHAIN_MINIMUM_SHORT_ORDER_SIZE             (BTS_BLOCKCHAIN_PRECISION*100)
#define BTS_BLOCKCHAIN_MAX_SHORT_PERIOD_SEC                 (2*60*60) // 2 hours for test network

/**
 * The number of delegates that the blockchain is designed to support
 */
#define BTS_BLOCKCHAIN_NUM_DELEGATES                        uint32_t(101)
#define BTS_BLOCKCHAIN_MAX_SLATE_SIZE                       (BTS_BLOCKCHAIN_NUM_DELEGATES + (BTS_BLOCKCHAIN_NUM_DELEGATES/10))
#define BTS_BLOCKCHAIN_MIN_FEEDS                            ((BTS_BLOCKCHAIN_NUM_DELEGATES/2) + 1)
#define BTS_BLOCKCHAIN_MAX_UNDO_HISTORY                     (BTS_BLOCKCHAIN_NUM_DELEGATES*4)

#define BTS_BLOCKCHAIN_ENABLE_NEGATIVE_VOTES                false

#define BTS_MAX_DELEGATE_PAY_PER_BLOCK                      int64_t( 50 * BTS_BLOCKCHAIN_PRECISION ) // 50 XTS

/**
 * To prevent a delegate from producing blocks on split network,
 * we check the connection count.  This means no blocks get produced
 * until at least a minimum number of clients are on line.
 */
#define BTS_MIN_DELEGATE_CONNECTION_COUNT                   1

/**
 * Defines the number of seconds that should elapse between blocks
 */
#define BTS_BLOCKCHAIN_BLOCK_INTERVAL_SEC                   int64_t(2)

/**
 *  The maximum size of the raw data contained in the blockchain, this size is
 *  notional based upon the serilized size of all user-generated transactions in
 *  all blocks for one year.
 *
 *  Actual size on disk will likely be 2 or 3x this size due to indexes and other
 *  storeage overhead.
 *
 *  Adjusting this value will change the effective fee charged on transactions
 */
#define BTS_BLOCKCHAIN_MAX_SIZE                             (1024*1024*1024*int64_t(100)) // 100 GB
#define BTS_BLOCKCHAIN_MIN_NAME_SIZE                        1
#define BTS_BLOCKCHAIN_MAX_NAME_SIZE                        63
#define BTS_BLOCKCHAIN_MAX_NAME_DATA_SIZE                   (1024*64)
#define BTS_BLOCKCHAIN_MAX_MEMO_SIZE                        19 // bytes
#define BTS_BLOCKCHAIN_MAX_SYMBOL_SIZE                      8 // characters
#define BTS_BLOCKCHAIN_MIN_SYMBOL_SIZE                      3 // characters

/**
 *  The maximum amount that can be issued for user assets.
 *
 *  10^18 / 2^63 < 1  however, to support representing all share values as a double in
 *  languages like java script, we must stay within the epsilon so
 *
 *  10^15 / 2^53 < 1 allows all values to be represented as a double or an int64
 */
#define BTS_BLOCKCHAIN_MAX_SHARES                           (1000*1000*int64_t(1000)*1000*int64_t(1000))

/**
 * Initial shares read from the genesis block are scaled to this number. It is divided
 * by 100 so that new shares may be issued without exceeding BTS_BLOCKCHAIN_MAX_SHARES
 */
#define BTS_BLOCKCHAIN_INITIAL_SHARES                       (BTS_BLOCKCHAIN_MAX_SHARES/5)

/**
 *  The number of blocks expected per hour based upon the BTS_BLOCKCHAIN_BLOCK_INTERVAL_SEC
 */
#define BTS_BLOCKCHAIN_BLOCKS_PER_HOUR                      ((60*60)/BTS_BLOCKCHAIN_BLOCK_INTERVAL_SEC)

/**
 *  The number of blocks expected per day based upon the BTS_BLOCKCHAIN_BLOCK_INTERVAL_SEC
 */
#define BTS_BLOCKCHAIN_BLOCKS_PER_DAY                       (BTS_BLOCKCHAIN_BLOCKS_PER_HOUR*int64_t(24))

/**
 * The number of blocks expected per year based upon the BTS_BLOCKCHAIN_BLOCK_INTERVAL_SEC
 */
#define BTS_BLOCKCHAIN_BLOCKS_PER_YEAR                      (BTS_BLOCKCHAIN_BLOCKS_PER_DAY*int64_t(365))

#define BTS_BLOCKCHAIN_AVERAGE_TRX_SIZE                     512 // just a random assumption used to calibrate TRX per SEC
#define BTS_BLOCKCHAIN_MAX_TRX_PER_SECOND                   1  // (10)
#define BTS_BLOCKCHAIN_MAX_PENDING_QUEUE_SIZE               10 // (BTS_BLOCKCHAIN_MAX_TRX_PER_SECOND * BTS_BLOCKCHAIN_BLOCK_INTERVAL_SEC)

/** defines the maximum block size allowed, 2 MB per hour */
#define BTS_BLOCKCHAIN_MAX_BLOCK_SIZE                       (10 * BTS_BLOCKCHAIN_AVERAGE_TRX_SIZE * BTS_BLOCKCHAIN_MAX_PENDING_QUEUE_SIZE )

/**
    This constant defines the number of blocks a delegate must produce before
    they are expected to break even on registration costs with their earned income.

 *   Currently set to 2 hours of active block production to break even.
 */
#define BTS_BLOCKCHAIN_DELEGATE_REGISTRATION_FEE            (BTS_BLOCKCHAIN_BLOCKS_PER_DAY/12)

/**
    If you are going to create an asset, you expect that it will be used in transactions.  We would
    like to limit the issuance of assets that have no demand for transactions, so we charge a fee
    proportional to average transaction fees included in a block (AKA delegate pay).  This constant
    defines the number of blocks worth of transactions that justify the creation of a new asset.

    The fee is set such that the transactions of this asset alone could justify filling up 2 full weeks of
    block production.
 */
#define BTS_BLOCKCHAIN_ASSET_REGISTRATION_FEE               (BTS_BLOCKCHAIN_BLOCKS_PER_DAY * 14)
<|endoftext|>