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

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

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

class CegoQueryCache {

public:

    CegoQueryCache(unsigned tabSetId, unsigned maxEntry, unsigned maxSize, unsigned threshold, unsigned hashRange);
    ~CegoQueryCache();
    
    Element* getCacheInfo();
    Element* getCacheList();
    unsigned getMaxEntry() const;
    unsigned getMaxSize() const;
    unsigned getThreshold() const;
    unsigned getNumQueryCache() const;
    unsigned long long getUsedSize() const;
    double getHitRate() const;
    unsigned getNumFail() const;
    void invalidate(const CegoObject& td);
    CegoFieldValue*** claimEntry(const Chain& queryId, ListT<CegoField>& cacheSchema, unsigned& cacheRows);
    void releaseEntry(const Chain& queryId);
    bool addEntry(const Chain& queryId, const SetT<CegoObject>& objList, ListT< ListT<CegoFieldValue> >* pCacheList, const ListT<CegoField>& cacheSchema);
    void clean();
    void getQCLockStat(unsigned& lockCount, unsigned long long &numRdLock, unsigned long long &numWrLock, unsigned long long &sumRdDelay, unsigned long long &sumWrDelay);

    void verifyLock(CegoAdminHandler* pAH);
    
private:
    
    class QueryCacheEntry {
	
    public:

	QueryCacheEntry();
	QueryCacheEntry(const Chain& queryId);
	QueryCacheEntry(const Chain& queryId, const SetT<CegoObject>& objectList, ListT< ListT<CegoFieldValue> >* pCacheList, const ListT<CegoField>& cacheSchema);
	~QueryCacheEntry();

	unsigned getSize() const;
	
	unsigned getHashPos(unsigned hashSize) const;

	bool cleanCache();
	const Chain getQueryId() const;
	unsigned getNumRows() const;
	unsigned getNumUsed() const;

	const SetT<CegoObject>& getObjectList() const;

	CegoFieldValue*** claimCache();
	void releaseCache();
	
	const ListT<CegoField>& getSchema() const;
	
	unsigned long getHit() const;
	void incHit();
	
	QueryCacheEntry& operator = ( const QueryCacheEntry& qce);
        bool operator == ( const QueryCacheEntry& qce);
	
	friend ostream& operator << (ostream& s, const QueryCacheEntry& qce)
	{
	    s << "Cache " << qce._queryId;
	    return s;
	}

    private:

	void calcSize();
	
	Chain _queryId;
	SetT<CegoObject> _objList;
	CegoFieldValue*** _pCacheArray;
	ListT<CegoField> _cacheSchema;
	unsigned long _numHit;
	unsigned _numRow;
	unsigned _numCol;
	unsigned _numUsed;
	unsigned _size;
    };

    void PR();
    void PW();
    void V();

    unsigned _tabSetId;
    unsigned _maxEntry;
    unsigned _threshold;
    unsigned _maxSize;
    unsigned _hashRange;
    unsigned long long _usedSize;
    unsigned _numFail;
    unsigned _numTry;
    unsigned _numHit;
    HashT<QueryCacheEntry>* _pQueryCache;
};
#endif
