///////////////////////////////////////////////////////////////////////////////
// File: GKZCache.hh
//
// In this class we cache the results of GKZ computations, since they might be
// computed a lot.
///////////////////////////////////////////////////////////////////////////////

#ifndef GKZCACHE_HH
#define GKZCACHE_HH

#include "mptopcom_typedefs.hh"
#include "TriangNode.hh"
#include "Flip.hh"
#include "GKZ.hh"

#include "LRUCache.hh"

template<bool checkFine>
class GKZCache{
   private:
      const gkz_type& gkz;
      mutable LRUCache<TriangNode, gkz_vector_type> triang_cache;
      // mutable LRUCache<Flip, gkz_vector_type> flip_cache;

   public:
      GKZCache(int size, const gkz_type& gkz_in): gkz(gkz_in), triang_cache(size) {}//, flip_cache(size) {}

      gkz_vector_type evaluate(const TriangNode& t) const{
         if(triang_cache.exist(t)){
            return triang_cache.get(t);
         } else {
            gkz_vector_type result;
            if(checkFine){
               result = gkz.evaluate_fine(t);
            } else {
               result = gkz.evaluate(t);
            }
            triang_cache.put(t, result);
            return triang_cache.get(t);
         }
      }
      
      gkz_vector_type evaluate(const Flip& f) const{
         if(checkFine){
            return gkz.evaluate_fine(f);
         } else {
            return gkz.evaluate(f);
         }
      }
      
      gkz_vector_type evaluate(const TriangNode& source, const TriangNode& target) const{
         return evaluate(target) - evaluate(source);
      }

};

#endif
