34 #ifndef SHARK_LINALG_LRUCACHE_H 35 #define SHARK_LINALG_LRUCACHE_H 38 #include <boost/intrusive/list.hpp> 57 struct CacheEntry:
public boost::intrusive::list_base_hook<>
61 CacheEntry():length(0){}
65 LRUCache(std::size_t lines, std::size_t cachesize = 0x4000000)
68 , m_maxSize( cachesize ){}
76 return m_cacheEntry[i].length != 0;
80 return m_cacheEntry[i].length;
85 return m_lruList.size();
94 CacheEntry& entry = m_cacheEntry[i];
97 cacheCreateRow(entry,size);
99 if(entry.length >= size)
100 cacheRedeclareNewest(entry);
109 return m_cacheEntry[i].data;
114 return m_cacheEntry[i].data;
127 CacheEntry& block = m_cacheEntry[i];
128 m_lruList.erase(m_lruList.iterator_to(block));
129 m_lruList.push_back(block);
134 typedef typename boost::intrusive::list<CacheEntry>::iterator Iterator;
139 CacheEntry& cachei = m_cacheEntry[i];
140 CacheEntry& cachej = m_cacheEntry[j];
144 Iterator pos = m_lruList.iterator_to( cachei );
145 m_lruList.insert(pos,cachej);
146 m_lruList.erase(pos);
148 Iterator pos = m_lruList.iterator_to( cachej );
149 m_lruList.insert(pos,cachei);
150 m_lruList.erase(pos);
152 Iterator posi = m_lruList.iterator_to( cachei );
153 Iterator posj = m_lruList.iterator_to( cachej );
157 Iterator incposi = posi;++incposi;
158 Iterator incposj = posj;++incposj;
162 m_lruList.erase( posj );
163 m_lruList.insert(posi,cachej);
164 }
else if(incposj == posi){
165 m_lruList.erase( posi );
166 m_lruList.insert(posj,cachei);
170 m_lruList.erase( m_lruList.iterator_to( cachei ) );
171 m_lruList.erase( m_lruList.iterator_to( cachej ) );
173 m_lruList.insert(incposi,cachej);
174 m_lruList.insert(incposj,cachei);
188 typename boost::intrusive::list<CacheEntry>::const_iterator iter = m_lruList.begin();
189 std::advance(iter,i);
190 return &(*iter)-&m_cacheEntry[0];
198 ensureFreeMemory(m_maxSize);
202 void cacheRedeclareNewest(CacheEntry& block){
203 m_lruList.erase(m_lruList.iterator_to(block));
204 m_lruList.push_front(block);
208 void cacheCreateRow(CacheEntry& block,std::size_t
size){
210 ensureFreeMemory(size);
212 block.data =
new T[
size];
213 m_lruList.push_front(block);
217 void cacheRemoveRow(CacheEntry& block){
218 m_cacheSize -= block.length;
219 m_lruList.erase( m_lruList.iterator_to( block ) );
224 void resizeLine(CacheEntry& block,std::size_t size){
227 T* newLine =
new T[
size];
228 std::copy(block.data,block.data+std::min(size,block.length),newLine);
231 cacheRemoveRow(block);
233 ensureFreeMemory(size);
236 block.data = newLine;
239 m_lruList.push_front(block);
243 void ensureFreeMemory(std::size_t size){
245 while(m_maxSize-m_cacheSize < size){
246 cacheRemoveRow(m_lruList.back());
250 std::vector<CacheEntry> m_cacheEntry;
251 boost::intrusive::list<CacheEntry> m_lruList;
253 std::size_t m_cacheSize;
254 std::size_t m_maxSize;