// -*- mode: C++; c-file-style: "stroustrup"; c-basic-offset: 4; -*-
////////////////////////////////////////////////////////////////////
//
// $Id: cache.h 815 2011-09-10 12:57:27Z Sebastian Kupferschmid $
//
////////////////////////////////////////////////////////////////////

#ifndef SEARCH_CACHE_H
#define SEARCH_CACHE_H

#include <ext/hash_map>
#include <ext/slist>
#include <inttypes.h>
#include <map>
#include <vector>

class State;

class Cache {
protected:
    uint32_t size;
public:
    static const int32_t NOT_FOUND;    
    Cache(uint32_t size) : size(size) {}
    virtual int32_t& lookup(const State* state) = 0;
};

////////////////////////////////////////////////////////////////////

class NoCache : public Cache {
private:
    int32_t res;
public:
    NoCache(uint32_t) : Cache(0) {}
    virtual int32_t& lookup(const State*) {
	res = NOT_FOUND;
	return res;
    }
};

////////////////////////////////////////////////////////////////////

class BitstateCache : public Cache {
private:
    typedef std::vector<int32_t> cache_t;
    cache_t cachedStates;
public:
    BitstateCache(uint32_t size);
    virtual int32_t& lookup(const State* state);
};

////////////////////////////////////////////////////////////////////

class DiscretePartCache : public Cache {
private:
    typedef std::pair<const State*, int32_t> entry_t;
    typedef __gnu_cxx::slist<entry_t> list_t;
    typedef __gnu_cxx::hash_map<uint32_t, list_t> cache_t;
    
    cache_t cachedStates;
protected:
    virtual bool isEqual(const State* lhs, const State* rhs) const;
public:
    DiscretePartCache(uint32_t size);
    virtual int32_t& lookup(const State* state);
};

////////////////////////////////////////////////////////////////////

class WholeStateCache : public DiscretePartCache {
private:
    virtual bool isEqual(const State* lhs, const State* rhs) const;
public:
    WholeStateCache(uint32_t size);
};

#endif /* SEARCH_CACHE_H */
