#ifndef _CEGOTABLECACHE_H_INCLUDED_
#define _CEGOTABLECACHE_H_INCLUDED_
///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoTableCache.h
// ----------------
// Cego query cache interface defintion
//      
// Design and Implementation by Bjoern Lemke
//
// (C)opyright 2000-2025 Bjoern Lemke
//
// INTERFACE MODULE
//
// Class: CegoTableCache
//
// Description: Table Cache Management
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

#include <lfcbase/Chain.h>
#include <lfcbase/ListT.h>
#include <lfcbase/HashT.h>
#include <lfcbase/Matcher.h>

#include "CegoField.h"
#include "CegoFieldValue.h"
#include "CegoAttrDesc.h"
#include "CegoComparison.h"
#include "CegoAdminHandler.h"

// forward declaration
class CegoDatabaseManager;

class CegoTableCache {
    
public:
    
    CegoTableCache(unsigned tabSetId, const Chain& cacheFilter, unsigned maxSize, unsigned maxEntry, unsigned hashRange, CegoDatabaseManager *pDBMng);
    ~CegoTableCache();

    Element* getCacheInfo();
    Element* getCacheList();
    const Chain& getFilter() const;
    void setFilter(const Chain& cacheFilter);
    unsigned getMaxSize() const;
    void setMaxSize(unsigned maxSize);
    unsigned getUsedSize() const;
    const unsigned getNumTableCache() const;
    void invalidate(const Chain& tableName);
    CegoFieldValue*** claimEntry(const Chain& tableName, unsigned& numRow, unsigned& numCol);
    void releaseEntry(const Chain& tableName);
    bool matchEntry(const Chain& tableName);
    bool addEntry(const Chain& tableName, ListT< ListT<CegoFieldValue> >* pCache);
    void clean();
    void getTCLockStat(unsigned& lockCount, unsigned long long &numRdLock, unsigned long long &numWrLock, unsigned long long &sumRdDelay, unsigned long long &sumWrDelay);

    void verifyLock(CegoAdminHandler* pAH);
    
private:

    class TableCacheEntry {
	
    public:

	TableCacheEntry();
	TableCacheEntry(unsigned tabSetId, const Chain& tableName);
	TableCacheEntry(unsigned tabSetId, const Chain& tableName, ListT< ListT<CegoFieldValue> >* pCacheList);
	~TableCacheEntry();

	const unsigned getSize() const;

	unsigned getHashPos(unsigned hashSize) const;
	
	unsigned getNumRows() const;
	unsigned getNumCols() const;

	const Chain& getTableName() const;
	unsigned getTabSetId() const;

	CegoFieldValue*** claimCache();
	void releaseCache();
	
	unsigned long getHit() const;
	void incHit();

	bool cleanCache();
	
	TableCacheEntry& operator = ( const TableCacheEntry& tce);
        bool operator == ( const TableCacheEntry& tce);
	
	friend ostream& operator << (ostream& s, const TableCacheEntry& tce)
	{
	    s << "Cache " << tce._tabSetId << " " << tce._tableName;
	    return s;
	}

    private:
	
	Chain _tableName;
	unsigned _tabSetId;
	CegoFieldValue*** _pCacheArray;
	unsigned _numRow;
	unsigned _numCol;
	unsigned _numUsed;
	unsigned long _numHit;
	
    };

    void PR();
    void PW();
    void V();
    
    unsigned _tabSetId;
    Chain _cacheFilter;
    unsigned _maxEntry;
    unsigned _maxSize;
    unsigned _hashRange;
    unsigned _usedSize;
    unsigned _numFail;
    CegoDatabaseManager* _pDBMng;
    HashT<TableCacheEntry>* _pTableCache;
    Matcher* _pTableFilter;
};
#endif
