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_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
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
00319
00320
00321
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
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 ¶ms);
00539
00543 void successfulPrefetch();
00544
00548 void rejectedPrefetch();
00549
00553 void ioRetry();
00554
00561 void calcDirtyThreshholds(uint nCachePages);
00562
00563
00564
00565
00566
00567 void markPageDirty(CachePage &page);
00568 void notifyTransferCompletion(CachePage &,bool);
00569
00570
00571
00572
00573
00574 virtual uint getTimerIntervalMillis();
00575 virtual void onTimerInterval();
00576
00577 protected:
00578 void closeImpl();
00579
00580 public:
00581
00582
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