#include <SegPageEntryIter.h>
Inheritance diagram for SegPageEntryIter< EntryT >:
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 * () |
| |
void | operator++ () |
Moves to the next prefetched PageId. | |
void | makeSingular () |
Aborts any iteration in progress and release all resources. | |
bool | isSingular () const |
| |
PageId | operator * () const |
| |
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. |
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.
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 }
SegPageEntryIter< EntryT >::SegPageEntryIter | ( | uint | nEntriesInit | ) | [explicit] |
Constructor: iterator starts out singular.
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 }
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 }
void SegPageEntryIter< EntryT >::prefetchPages | ( | PageId | prevPageId, | |
bool | oneIter | |||
) | [private] |
Determines a set of pages that should be pre-fetched and pre-fetches them.
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 }
void SegPageEntryIter< EntryT >::resize | ( | uint | nEntries | ) |
Resizes the object to allow for storage of N pre-fetch entries.
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 }
void SegPageEntryIter< EntryT >::setPrefetchSource | ( | SegPageEntryIterSource< EntryT > & | prefetchSource | ) |
Sets the pre-fetch source for this iterator.
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 }
void SegPageEntryIter< EntryT >::mapRange | ( | SegmentAccessor const & | segmentAccessor, | |
PageId | beginPageId, | |||
PageId | endPageId = NULL_PAGE_ID | |||
) |
Begins a new iteration.
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 }
std::pair<PageId, EntryT>& SegPageEntryIter< EntryT >::operator * | ( | ) | [inline] |
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 }
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 }
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 }
bool SegPageEntryIter< EntryT >::isSingular | ( | ) | const [inline] |
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.
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] |
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 }
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().
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().