00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef Fennel_LRUVictimPolicy_Included
00025 #define Fennel_LRUVictimPolicy_Included
00026
00027 #include "fennel/common/IntrusiveDList.h"
00028
00029 FENNEL_BEGIN_NAMESPACE
00030
00035 class FENNEL_CACHE_EXPORT LRUVictim
00036 : public IntrusiveDListNode
00037 {
00038
00039
00040 };
00041
00054 template <class PageT>
00055 class LRUVictimPolicy
00056 {
00060 SXMutex mutex;
00061
00066 PageT *pageLRU;
00067
00072 PageT *pageMRU;
00073
00074 public:
00075
00083 typedef IntrusiveDListIter<PageT> PageIterator;
00084
00094 typedef IntrusiveDListIter<PageT> DirtyPageIterator;
00095
00106 typedef SXMutexSharedGuard SharedGuard;
00107
00111 typedef SXMutexExclusiveGuard ExclusiveGuard;
00112
00116 LRUVictimPolicy()
00117 {
00118 pageLRU = NULL;
00119 pageMRU = NULL;
00120 }
00121
00122 LRUVictimPolicy(const CacheParams ¶ms)
00123 {
00124 pageLRU = NULL;
00125 pageMRU = NULL;
00126 }
00127
00134 void setAllocatedPageCount(uint nCachePages)
00135 {
00136 }
00137
00145 void registerPage(PageT &page)
00146 {
00147
00148 ExclusiveGuard exclusiveGuard(mutex);
00149 if (!pageLRU) {
00150 pageLRU = &page;
00151 } else {
00152 page.IntrusiveDListNode::insertAfter(*pageMRU);
00153 }
00154 pageMRU = &page;
00155 }
00156
00164 void unregisterPage(PageT &page)
00165 {
00166 ExclusiveGuard exclusiveGuard(mutex);
00167 if (&page == pageLRU) {
00168 pageLRU = (PageT *) (page.getNext());
00169 }
00170 if (&page == pageMRU) {
00171 pageMRU = (PageT *) (page.getPrev());
00172 }
00173 page.IntrusiveDListNode::detach();
00174 }
00175
00186 void notifyPageAccess(PageT &page, bool pin)
00187 {
00188 ExclusiveGuard exclusiveGuard(mutex);
00189 if (&page == pageMRU) {
00190 return;
00191 }
00192 if (&page == pageLRU) {
00193 pageLRU = (PageT *) (page.getNext());
00194 }
00195 page.IntrusiveDListNode::detach();
00196 page.IntrusiveDListNode::insertAfter(*pageMRU);
00197 pageMRU = &page;
00198 }
00199
00207 void notifyPageNice(PageT &page)
00208 {
00209 ExclusiveGuard exclusiveGuard(mutex);
00210 if (&page == pageLRU) {
00211 return;
00212 }
00213 if (&page == pageMRU) {
00214 pageMRU = (PageT *) (page.getPrev());
00215 }
00216 page.IntrusiveDListNode::detach();
00217 page.IntrusiveDListNode::insertBefore(*pageLRU);
00218 pageLRU = &page;
00219 }
00220
00229 void notifyPageMap(PageT &page, bool pin)
00230 {
00231
00232
00233 notifyPageAccess(page, pin);
00234 }
00235
00244 void notifyPageUnmap(PageT &page, bool discard)
00245 {
00246
00247
00248 notifyPageAccess(page, false);
00249 }
00250
00257 void notifyPageUnpin(PageT &page)
00258 {
00259 }
00260
00267 void notifyPageDirty(PageT &page)
00268 {
00269 }
00270
00276 void notifyPageClean(PageT &page)
00277 {
00278 }
00279
00287 void notifyPageDiscard(BlockId blockId)
00288 {
00289 }
00290
00298 SXMutex &getMutex()
00299 {
00300 return mutex;
00301 }
00302
00309 std::pair<PageIterator,PageIterator> getVictimRange()
00310 {
00311 return std::pair<PageIterator,PageIterator>(
00312 PageIterator(pageLRU),PageIterator());
00313 }
00314
00321 std::pair<DirtyPageIterator,DirtyPageIterator> getDirtyVictimRange()
00322 {
00323 return
00324 static_cast<std::pair<DirtyPageIterator,DirtyPageIterator> >(
00325 getVictimRange());
00326 }
00327 };
00328
00329 FENNEL_END_NAMESPACE
00330
00331 #endif
00332
00333