SegPageEntryIter< EntryT > Class Template Reference

SegPageEntryIter extends SegPageIter. More...

#include <SegPageEntryIter.h>

Inheritance diagram for SegPageEntryIter< EntryT >:

SegPageIter List of all members.

Public Member Functions

 SegPageEntryIter ()
 Constructor: iterator starts out singular.
 SegPageEntryIter (uint nEntriesInit)
 Constructor: iterator starts out singular.
void resize (uint nEntries)
 Resizes the object to allow for storage of N pre-fetch entries.
void setPrefetchSource (SegPageEntryIterSource< EntryT > &prefetchSource)
 Sets the pre-fetch source for this iterator.
void mapRange (SegmentAccessor const &segmentAccessor, PageId beginPageId, PageId endPageId=NULL_PAGE_ID)
 Begins a new iteration.
std::pair< PageId, EntryT > & operator * ()
 
Returns:
the current (PageId, EntryT) in the iteration

void operator++ ()
 Moves to the next prefetched PageId.
void makeSingular ()
 Aborts any iteration in progress and release all resources.
bool isSingular () const
 
Returns:
true iff no iteration is in progress

PageId operator * () const
 
Returns:
the current PageId in the iteration

void forcePrefetchReject ()
 Forces the next pre-fetch request to be rejected.

Protected Member Functions

void initPrefetchQueue ()
 Reads the pre-fetch parameters, sizes the pre-fetch queue, and initializes various state variables related to the queue.
void prefetchPage (PageId pageId)
 Pre-fetches a specified page.

Protected Attributes

SegmentAccessor segmentAccessor
 Accessor for the Segment containing the pages to be visited.
PageId endPageId
 PageId at which to stop iteration.
std::vector< PageId > prefetchQueue
 Fixed-size circular queue of prefetched PageIds, indexed by iFetch.
uint iFetch
 Position in prefetchQueue.
bool atEnd
 Whether end of iteration has been reached by prefetch (but not necessarily by fetch).
uint queueSize
 Current size of the pre-fetch queue.
int nFreePageSlots
 Number of slots available in the prefetchQueue.

Private Member Functions

void init ()
 Initializes object.
void prefetchPages (PageId prevPageId, bool oneIter)
 Determines a set of pages that should be pre-fetched and pre-fetches them.

Private Attributes

CircularBuffer< std::pair<
PageId, EntryT > > 
entryQueue
 Circular vector with the context-specific information associated with each pre-fetched page.
SegPageEntryIterSource< EntryT > * pPrefetchSource
 Pointer to the source that provides the callback method that determines which pages to pre-fetch.

Detailed Description

template<class EntryT>
class SegPageEntryIter< EntryT >

SegPageEntryIter extends SegPageIter.

Rather than pre-fetching successor pages, it takes a source parameter that provides a callback method that's used to determine which pages should be pre-fetched. The class is a template class, which allows context-specific information to be associated with each pre-fetched page.

Definition at line 42 of file SegPageEntryIter.h.


Constructor & Destructor Documentation

template<class EntryT>
FENNEL_BEGIN_NAMESPACE SegPageEntryIter< EntryT >::SegPageEntryIter (  )  [explicit]

Constructor: iterator starts out singular.

Initializes the object with no storage yet for pre-fetch entries.

Definition at line 33 of file SegPageEntryIterImpl.h.

References SegPageEntryIter< EntryT >::init().

00034 {
00035     init();
00036 }

template<class EntryT>
SegPageEntryIter< EntryT >::SegPageEntryIter ( uint  nEntriesInit  )  [explicit]

Constructor: iterator starts out singular.

Parameters:
nEntriesInit number of pre-fetch entries

Definition at line 39 of file SegPageEntryIterImpl.h.

References SegPageEntryIter< EntryT >::init().

00040     : entryQueue(nEntriesInit)
00041 {
00042     init();
00043 }


Member Function Documentation

template<class EntryT>
void SegPageEntryIter< EntryT >::init (  )  [private]

Initializes object.

Definition at line 46 of file SegPageEntryIterImpl.h.

References SegPageEntryIter< EntryT >::pPrefetchSource.

Referenced by SegPageEntryIter< EntryT >::SegPageEntryIter().

00047 {
00048     pPrefetchSource = NULL;
00049 }

template<class EntryT>
void SegPageEntryIter< EntryT >::prefetchPages ( PageId  prevPageId,
bool  oneIter 
) [private]

Determines a set of pages that should be pre-fetched and pre-fetches them.

Parameters:
prevPageId the id of the last page pre-fetched; only needed in the case where the entry queue is currently empty
oneIter if true, pre-fetch no more than one page

Definition at line 87 of file SegPageEntryIterImpl.h.

References SegPageIter::atEnd, CircularBuffer< T >::empty(), SegPageIter::endPageId, SegPageEntryIter< EntryT >::entryQueue, CircularBuffer< T >::getLastPos(), SegPageIter::nFreePageSlots, SegPageEntryIter< EntryT >::pPrefetchSource, SegPageIter::prefetchPage(), CircularBuffer< T >::push_back(), CircularBuffer< T >::reference_back(), and CircularBuffer< T >::spaceAvailable().

Referenced by SegPageEntryIter< EntryT >::mapRange(), and SegPageEntryIter< EntryT >::operator++().

00088 {
00089     if (!entryQueue.empty()) {
00090         prevPageId = entryQueue.reference_back().first;
00091     }
00092 
00093     // Continue retrieving pageIds while we have available space in
00094     // the prefetch queue
00095     while (nFreePageSlots != 0 || oneIter) {
00096         // But make sure we have space in the entryQueue
00097         if (!entryQueue.spaceAvailable()) {
00098             break;
00099         }
00100 
00101         std::pair<PageId, EntryT> &entryPair =
00102             entryQueue[entryQueue.getLastPos() + 1];
00103         bool found;
00104         entryPair.first =
00105             pPrefetchSource->getNextPageForPrefetch(entryPair.second, found);
00106         if (!found) {
00107             break;
00108         }
00109         entryQueue.push_back(entryPair);
00110 
00111         if (entryPair.first == endPageId) {
00112             atEnd = 1;
00113         }
00114 
00115         if (atEnd || entryPair.first != prevPageId) {
00116             prefetchPage(entryPair.first);
00117         }
00118 
00119         if (atEnd || oneIter) {
00120             break;
00121         }
00122 
00123         prevPageId = entryPair.first;
00124     }
00125 }

template<class EntryT>
void SegPageEntryIter< EntryT >::resize ( uint  nEntries  ) 

Resizes the object to allow for storage of N pre-fetch entries.

Parameters:
nEntries the number of storage slots

Definition at line 52 of file SegPageEntryIterImpl.h.

References SegPageEntryIter< EntryT >::entryQueue, and CircularBuffer< T >::resize().

Referenced by BTreePrefetchSearchExecStream::open().

00053 {
00054     entryQueue.resize(nEntries);
00055 }

template<class EntryT>
void SegPageEntryIter< EntryT >::setPrefetchSource ( SegPageEntryIterSource< EntryT > &  prefetchSource  ) 

Sets the pre-fetch source for this iterator.

Parameters:
prefetchSource the source

Definition at line 58 of file SegPageEntryIterImpl.h.

References SegPageEntryIter< EntryT >::entryQueue, SegPageEntryIterSource< EntryT >::initPrefetchEntry(), SegPageEntryIter< EntryT >::pPrefetchSource, and CircularBuffer< T >::size().

Referenced by LcsClusterReader::LcsClusterReader(), BTreePrefetchSearchExecStream::open(), and SegPageEntryIterTest::testIter().

00060 {
00061     assert(entryQueue.size() > 0);
00062     pPrefetchSource = &prefetchSource;
00063     for (uint i = 0; i < entryQueue.size(); i++) {
00064         pPrefetchSource->initPrefetchEntry(entryQueue[i].second);
00065     }
00066 }

template<class EntryT>
void SegPageEntryIter< EntryT >::mapRange ( SegmentAccessor const &  segmentAccessor,
PageId  beginPageId,
PageId  endPageId = NULL_PAGE_ID 
)

Begins a new iteration.

Parameters:
segmentAccessor accessor for the segment containing the pages to visit
beginPageId the ID of the first page to visit; always set to NULL_PAGE_ID for this class, as the initial page is provided by the source parameter
endPageId the ID at which to end iteration; by default, this is NULL_PAGE_ID (representing the sentinel end of a chain) but the iteration (and prefetch) can be stopped earlier with some other known PageId; note that endPageId itself will not be prefetched

Reimplemented from SegPageIter.

Definition at line 69 of file SegPageEntryIterImpl.h.

References CircularBuffer< T >::clear(), SegPageIter::endPageId, SegPageEntryIter< EntryT >::entryQueue, SegPageIter::initPrefetchQueue(), NULL_PAGE_ID, SegmentAccessor::pCacheAccessor, SegPageEntryIter< EntryT >::prefetchPages(), SegmentAccessor::pSegment, and SegPageIter::segmentAccessor.

Referenced by BTreePrefetchSearchExecStream::innerSearchLoop(), LcsClusterReader::position(), and SegPageEntryIterTest::testIter().

00073 {
00074     assert(segmentAccessorInit.pSegment);
00075     assert(segmentAccessorInit.pCacheAccessor);
00076     assert(beginPageIdInit == NULL_PAGE_ID);
00077     segmentAccessor = segmentAccessorInit;
00078     endPageId = endPageIdInit;
00079     initPrefetchQueue();
00080     entryQueue.clear();
00081 
00082     // Pre-populate the queues
00083     prefetchPages(NULL_PAGE_ID, false);
00084 }

template<class EntryT>
std::pair<PageId, EntryT>& SegPageEntryIter< EntryT >::operator * (  )  [inline]

Returns:
the current (PageId, EntryT) in the iteration

Definition at line 125 of file SegPageEntryIter.h.

00126     {
00127         assert(!isSingular());
00128         std::pair<PageId, EntryT> &entryPair = entryQueue.reference_front();
00129         assert(entryPair.first == prefetchQueue[iFetch]);
00130         return entryPair;
00131     }

template<class EntryT>
void SegPageEntryIter< EntryT >::operator++ (  ) 

Moves to the next prefetched PageId.

An assertion violation results if called when positioned on endPageId.

Reimplemented from SegPageIter.

Definition at line 128 of file SegPageEntryIterImpl.h.

References SegPageIter::atEnd, CircularBuffer< T >::empty(), SegPageIter::endPageId, SegPageEntryIter< EntryT >::entryQueue, SegPageIter::iFetch, SegPageEntryIter< EntryT >::isSingular(), SegPageIter::nFreePageSlots, NULL_PAGE_ID, CircularBuffer< T >::pop_front(), SegPageEntryIter< EntryT >::prefetchPages(), SegPageIter::queueSize, and CircularBuffer< T >::reference_front().

00129 {
00130     assert(!isSingular());
00131     std::pair<PageId, EntryT> &entryPair = entryQueue.reference_front();
00132     PageId currPageId = entryPair.first;
00133     assert(currPageId != endPageId);
00134 
00135     entryQueue.pop_front();
00136 
00137     // If the queue is empty, we have to try and pre-fetch some more entries.
00138     // Worst case, we'll hit the ending page.  The queueSize == 1 case needs
00139     // special handling because:
00140     // 1) There are currently no free slots in the prefetch queue.  The one
00141     //    slot is occupied by the last page pre-fetched.
00142     // 2) We can only replace that slot with a new page if it's different
00143     //    from that last pre-fetched page.
00144     // Therefore, we can't assume that the current page will always be
00145     // replaced by a new one.
00146     if (entryQueue.empty()) {
00147         prefetchPages(currPageId, (queueSize == 1));
00148     }
00149 
00150     PageId nextPageId = entryQueue.reference_front().first;
00151     // Bump up the prefetch queue only if we've moved on to a new page
00152     if (nextPageId != currPageId) {
00153         iFetch = (iFetch + 1) % queueSize;
00154         nFreePageSlots++;
00155     }
00156 
00157     // Re-populate the queues if there's available space
00158     if (!atEnd) {
00159         prefetchPages(NULL_PAGE_ID, false);
00160     }
00161 }

template<class EntryT>
void SegPageEntryIter< EntryT >::makeSingular (  )  [inline]

Aborts any iteration in progress and release all resources.

Reimplemented from SegPageIter.

Definition at line 142 of file SegPageEntryIter.h.

Referenced by SegPageEntryIterTest::testIter().

00143     {
00144         SegPageIter::makeSingular();
00145         pPrefetchSource = NULL;
00146     }

template<class EntryT>
bool SegPageEntryIter< EntryT >::isSingular (  )  const [inline]

Returns:
true iff no iteration is in progress

Reimplemented from SegPageIter.

Definition at line 151 of file SegPageEntryIter.h.

Referenced by SegPageEntryIter< LcsRid >::operator *(), and SegPageEntryIter< EntryT >::operator++().

00152     {
00153         return (pPrefetchSource == NULL || SegPageIter::isSingular());
00154     }

void SegPageIter::initPrefetchQueue (  )  [protected, inherited]

Reads the pre-fetch parameters, sizes the pre-fetch queue, and initializes various state variables related to the queue.

Definition at line 66 of file SegPageIter.cpp.

References SegPageIter::atEnd, SegPageIter::currPageSlot, SegPageIter::forceReject, SegPageIter::iFetch, SegPageIter::nFreePageSlots, SegPageIter::noPrefetch, SegmentAccessor::pCacheAccessor, SegPageIter::prefetchPagesMax, SegPageIter::prefetchQueue, SegPageIter::prefetchThrottleRate, SegPageIter::queueSize, SegPageIter::segmentAccessor, and SegPageIter::throttleCount.

Referenced by SegPageIter::mapRange(), and SegPageEntryIter< EntryT >::mapRange().

00067 {
00068     segmentAccessor.pCacheAccessor->getPrefetchParams(
00069         prefetchPagesMax,
00070         prefetchThrottleRate);
00071     queueSize = prefetchPagesMax;
00072     noPrefetch = (queueSize == 0);
00073     // Reset the queue size so we have space to store at least one page
00074     if (queueSize < 1) {
00075         queueSize = 1;
00076     }
00077     prefetchQueue.resize(queueSize);
00078 
00079     nFreePageSlots = queueSize;
00080     currPageSlot = 0;
00081     iFetch = 0;
00082     atEnd = 0;
00083     throttleCount = 0;
00084     forceReject = false;
00085 }

void SegPageIter::prefetchPage ( PageId  pageId  )  [protected, inherited]

Pre-fetches a specified page.

Parameters:
pageId the id of the page to be pre-fetched

Definition at line 110 of file SegPageIter.cpp.

References SegPageIter::atEnd, SegPageIter::currPageSlot, SegPageIter::endPageId, SegPageIter::forceReject, SegPageIter::iFetch, SegPageIter::nFreePageSlots, SegPageIter::noPrefetch, NULL_BLOCK_ID, SegmentAccessor::pCacheAccessor, SegPageIter::prefetchPagesMax, SegPageIter::prefetchQueue, SegPageIter::prefetchThrottleRate, SegmentAccessor::pSegment, SegPageIter::queueSize, SegPageIter::segmentAccessor, and SegPageIter::throttleCount.

Referenced by SegPageIter::mapRange(), SegPageIter::operator++(), and SegPageEntryIter< EntryT >::prefetchPages().

00111 {
00112     // Store the page we're about to pre-fetch in the first empty slot
00113     // in the queue
00114     prefetchQueue[currPageSlot++] = pageId;
00115     currPageSlot %= queueSize;
00116     --nFreePageSlots;
00117 
00118     if (pageId == endPageId) {
00119         atEnd = 1;
00120         return;
00121     }
00122 
00123     // If pre-fetches are turned off, don't bothering issuing the pre-fetch
00124     // request.
00125     BlockId blockId = NULL_BLOCK_ID;
00126     if (!forceReject && !noPrefetch) {
00127         blockId = segmentAccessor.pSegment->translatePageId(pageId);
00128     }
00129     if (!forceReject &&
00130         (noPrefetch ||
00131             segmentAccessor.pCacheAccessor->prefetchPage(
00132                 blockId,
00133                 segmentAccessor.pSegment->getMappedPageListener(blockId))))
00134     {
00135         // If the pre-fetch rate was throttled down, then wait until we
00136         // reach the desired number of successful pre-fetches before
00137         // throttling the rate back up, one page at a time.
00138         if (throttleCount > 0) {
00139             assert(prefetchPagesMax != 0);
00140             if (--throttleCount == 0) {
00141                 // At a minimum, reenable pre-fetches
00142                 noPrefetch = false;
00143 
00144                 // If we haven't throttled back to the max pre-fetch
00145                 // rate, then reset the counter so we can continue
00146                 // counting successful pre-fetches to allow the rate
00147                 // to continue throttling up.  In the case where the
00148                 // pre-fetch rate is a single page, no further throttling
00149                 // is possible.
00150                 if (prefetchPagesMax > 1) {
00151                     nFreePageSlots++;
00152                     if (nFreePageSlots < prefetchPagesMax) {
00153                         throttleCount = prefetchThrottleRate;
00154                     }
00155                 }
00156             }
00157         }
00158     } else {
00159         // If pre-fetches aren't already disabled, then set the number of
00160         // pre-fetches to the number of outstanding pre-fetches by
00161         // disallowing any new pre-fetches until the existing ones are used.
00162         // If we're down to doing a single pre-fetch, then turn off
00163         // pre-fetches.
00164         if (prefetchPagesMax > 0) {
00165             if (nFreePageSlots > 0) {
00166                 nFreePageSlots = 0;
00167             }
00168             if (iFetch == currPageSlot) {
00169                 noPrefetch = true;
00170             }
00171             throttleCount = prefetchThrottleRate;
00172         }
00173         forceReject = false;
00174     }
00175 }

PageId SegPageIter::operator * (  )  const [inline, inherited]

Returns:
the current PageId in the iteration

Definition at line 156 of file SegPageIter.h.

00157     {
00158         assert(!isSingular());
00159         return prefetchQueue[iFetch];
00160     }

void SegPageIter::forcePrefetchReject (  )  [inherited]

Forces the next pre-fetch request to be rejected.

Used for testing purposes.

Definition at line 177 of file SegPageIter.cpp.

References SegPageIter::forceReject.

Referenced by SegPageIterTest::testIter(), and SegPageEntryIterTest::testIter().

00178 {
00179     forceReject = true;
00180 }


Member Data Documentation

template<class EntryT>
CircularBuffer<std::pair<PageId, EntryT> > SegPageEntryIter< EntryT >::entryQueue [private]

Circular vector with the context-specific information associated with each pre-fetched page.

The number of entries in this vector is not necessarily the same as the number of pages that have been pre-fetched, as the same page can be associated with multiple entries.

Definition at line 50 of file SegPageEntryIter.h.

Referenced by SegPageEntryIter< EntryT >::mapRange(), SegPageEntryIter< LcsRid >::operator *(), SegPageEntryIter< EntryT >::operator++(), SegPageEntryIter< EntryT >::prefetchPages(), SegPageEntryIter< EntryT >::resize(), and SegPageEntryIter< EntryT >::setPrefetchSource().

template<class EntryT>
SegPageEntryIterSource<EntryT>* SegPageEntryIter< EntryT >::pPrefetchSource [private]

Pointer to the source that provides the callback method that determines which pages to pre-fetch.

Definition at line 56 of file SegPageEntryIter.h.

Referenced by SegPageEntryIter< EntryT >::init(), SegPageEntryIter< LcsRid >::isSingular(), SegPageEntryIter< LcsRid >::makeSingular(), SegPageEntryIter< EntryT >::prefetchPages(), and SegPageEntryIter< EntryT >::setPrefetchSource().

SegmentAccessor SegPageIter::segmentAccessor [protected, inherited]

Accessor for the Segment containing the pages to be visited.

Definition at line 82 of file SegPageIter.h.

Referenced by SegPageIter::initPrefetchQueue(), SegPageIter::mapRange(), SegPageEntryIter< EntryT >::mapRange(), SegPageIter::operator++(), and SegPageIter::prefetchPage().

PageId SegPageIter::endPageId [protected, inherited]

PageId at which to stop iteration.

Definition at line 87 of file SegPageIter.h.

Referenced by SegPageIter::mapRange(), SegPageEntryIter< EntryT >::mapRange(), SegPageIter::operator++(), SegPageEntryIter< EntryT >::operator++(), SegPageIter::prefetchPage(), and SegPageEntryIter< EntryT >::prefetchPages().

std::vector<PageId> SegPageIter::prefetchQueue [protected, inherited]

Fixed-size circular queue of prefetched PageIds, indexed by iFetch.

Definition at line 92 of file SegPageIter.h.

Referenced by SegPageIter::initPrefetchQueue(), SegPageIter::mapRange(), SegPageEntryIter< LcsRid >::operator *(), SegPageIter::operator++(), and SegPageIter::prefetchPage().

uint SegPageIter::iFetch [protected, inherited]

Position in prefetchQueue.

Definition at line 97 of file SegPageIter.h.

Referenced by SegPageIter::initPrefetchQueue(), SegPageEntryIter< LcsRid >::operator *(), SegPageIter::operator++(), SegPageEntryIter< EntryT >::operator++(), and SegPageIter::prefetchPage().

bool SegPageIter::atEnd [protected, inherited]

Whether end of iteration has been reached by prefetch (but not necessarily by fetch).

Definition at line 103 of file SegPageIter.h.

Referenced by SegPageIter::initPrefetchQueue(), SegPageIter::mapRange(), SegPageIter::operator++(), SegPageEntryIter< EntryT >::operator++(), SegPageIter::prefetchPage(), and SegPageEntryIter< EntryT >::prefetchPages().

uint SegPageIter::queueSize [protected, inherited]

Current size of the pre-fetch queue.

Definition at line 108 of file SegPageIter.h.

Referenced by SegPageIter::initPrefetchQueue(), SegPageIter::mapRange(), SegPageIter::operator++(), SegPageEntryIter< EntryT >::operator++(), and SegPageIter::prefetchPage().

int SegPageIter::nFreePageSlots [protected, inherited]

Number of slots available in the prefetchQueue.

May temporarily become negative in the case where pre-fetches are turned off.

Definition at line 114 of file SegPageIter.h.

Referenced by SegPageIter::initPrefetchQueue(), SegPageIter::operator++(), SegPageEntryIter< EntryT >::operator++(), SegPageIter::prefetchPage(), and SegPageEntryIter< EntryT >::prefetchPages().


The documentation for this class was generated from the following files:
Generated on Mon Jun 22 04:00:46 2009 for Fennel by  doxygen 1.5.1