1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
| #include<hash_map>
using namespace std;
template < class K, class V, int limsize = 1000, int BiqQ = 0x7fffffff, int SmallQ=0 >
class cache
{
public:
cache() { m_size =0;}
~cache()
{
for(listiter ilist = m_list.begin(); ilist != m_list.end(); ilist++)
delete (*ilist).m_p;
}
V* operator[](K& k)
{
mapiter imap = m_map.find(k);
if(imap== m_map.end()) return ((V*) -1);
listiter ilist = (*imap).second;
V* p= (*ilist).m_p;
m_list.erase(ilist);
push_back(p, imap);
return p;
}
void push_back(const K &k,V* p)
{
int size = p->size();
bool Remove;
listiter ilist =NULL;
do
{
Remove = m_size>limsize;
if(Remove)
{
Remove = m_list.size()> SmallQ;
}
else
{
Remove = m_list.size()> BiqQ;
}
if(Remove)
{
ilist = m_list.end();
ilist--;
m_size -= ((*ilist).m_p)->size();
delete (*ilist).m_p;
m_map.erase((*ilist).m_mapiter);
m_list.erase(ilist);
}
} while(Remove);
mapiter imap;
ASSERT(m_map.find(k)==m_map.end()); // No, you are not allowed to insert twice the same elment
// begin bad writing : The 2 next lines are bad writing, but I do not know how to avoid it.. please help
ASSERT(m_map.size() == m_list.size());
TRACE(" %d \n",m_map.size());
m_map[k]=ilist;
TRACE(" %d \n",m_map.size());
ASSERT(m_map.size() == m_list.size()+1);
imap = m_map.find(k);
// They should be replaced by some :
// imap = m_map.insert(k,ilist);
// end bad writing : please help me to fix that
ASSERT(m_map[k]==ilist);
push_back(p, imap);
m_size += p->size();
}
bool iscached(V* p)
{
return (p != (V*) -1);
}
//#ifdef _DEBUG
// int dbggetmapsize()
// {
// ASSERT(m_map.size() == m_list.size());
// TRACE(" dbggetmapsize %d (m_size %d) order : ",m_map.size(),m_size);
// for(listiter ilist = m_list.begin(); ilist != m_list.end(); ilist++)
// TRACE(" %d ", (*((*ilist).m_mapiter)).first);
// TRACE("\n");
// return m_map.size();
// }
// int dbggetcachesize()
// {
// return m_size;
// }
// V* dbgcheck(K &k)
// {
// mapiter imap = m_map.find(k);
// if(imap== m_map.end()) return ((V*) -1);
// listiter ilist = (*imap).second;
// return (*ilist).m_p;
//
// }
//#endif _DEBUG
private:
class listitem;
typedef list<listitem>::iterator listiter;
typedef hash_map< K,listiter>::iterator mapiter;
class listitem
{
friend class cache< K, V, limsize, BiqQ, SmallQ > ;
private:
mapiter m_mapiter;
V* m_p;
};
list<listitem> m_list;
hash_map< K,listiter> m_map;
int m_size;
void push_back(V* p, mapiter &imap)
{
ASSERT(m_map.size() == m_list.size()+1);
m_list.push_front();
ASSERT(m_map.size() == m_list.size());
listiter ilist = m_list.begin();
(*ilist).m_mapiter = imap;
(*ilist).m_p = p;
(*imap).second = ilist;
ASSERT(m_map.size() == m_list.size());
}
}; |
Partager