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

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

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

// forward declaration
class CegoDatabaseManager;

class CegoTableCache {
    
public:
    
    CegoTableCache(int maxEntry, int maxCacheSize, CegoDatabaseManager *pDBMng);
    ~CegoTableCache();

    Element* getCacheInfo();
    Element* getCacheList();

    int getMaxEntry() const;
    void setMaxEntry(int maxEntry);

    int getMaxSize() const;
    void setMaxSize(int maxSize);

    int getUsedSize() const;
    
    const int getNumTableCache() const;

    void invalidate(int tabSetId, const Chain& tableName);

    CegoFieldValue*** claimEntry(int tabSetId, const Chain& tableName, int& numRow, int& numCol);
    void releaseEntry(int tabSetId, const Chain& tableName);
    
    void addEntry(int tabSetId, const Chain& tableName, ListT< ListT<CegoFieldValue> >* pCache);
    
    void clean();
    
private:
     
    void PR();
    void PW();
    void V();
    
    class TableCacheEntry {
	
    public:

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

	const int getSize() const;
	
	int getNumRows() const;
	int getNumCols() const;

	const Chain& getTableName() const;
	int 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;
	int _tabSetId;
	CegoFieldValue*** _pCacheArray;
	int _numRow;
	int _numCol;
	int _numUsed;
	unsigned long _numHit;
	
    };

    int _maxEntry;
    int _maxSize;
    int _usedSize;

    CegoDatabaseManager* _pDBMng;
    SetT<TableCacheEntry> _tableCache;  
};

#endif
