//------------------------------------------------------------
// $Id: Statistics.h,v 1.1.1.1.2.1 2000/06/14 17:46:35 yamauchi Exp $
//------------------------------------------------------------
//	(M\pi)^2 Statistics 統計情報
//	1999年6月25日(金) 
//	Copyright (C) 1996--1999 YAMAUCHI Hitoshi 山内 斉
// 
//	statistics を使う場合には、USE_STAT フラグをたててコンパイル
//	を行う．
// 	(original statistics.h)
//------------------------------------------------------------
#ifndef _Statistics_h
#define _Statistics_h 1

#include "mpi2_funcs.h"

//------------------------------------------------------------
// 通信とは異なる statistics
//------------------------------------------------------------
class GeneralStatistics {
private:
    GeneralStatistics(const GeneralStatistics& rhs);
    const GeneralStatistics& operator=(const GeneralStatistics& rhs);
    
protected:
    // HemiCube の生成数
    int    mNumberOfGenHC;
    
public:    
    GeneralStatistics(void)
    {
	this->mNumberOfGenHC = 0;
    }
    
    // HemiCube の生産数
    void incHCGenNum(void) 		{ this->mNumberOfGenHC++;	}
    int  getHCGenNum(void) const 	{ return(this->mNumberOfGenHC);	}

    void print(const char* pMes)
    {
	cout << pMes << "total generated number of HCs " <<
		this->mNumberOfGenHC << endl;
    }
};


//------------------------------------------------------------
// 通信バッファの用いる statistics
//------------------------------------------------------------
//	(送・受信オブジェクトの総数 / 送・受信回数) で平均一回あたりい
//	くつのオブジェクトを送・受信したのかわかる．
//------------------------------
class CommunBufStatistics  {
protected:
    int mMaxQueueLen; 		// 送信側のキュー長 (送信側のみ)
    int mNSendRecv;		// 送信 or 受信回数
    int mNObjs;			// 送信 or 受信オブジェクト総数

public:
    CommunBufStatistics (void)
    {
	this->init();
    }
    ~CommunBufStatistics (void){}
    CommunBufStatistics (const CommunBufStatistics & rhs)
    {
	this->mMaxQueueLen = rhs.mMaxQueueLen;
	this->mNSendRecv   = rhs.mNSendRecv;
	this->mNObjs	   = rhs.mNObjs;
    }
    const CommunBufStatistics & operator=(const CommunBufStatistics & rhs)
    {
	if(this != &rhs)
	{
	    this->mMaxQueueLen = rhs.mMaxQueueLen;
	    this->mNSendRecv   = rhs.mNSendRecv;
	    this->mNObjs       = rhs.mNObjs;
	}
	return(*this);
    }
    void init(void)
    {
	this->mMaxQueueLen = 0;
	this->mNSendRecv   = 0;
	this->mNObjs	   = 0;
    }

    // 常に現在のキュー長を受け，最大のキュー長を記録する．
    void reportQueLen(int quelen)
    {
#ifdef USE_STAT
	if(quelen > this->mMaxQueueLen)
	{
	    this->mMaxQueueLen = quelen;
	}
#else
	return;
	quelen = quelen;	// for -Wall, never reached
#endif
    }
    // 一回の送信で送った(受信で受けた)物体数の記録
    void reportNSendRecvObjs(int n_objes)
    {
#ifdef USE_STAT
	this->mNSendRecv++;
	this->mNObjs += n_objes;
#else
	return;
	n_objes = n_objes;	// for -Wall, never reached
#endif
    }

    int getMaxQueueLen(void) const 	{ return(this->mMaxQueueLen);	}
    int getNSendRecv(void) const	{ return(this->mNSendRecv);	}
    int getNObjs(void) const 		{ return(this->mNObjs);		}

    double getNObjParSend(void) const 
    {
	if(this->mNSendRecv == 0)
	{
	    return(0.0);	// 利用されなかった場合には 0.0 を返す
	}else
	{
	    return(((double)this->mNObjs) / ((double)this->mNSendRecv));
	}
    }
};


//------------------------------------------------------------
// Host の statistics
//------------------------------------------------------------
class HostStatistics {
private:
    HostStatistics(const HostStatistics& rhs);
    const HostStatistics& operator=(const HostStatistics& rhs);
protected:
    // host が受信した PEstat の数
    double mHostGetPEStats;
    
public:
    HostStatistics(void)
    {
	this->init();
    }
    void init(void)
    {
	this->mHostGetPEStats = 0.0;
    }
    void incrGetPEStatsNum(void) { this->mHostGetPEStats++;	}
    void print(void) const 
    {
	// cout << "// host :: get PEstat num " << this->mHostGetPEStats << endl;
    }
};

#endif				// #define _Statistics_h 1
