#ifndef _CEGOBUFFERPOOL_H_INCLUDED_
#define _CEGOBUFFERPOOL_H_INCLUDED_
///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoBufferPool.h
// ----------------
// Cego BufferPool class definition
//                                                         
// Design and Implementation by Bjoern Lemke
//
// (C)opyright 2000-2010 Bjoern Lemke
//
// 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, or (at your option)
// any later version.
// 
// 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; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// INTERFACE MODULE
//
// Class: CegoBufferPool
// 
// Description: Cego buffer pool
//
// Status: QG-2.6
//
///////////////////////////////////////////////////////////////////////////////

#include <lfc/Chain.h>
#include <lfc/NanoTimer.h>

#include "CegoXMLSpace.h"
#include "CegoLogManager.h"
#include "CegoFileHandler.h"
#include "CegoBufferPage.h"
#include "CegoBufferPoolEntry.h"
#include "CegoLockHandler.h"

class CegoBufferPool : public CegoLogManager {
    
public:
    
    enum FixMode { SYNC, NOSYNC, PERSISTENT };
    
    CegoBufferPool(const Chain& xmlDef, const Chain& logFile);
    ~CegoBufferPool();
    
    void initPool(long numPages);
    void removePool();
    
    void attachPool();
    void detachPool();
    
    void bufferFix(CegoBufferPage &bp, int tabSetId, int fileId, int pageId, FixMode m, CegoLockHandler *pLockHandle, int numTry = 0);
    void emptyFix(CegoBufferPage &bp, int tabSetId, FixMode m, CegoFileHandler::FileType ft, CegoLockHandler *pLockHandle, bool doAppend = false);

    void bufferUnfix(CegoBufferPage &bp, bool isDirty, CegoLockHandler *pLockHandle);
    void bufferRelease(CegoBufferPage &bp, CegoLockHandler *pLockHandle);

    int writeCheckPoint(int tabSetId, bool switchLog, const Chain& escCmd, int timeout, CegoLockHandler *pLockHandle);
    void writeAndRemoveTabSet(int tabSetId, CegoLockHandler *pLockHandle);

    void poolInfo(int& pageSize,
		  long& numTotal,
		  long& numUsed,
		  long& numFree,
		  long& numDirty,
		  long& numFixes,
		  long& numPersistent,
		  long& numNoSync,
		  long& numDiskRead,
		  long& numDiskWrite,
		  long& hitRate,
		  long& avgReadDelay,
		  long& avgWriteDelay,
		  long& curFixCount,
		  long& maxFixCount,
		  int& statStart);

    void getPoolEntryList(ListT<CegoBufferPoolEntry>& entryList);

    void resetStats();

    void printPool();

    Chain getDBName();

private:

    typedef struct BufferPoolHead {
	int numPages;
    } BufferPoolHead;
    
    enum OccState { NOT_OCCUPIED, WRITE_ON_SYNC, WRITE_ON_DIRTY, PERSISTENT_OCCUPIED };
    
    typedef struct BufferHead {
	OccState isOccupied;
	char isDirty;
	int numFixes;
	int tabSetId;
	int fileId;
	int pageId;
	int fixStat;
    } BufferHead;

    void logBM(int tabSetId, int fileId, unsigned* fbm, int fbmSize);
    
    Chain _dbName;
    long _numPages;
    int _key;
    
    void *_pBufPool;

    long _fixCount;
    long _numDiskRead;    
    long _numDiskWrite;
    long _avgReadDelay;
    long _avgWriteDelay;

    NanoTimer _diskReadTimer;
    NanoTimer _diskWriteTimer;

    int _statStart;
    int _maxFixTries;

    unsigned long _modId;
};



#endif




