#ifndef _CEGODBTHREADPOOL_H_INCLUDED_
#define _CEGODBTHREADPOOL_H_INCLUDED_
///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoDbThreadPool.h  
// ------------------
// Cego db threadpool class definition
//                                                        
// Design and Implementation by Bjoern Lemke
//
// (C)opyright 2000-2025 Bjoern Lemke
//
// INTERFACE MODULE
//
// Class: CegoDbThreadPool
//
// Description: Managing the database threads
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

#include <lfcbase/Chain.h>
#include <lfcbase/ListT.h>
#include <lfcbase/NetHandler.h>
#include <lfcbase/Net.h>

#include "CegoDbThread.h"
#include "CegoBufferPool.h"
#include "CegoLockHandler.h"
#include "CegoDbHandler.h"
#include "CegoAdminHandler.h"

class CegoDbThread;

class CegoDbThreadPool : public Thread {
    
 public:

    enum ThreadState { STARTING, READY, CONNECTED, BUSY };
  
    CegoDbThreadPool(unsigned poolLimit, CegoDatabaseManager *pDBMng, CegoDbHandler::ProtocolType protType);
    ~CegoDbThreadPool();

    bool init();
    void* job(void* arg);

    void loadObjects(unsigned tabSetId);
    void unloadObjects(unsigned tabSetId);
    void invalidateObject(unsigned tabSetId, const Chain& objName, CegoObject::ObjectType type);
    unsigned getPoolLimit() const;
    void getThreadInfo(unsigned i, unsigned long long& numRequest, unsigned long long& numQueryRequest, unsigned long long& threadLoad, unsigned long long& allocatedSort, ThreadState& state, Chain& lastAction);
    void getThreadHistory(unsigned i, ListT<CegoDbThread::QueryEntry>& queryList);
    void getQueryHistoryLast(unsigned numLast, ListT<CegoDbThread::QueryEntry>& queryList);
    void getQueryHistoryCost(unsigned numLast, ListT<CegoDbThread::QueryEntry>& queryList);
    void setState(unsigned i, ThreadState state);
    void incNumRequest(unsigned i);
    void incNumQueryRequest(unsigned i);
    void addThreadIdle(unsigned i, unsigned long long usec);
    void setTid(unsigned i, unsigned long long tid);
    void setThreadState(unsigned i, CegoDbThreadPool::ThreadState state);
    void abortThread(unsigned i);
    NetHandler* nextRequest();
    bool isBusy();
    bool isTerminated();
    void getLockStat(Chain& lockName, unsigned& lockCount, unsigned long long &numRdLock, unsigned long long &numWrLock, unsigned long long &sumRdDelay, unsigned long long &sumWrDelay);
    void getAggThreadLockStat(Chain& lockGroup, unsigned& numLock, unsigned& lockCount, unsigned long long &numRdLock, unsigned long long &numWrLock, unsigned long long &sumRdDelay, unsigned long long &sumWrDelay);
    void P(unsigned i);
    void V(unsigned i);

    void verifyLocks(CegoAdminHandler* pAH);
    
 private:

    void allocate();
    
    void lockQueue();
    void unlockQueue();

    unsigned long long* _threadId;
    ThreadState* _threadState;
    unsigned long long* _numRequest;
    unsigned long long* _numQueryRequest;
    unsigned long long* _threadIdle[THRMNG_NUMLOADSAMPLE];
    unsigned long long* _threadLoad;
    unsigned _samplePos;
    CegoDbThread** _threadList;
    unsigned _poolLimit;
    unsigned _dataPortNo;
    unsigned _maxSendLen;
    Chain _dataHostName;

    Net* _pNet;

    bool _isAllocated;
    bool _terminated;
    bool _joined;
    ListT<NetHandler*> _requestQueue;
    CegoDatabaseManager* _pDBMng;
    CegoDbHandler::ProtocolType _protType;

    unsigned long _modId;
};
#endif
