CacheImpl.h

Go to the documentation of this file.
00001 /*
00002 // $Id: //open/dev/fennel/cache/CacheImpl.h#20 $
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_CacheImpl_Included
00025 #define Fennel_CacheImpl_Included
00026 
00027 #include "fennel/cache/Cache.h"
00028 #include "fennel/cache/CacheStats.h"
00029 #include "fennel/common/IntrusiveList.h"
00030 #include "fennel/common/AtomicCounter.h"
00031 #include "fennel/synch/SXMutex.h"
00032 #include "fennel/synch/TimerThread.h"
00033 #include "fennel/cache/CacheAllocator.h"
00034 #include "fennel/device/DeviceAccessScheduler.h"
00035 #include "fennel/cache/CachePage.h"
00036 #include "fennel/cache/PageBucket.h"
00037 #include "fennel/cache/MappedPageListener.h"
00038 #include "fennel/cache/PagePredicate.h"
00039 #include "fennel/common/FileStatsTarget.h"
00040 
00041 #include <vector>
00042 #include <algorithm>
00043 #include <boost/scoped_ptr.hpp>
00044 
00045 FENNEL_BEGIN_NAMESPACE
00046 
00114 template <class PageT,class VictimPolicyT>
00115 class CacheImpl : public Cache, private TimerThreadClient
00116 {
00117     // convenience typedef
00118     typedef PageBucket<PageT> PageBucketT;
00119     typedef typename PageBucketT::PageListIter PageBucketIter;
00120     typedef typename PageBucketT::PageListMutator PageBucketMutator;
00121 
00128     std::vector<SharedRandomAccessDevice> deviceTable;
00129 
00133     PageBucketT unmappedBucket;
00134 
00138     PageBucketT unallocatedBucket;
00139 
00144     std::vector<PageBucketT *> pageTable;
00145 
00150     uint dirtyHighWaterPercent;
00151 
00156     uint dirtyLowWaterPercent;
00157 
00162     uint dirtyHighWaterMark;
00163 
00168     uint dirtyLowWaterMark;
00169 
00175     bool inFlushMode;
00176 
00180     AtomicCounter nCacheHits;
00181 
00185     AtomicCounter nCacheRequests;
00186 
00190     AtomicCounter nVictimizations;
00191 
00197     AtomicCounter nDirtyPages;
00198 
00202     AtomicCounter nPageReads;
00203 
00207     AtomicCounter nPageWrites;
00208 
00212     AtomicCounter nRejectedCachePrefetches;
00213 
00217     AtomicCounter nIoRetries;
00218 
00222     AtomicCounter nSuccessfulCachePrefetches;
00223 
00227     AtomicCounter nLazyWrites;
00228 
00232     AtomicCounter nLazyWriteCalls;
00233 
00237     AtomicCounter nVictimizationWrites;
00238 
00242     AtomicCounter nCheckpointWrites;
00243 
00248     CacheStats statsSinceInit;
00249 
00253     StrictMutex freePageMutex;
00254 
00258     LocalCondition freePageCondition;
00259 
00265     std::vector<PageT *> pages;
00266 
00270     DeviceAccessScheduler *pDeviceAccessScheduler;
00271 
00275     CacheAllocator &bufferAllocator;
00276 
00280     boost::scoped_ptr<CacheAllocator> pBufferAllocator;
00281 
00287     VictimPolicyT victimPolicy;
00288 
00292     TimerThread timerThread;
00293 
00297     uint idleFlushInterval;
00298 
00302     uint prefetchPagesMax;
00303 
00309     uint prefetchThrottleRate;
00310 
00314     enum FlushPhase {
00315         phaseSkip, phaseInitiate, phaseWait
00316     };
00317 
00318     // A class used as VictimPolicyT is required to define nested types
00319     // PageIterator and SharedGuard via which CacheImpl can safely iterate
00320     // over victim candidates.  Within CacheImpl code, these are referred to
00321     // via private typedefs for brevity.
00322     typedef typename VictimPolicyT::PageIterator VictimPageIterator;
00323     typedef typename VictimPolicyT::DirtyPageIterator DirtyVictimPageIterator;
00324     typedef typename VictimPolicyT::SharedGuard VictimSharedGuard;
00325     typedef typename VictimPolicyT::ExclusiveGuard VictimExclusiveGuard;
00326 
00327 // ----------------------------------------------------------------------
00328 // CacheImpl internal helper methods
00329 // ----------------------------------------------------------------------
00330 
00344     PageT *lookupPage(PageBucketT &bucket,BlockId blockId,bool pin);
00345 
00354     PageT *findFreePage();
00355 
00360     void flushSomePages();
00361 
00370     bool transferPageAsync(PageT &page);
00371 
00379     bool readPageAsync(PageT &page);
00380 
00388     bool writePageAsync(PageT &page);
00389 
00398     FileSize getPageOffset(BlockId const &blockId);
00399 
00407     PageBucketT &getHashBucket(BlockId const &blockId);
00408 
00416     void assertCorrectBucket(PageBucketT &bucket,BlockId const &blockId);
00417 
00431     void unmapPage(PageT &page,StrictMutexGuard &guard,bool discard);
00432 
00445     void unmapAndFreeDiscardedPage(
00446         PageT &page,
00447         StrictMutexGuard &guard);
00448 
00475     PageT &mapPage(
00476         PageBucketT &bucket,PageT &newPage,BlockId blockId,
00477         MappedPageListener *pMappedPageListener,
00478         bool bPendingRead = true,bool bIncRef = true);
00479 
00486     void freePage(PageT &page);
00487 
00497     bool canVictimizePage(PageT &page);
00498 
00504     void incrementCounter(AtomicCounter &x);
00505 
00511     void decrementCounter(AtomicCounter &x);
00512 
00519     void incrementStatsCounter(AtomicCounter &x);
00520 
00527     void decrementStatsCounter(AtomicCounter &x);
00528 
00532     void initializeStats();
00533 
00538     void allocatePages(CacheParams const &params);
00539 
00543     void successfulPrefetch();
00544 
00548     void rejectedPrefetch();
00549 
00553     void ioRetry();
00554 
00561     void calcDirtyThreshholds(uint nCachePages);
00562 
00563 // ----------------------------------------------------------------------
00564 // Implementation of private Cache interface (q.v.)
00565 // ----------------------------------------------------------------------
00566 
00567     void markPageDirty(CachePage &page);
00568     void notifyTransferCompletion(CachePage &,bool);
00569 
00570 // ----------------------------------------------------------------------
00571 // Implementation of TimerThreadClient interface (q.v.)
00572 // ----------------------------------------------------------------------
00573 
00574     virtual uint getTimerIntervalMillis();
00575     virtual void onTimerInterval();
00576 
00577 protected:
00578     void closeImpl();
00579 
00580 public:
00581 // ----------------------------------------------------------------------
00582 // Implementation of public Cache interface (q.v.)
00583 // ----------------------------------------------------------------------
00584     CacheImpl(
00585         CacheParams const &,
00586         CacheAllocator * = NULL);
00587     virtual void setAllocatedPageCount(uint nMemPages);
00588     virtual uint getAllocatedPageCount();
00589     virtual uint getMaxAllocatedPageCount();
00590     virtual PageT *lockPage(
00591         BlockId blockId,LockMode lockMode,bool readIfUnmapped,
00592         MappedPageListener *pMappedPageListener,TxnId txnId);
00593     virtual PageT &lockScratchPage(BlockNum blockNum);
00594     virtual void discardPage(BlockId blockId);
00595     virtual uint checkpointPages(
00596         PagePredicate &pagePredicate,CheckpointType checkpointType);
00597     virtual void collectStats(CacheStats &stats);
00598     virtual void registerDevice(
00599         DeviceId deviceId,SharedRandomAccessDevice pDevice);
00600     virtual void unregisterDevice(DeviceId deviceId);
00601     virtual SharedRandomAccessDevice &getDevice(DeviceId deviceId);
00602     virtual bool prefetchPage(
00603         BlockId blockId,MappedPageListener *pMappedPageListener);
00604     virtual void prefetchBatch(
00605         BlockId blockId,uint nPages,MappedPageListener *pMappedPageListener);
00606     virtual void flushPage(CachePage &page,bool async);
00607     virtual void unlockPage(CachePage &page,LockMode lockMode,TxnId txnId);
00608     virtual void nicePage(CachePage &page);
00609     virtual bool isPageMapped(BlockId blockId);
00610     virtual CacheAllocator &getAllocator() const;
00611     virtual void getPrefetchParams(
00612         uint &prefetchPagesMax,
00613         uint &prefetchThrottleRate);
00614     virtual DeviceAccessScheduler &getDeviceAccessScheduler(
00615         RandomAccessDevice &)
00616     {
00617         return *pDeviceAccessScheduler;
00618     }
00619 
00620 };
00621 
00622 FENNEL_END_NAMESPACE
00623 
00624 #include "fennel/cache/CacheMethodsImpl.h"
00625 
00626 #endif
00627 
00628 // End CacheImpl.h

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