#ifndef _CEGOQUERYCACHE_H_INCLUDED_
#define _CEGOQUERYCACHE_H_INCLUDED_
///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoQueryCache.h
// ----------------
// Cego query cache interface defintion
//      
// Design and Implementation by Bjoern Lemke
//
// (C)opyright 2000-2019 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"

class CegoQueryCache {

public:

    CegoQueryCache(int maxEntry, int maxCacheSize);
    ~CegoQueryCache();
    
    Element* getCacheInfo();
    Element* getCacheList();

    int getMaxEntry() const;
    void setMaxEntry(int maxEntry);
    
    int getMaxSize() const;
    void setMaxSize(int maxSize);
    
    int getNumQueryCache() const;

    int getUsedSize() const;
	
    void invalidate(const CegoObject& td);

    CegoFieldValue*** claimEntry(const Chain& queryId, ListT<CegoField>& cacheSchema, int& cacheRows);
    void releaseEntry(const Chain& queryId);
    
    void addEntry(const Chain& queryId, const SetT<CegoObject>& objList, ListT< ListT<CegoFieldValue> >* pCacheList, const ListT<CegoField>& cacheSchema);
    
    void clean();
    
private:

    void PR();
    void PW();
    void V();
    
    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();

	int getSize() const;
	
	int getHashPos(int hashSize) const;

	
	bool cleanCache();
	const Chain getQueryId() const;
	int getNumRows() 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:
	
	Chain _queryId;
	SetT<CegoObject> _objList;
	CegoFieldValue*** _pCacheArray;
	ListT<CegoField> _cacheSchema;
	unsigned long _numHit;
	int _numRow;
	int _numCol;
	int _numUsed;
    };

    int _maxEntry;
    int _maxSize;
    int _usedSize;

    HashT<QueryCacheEntry>* _pQueryCache;    
    // SetT<QueryCacheEntry> _queryCache;    
};

#endif
