#ifndef _CEGOLOCKHANDLER_H_INCLUDED_
#define _CEGOLOCKHANDLER_H_INCLUDED_
///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoLockHandler.h
// -----------------
// Cego lock handler class definition
//     
// Design and Implementation by Bjoern Lemke
//
// (C)opyright 2000-2025 Bjoern Lemke
//
// INTERFACE MODULE
//
// Class: CegoLockHandler
// 
// Description: All semaphore lock operations on database files, pool buffers, pages and records level
//              are managed using the LockHandler class.
//              A number of available semaphores is distributed among all required lock operations.
//              
//             
// Status: CLEAN 
//
///////////////////////////////////////////////////////////////////////////////

// CEGO INCLUDES
#include "CegoDefs.h"
#include "CegoDataPointer.h"
#include "CegoBufferPage.h"
#include "CegoObject.h"
#include "CegoAdminHandler.h"

class CegoDatabaseManager;

class CegoLockHandler {
    
public:

    enum LockMode { READ, WRITE };

    CegoLockHandler(CegoDatabaseManager* pDBMng);
    ~CegoLockHandler();

    void initLocks();
    void deleteLocks();
    unsigned long long lockRecord(const CegoDataPointer& dp, enum LockMode lockMode);
    void unlockRecord(unsigned long long id);
    unsigned long long lockRBRecord(const CegoDataPointer& dp, enum LockMode lockMode);
    void unlockRBRecord(unsigned long long id);
    unsigned long long lockSysRecord(const CegoDataPointer& dp, enum LockMode lockMode);
    void unlockSysRecord(unsigned long long id);
    unsigned long long lockSysPage(PageIdType pageId, enum LockMode lockMode);
    void unlockSysPage(unsigned long long id);
    unsigned long long lockData(CegoObject::ObjectType type, PageIdType pageId, enum LockMode lockMode);
    void unlockData(CegoObject::ObjectType type, unsigned long long id);
    void lockDataFile(unsigned fileId, enum LockMode lockMode);
    void unlockDataFile(unsigned fileId);
    void lockBufferPool(unsigned hashId, enum LockMode lockMode);
    void unlockBufferPool(unsigned hashId);
    void lockBufferPool();
    void unlockBufferPool();
    void getLockStat(unsigned semId, Chain& lockName, unsigned& lockCount, unsigned long long &numRdLock, unsigned long long &numWrLock, unsigned long long &sumRdDelay, unsigned long long &sumWrDelay);
    void getAggLockStat(const Chain& lockName, unsigned& numLock, unsigned& lockCount, unsigned long long &numRdLock, unsigned long long &numWrLock, unsigned long long &sumRdDelay, unsigned long long &sumWrDelay);

    void verifyLocks(CegoAdminHandler* pAH);
    
private:

    unsigned long long lockDataPage(PageIdType pageId, enum LockMode lockMode);
    void unlockDataPage(unsigned long long id);
    unsigned long long lockIndexPage(PageIdType pageId, enum LockMode lockMode);
    void unlockIndexPage(unsigned long long id);
    unsigned long long lockRBPage(PageIdType pageId, enum LockMode lockMode);
    void unlockRBPage(unsigned long long id);

    void verifyLockGroup(CegoAdminHandler* pAH, unsigned low, unsigned high, const Chain lockGroup);
	
    unsigned long long _nextLockId;

    
    unsigned *_lockCount; 

    struct RecordLock
    {
 	unsigned long long lockId;
	unsigned semId;
    } *_recordLock, *_rbRecordLock, *_sysRecordLock; 
    
    struct PageLock
    {
	unsigned long long lockId;
	PageIdType pageId;
	unsigned semId;
    } *_sysPageLock, 
	  *_dataPageLock, 
	  *_idxPageLock,
	  *_rbPageLock;
    
    unsigned _numRecSema;
    unsigned _numRBRecSema;
    unsigned _numSysRecSema;
    unsigned _numSysPageSema;
    unsigned _numDataPageSema;
    unsigned _numIdxPageSema;
    unsigned _numRBPageSema;
    unsigned _numDataFileSema;
    unsigned _numBufferPoolSema;
    unsigned _numSema;
    unsigned _pageLockTimeout;
    unsigned _recLockTimeout;
    unsigned _fileLockTimeout;
    unsigned _poolLockTimeout;
    unsigned _numLockTries;
    unsigned _poolLockRange;
    
    CegoDatabaseManager *_pDBMng;

    unsigned long _modId;
};
#endif
