#include "cache_store.h"


// FIXME is_loaded : addresse de block et non addresse absolues
//    Le cache store ne stocke que des lignes et se moque des adresses

/*
bool CacheStore::is_loaded( list<int> *lines, int line)
{
    list<int>::iterator it;

    //
    // simple lookup : iterates over all elements and
    // returns true if found
    //
    for(it = lines->begin(); it != lines->end(); ++it)
    {
        if(*it == line )
            return true;
    }

    return false;
}
*/

bool CacheStore::is_loaded(Address address)
{
    list<int>::iterator it;

    if (associativity == DIRECT_MAPPING) {
        // direct mapping :
        //  the data is in a set determined by its modulo. The set size is 1
        unsigned int location = address.block;
        std::list<int> set = cache_lines[location];

        // this should be only one iteration
        for (it=set.begin(); it!= set.end(); ++it)
        {
            if (*it == address.block)
                return true;
        }
        return false;

    } else if (associativity == FULLY_ASSOCIATIVE) {
        // fully associative : 
        //    the data can be anywhere in the set. There is only 1 set, and it is
        //    in index 0

        // FIXME URGENT CA PLANTE ICI
        std::list<int> set = cache_lines[0];

        for (it=set.begin(); it != set.end(); ++it)
        {
            if (*it == address.block)
                return true;
        }
        return false;

    } else {
        // N-Way associative :
        //    the data can be anywhere in a N-Set which position is given
        //    by the modulo
        unsigned int location = address.block;
        std::list<int> set = cache_lines[location];

        for (it = set.begin(); it != set.end(); ++it)
        {
            if (*it == address.block)
                return true;
        }
        return false;
    }
}

/*
void CacheStore::do_load( list<int> *lines, int line)
{
   
     * LRU placement :
     * if the list contains more than *N* associativity
     *  remove the oldest element (back)
     *  and insert the new element (front)
     *
    if ( lines->size() >= associativity)
        lines->pop_back();

    lines->push_front(line); 
}*/

int CacheStore::get_line_width()
{
    return this->line_width;
}

// FIXME harmonize between address.absolute % line_width
//                  and    address.block
void CacheStore::do_load(Address address)
{
   // LRU replacement :
   // if the list contains more than *N* (assossiativity)
   //   then remove the oldest element (back)
   //   and insert the new element (front)
   if (associativity ==  DIRECT_MAPPING) {
       unsigned int location = address.as_absolute() % line_width;
       if (cache_lines[location].size() >= associativity)
           cache_lines[location].pop_back();

       cache_lines[location].push_front(address.block);

   } else if (associativity == FULLY_ASSOCIATIVE) {
       if(cache_lines[0].size() >= num_lines)
           cache_lines[0].pop_back();
       cache_lines[0].push_front(address.block);
   } else {

       unsigned int location = address.block;
       if(cache_lines[location].size() >= associativity)
           cache_lines[location].pop_back();
       cache_lines[location].push_front(address.block);
   }
}
