LRUVictimPolicy.h

Go to the documentation of this file.
00001 /*
00002 // $Id: //open/dev/fennel/cache/LRUVictimPolicy.h#13 $
00003 // Fennel is a library of data storage and processing components.
00004 // Copyright (C) 2005-2009 The Eigenbase Project
00005 // Copyright (C) 2005-2009 SQLstream, Inc.
00006 // Copyright (C) 2005-2009 LucidEra, Inc.
00007 // Portions Copyright (C) 1999-2009 John V. Sichi
00008 //
00009 // This program is free software; you can redistribute it and/or modify it
00010 // under the terms of the GNU General Public License as published by the Free
00011 // Software Foundation; either version 2 of the License, or (at your option)
00012 // any later version approved by The Eigenbase Project.
00013 //
00014 // This program is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU General Public License
00020 // along with this program; if not, write to the Free Software
00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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     // no data; base IntrusiveDListNode is used to order LRUVictims in an
00039     // intrusive doubly-linked list.
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 &params)
00123     {
00124         pageLRU = NULL;
00125         pageMRU = NULL;
00126     }
00127 
00134     void setAllocatedPageCount(uint nCachePages)
00135     {
00136     }
00137 
00145     void registerPage(PageT &page)
00146     {
00147         // TODO:  use a DList container to avoid this edge case
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         // first access for a newly mapped page will not get a corresponding
00232         // call to notifyPageAccess, so do it now
00233         notifyPageAccess(page, pin);
00234     }
00235 
00244     void notifyPageUnmap(PageT &page, bool discard)
00245     {
00246         // move the unmapped page to the MRU position so that it will not be
00247         // treated as a candidate for flush
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 // End LRUVictimPolicy.h

Generated on Mon Jun 22 04:00:13 2009 for Fennel by  doxygen 1.5.1