#include <CachePage.h>
Inheritance diagram for CachePage:
Public Types | |
enum | DataStatus { DATA_INVALID, DATA_ERROR, DATA_CLEAN, DATA_DIRTY, DATA_WRITE, DATA_READ } |
Enumeration of possible status of page data. More... | |
Public Member Functions | |
CachePage (Cache &, PBuffer) | |
virtual | ~CachePage () |
Cache & | getCache () |
| |
bool | isDirty () const |
| |
bool | isTransferInProgress () const |
| |
bool | isDataValid () const |
| |
bool | isDataError () const |
| |
BlockId | getBlockId () const |
| |
PConstBuffer | getReadableData () const |
Obtains a const pointer to the page contents. | |
PBuffer | getWritableData () |
Obtains a writable pointer to the page contents, marking the page dirty. | |
bool | isScratchLocked () const |
| |
MappedPageListener * | getMappedPageListener () const |
| |
bool | tryUpgrade (TxnId txnId) |
Attempts to upgrade from LOCKMODE_S (which caller must already have acquired) to LOCKMODE_X. | |
void | upgrade (TxnId txnId) |
Upgrades from LOCKMODE_S (which caller must already have acquired) to LOCKMODE_X. | |
void | swapBuffers (CachePage &other) |
Swaps this page's buffer with another page. | |
Private Member Functions | |
bool | hasBlockId () const |
| |
void | waitForPendingIO (StrictMutexGuard &guard) |
Waits for pending I/O to complete. | |
bool | isExclusiveLockHeld () const |
| |
virtual void | notifyTransferCompletion (bool bSuccess) |
Receives notification when a transfer completes. | |
virtual PBuffer | getBuffer () const |
| |
virtual uint | getBufferSize () const |
| |
Private Attributes | |
Cache & | cache |
| |
StrictMutex | mutex |
Mutex protecting this Page's state variables. | |
SXMutex | lock |
Synchronization object used to implement shared and exclusive locks. | |
PBuffer | pBuffer |
Allocated buffer memory, or NULL if page is currently unallocated. | |
BlockId | blockId |
The BlockId to which this page is currently mapped, or NULL_BLOCK_ID if unmapped. | |
uint | nReferences |
Reference count used to pin page so that it can't be victimized; this is equal to at least the number of locks currently held on this page, but may be higher due to the presence of threads which are still in the process of locking the page or otherwise manipulating it. | |
LocalCondition | ioCompletionCondition |
Condition variable used for notification of pending I/O completion. | |
MappedPageListener * | pMappedPageListener |
Listener to receive notifications of page writes, or NULL if no listener defined. | |
DataStatus | dataStatus |
Status of page data. | |
Friends | |
class | CacheImpl |
Once a CachePage has been mapped to some block of a Device and locked, its data can be read or written with the getReadableData() and getWritableData() member functions.
Definition at line 56 of file CachePage.h.
Enumeration of possible status of page data.
Order matters (valid data states are grouped together, as are I/O states).
Definition at line 64 of file CachePage.h.
00064 { 00068 DATA_INVALID, 00069 00073 DATA_ERROR, 00074 00079 DATA_CLEAN, 00080 00084 DATA_DIRTY, 00085 00089 DATA_WRITE, 00090 00095 DATA_READ 00096 };
Definition at line 33 of file CachePage.cpp.
References blockId, DATA_INVALID, dataStatus, nReferences, NULL_BLOCK_ID, pBuffer, and pMappedPageListener.
00034 : cache(cacheInit) 00035 { 00036 nReferences = 0; 00037 dataStatus = DATA_INVALID; 00038 blockId = NULL_BLOCK_ID; 00039 pBuffer = pBufferInit; 00040 pMappedPageListener = NULL; 00041 }
CachePage::~CachePage | ( | ) | [virtual] |
Definition at line 43 of file CachePage.cpp.
References blockId, DATA_INVALID, dataStatus, nReferences, and NULL_BLOCK_ID.
00044 { 00045 assert(!nReferences); 00046 assert(blockId == NULL_BLOCK_ID); 00047 assert(dataStatus == DATA_INVALID); 00048 }
bool CachePage::hasBlockId | ( | ) | const [inline, private] |
Definition at line 168 of file CachePage.h.
References NULL_BLOCK_ID.
00169 { 00170 return blockId != NULL_BLOCK_ID; 00171 }
void CachePage::waitForPendingIO | ( | StrictMutexGuard & | guard | ) | [inline, private] |
Waits for pending I/O to complete.
Note that this wraps a condition variable, which is subject to spurious wakeups; for this reason, the caller MUST enclose calls to this method in a while loop.
Definition at line 178 of file CachePage.h.
Referenced by CacheImpl< PageT, VictimPolicyT >::flushPage().
00179 { 00180 ioCompletionCondition.wait(guard); 00181 }
bool CachePage::isExclusiveLockHeld | ( | ) | const [inline, private] |
Definition at line 186 of file CachePage.h.
References LOCKMODE_X.
Referenced by CacheImpl< PageT, VictimPolicyT >::flushPage(), and swapBuffers().
00187 { 00188 // REVIEW: should make sure lock is held by this thread? 00189 return isScratchLocked() || lock.isLocked(LOCKMODE_X); 00190 }
void CachePage::notifyTransferCompletion | ( | bool | bSuccess | ) | [private, virtual] |
Receives notification when a transfer completes.
bSuccess | true if the full buffer size was successfully transferred for this binding |
Implements RandomAccessRequestBinding.
Definition at line 50 of file CachePage.cpp.
References getCache(), and Cache::notifyTransferCompletion().
00051 { 00052 getCache().notifyTransferCompletion(*this,bSuccess); 00053 }
PBuffer CachePage::getBuffer | ( | ) | const [private, virtual] |
Implements RandomAccessRequestBinding.
Definition at line 55 of file CachePage.cpp.
References pBuffer.
00056 { 00057 return pBuffer; 00058 }
uint CachePage::getBufferSize | ( | ) | const [private, virtual] |
Implements RandomAccessRequestBinding.
Definition at line 60 of file CachePage.cpp.
References cache, and Cache::getPageSize().
00061 { 00062 return cache.getPageSize(); 00063 }
Cache& CachePage::getCache | ( | ) | [inline] |
Definition at line 206 of file CachePage.h.
Referenced by DoubleBufferExecStream::execute(), notifyTransferCompletion(), FlatFileExecStreamImpl::open(), ScratchBufferExecStream::open(), and DoubleBufferExecStream::open().
00207 { 00208 return cache; 00209 }
bool CachePage::isDirty | ( | ) | const [inline] |
Definition at line 215 of file CachePage.h.
Referenced by WALSegment::notifyPageUnmap(), and FuzzyCheckpointSet::operator()().
00216 { 00217 return dataStatus == DATA_DIRTY; 00218 }
bool CachePage::isTransferInProgress | ( | ) | const [inline] |
Definition at line 223 of file CachePage.h.
00224 { 00225 return (dataStatus >= DATA_WRITE); 00226 }
bool CachePage::isDataValid | ( | ) | const [inline] |
Definition at line 231 of file CachePage.h.
Referenced by CrcSegInputStream::lockBufferParanoid(), and CacheImpl< PageT, VictimPolicyT >::markPageDirty().
00232 { 00233 return (dataStatus >= DATA_CLEAN) && (dataStatus <= DATA_WRITE); 00234 }
bool CachePage::isDataError | ( | ) | const [inline] |
Definition at line 239 of file CachePage.h.
00240 { 00241 return (dataStatus == DATA_ERROR); 00242 }
BlockId CachePage::getBlockId | ( | ) | const [inline] |
Definition at line 247 of file CachePage.h.
Referenced by VersionedSegment::canFlushPage(), isScratchLocked(), TracingSegment::notifyAfterPageCheckpointFlush(), WALSegment::notifyAfterPageFlush(), TracingSegment::notifyAfterPageFlush(), TracingSegment::notifyAfterPageRead(), TracingSegment::notifyBeforePageFlush(), WALSegment::notifyPageDirty(), VersionedSegment::notifyPageDirty(), TracingSegment::notifyPageDirty(), TracingSegment::notifyPageMap(), TracingSegment::notifyPageUnmap(), CacheImpl< PageT, VictimPolicyT >::notifyTransferCompletion(), and DeviceIdPagePredicate::operator()().
00248 { 00249 return blockId; 00250 }
PConstBuffer CachePage::getReadableData | ( | ) | const [inline] |
Obtains a const pointer to the page contents.
The page must be locked in shared or exclusive mode first. The number of valid bytes returned depends on the page size.
Definition at line 260 of file CachePage.h.
References LOCKMODE_S.
Referenced by VersionedRandomAllocationSegment::backupAllocationNodes(), SegNodeLock< Node >::checkMagicNumber(), SpillOutputStream::getInputStream(), SegNodeLock< Node >::getNodeForRead(), Segment::getReadableFooter(), SegNodeLock< Node >::isMagicNumberValid(), VersionedRandomAllocationSegment::locateDataPages(), VersionedSegment::notifyPageDirty(), SpillOutputStream::spill(), and PagingTestBase::verifyPage().
00261 { 00262 assert(isDataValid()); 00263 assert(lock.isLocked(LOCKMODE_S) || isExclusiveLockHeld()); 00264 return pBuffer; 00265 }
PBuffer CachePage::getWritableData | ( | ) | [inline] |
Obtains a writable pointer to the page contents, marking the page dirty.
The page must be locked in exclusive mode first. The number of valid bytes returned depends on the page size.
Definition at line 274 of file CachePage.h.
References Cache::getCache().
Referenced by LcsClusterNodeWriter::allocArrays(), LbmEntryTest::allocateBuf(), ExternalSortRunLoader::allocateBuffer(), BTreePrefetchSearchExecStream::allocateScratchPages(), LhxHashTable::allocBlock(), DoubleBufferExecStream::execute(), PagingTestBase::fillPage(), SegNodeLock< Node >::getNodeForWrite(), Segment::getWritableFooter(), LbmGeneratorExecStream::initBitmapTable(), LcsClusterAppendExecStream::initLoad(), SegPageBackupRestoreDevice::initScratchPages(), VersionedSegment::notifyPageDirty(), LbmUnionExecStream::open(), LbmChopperExecStream::open(), FlatFileExecStreamImpl::open(), ScratchBufferExecStream::open(), DoubleBufferExecStream::open(), VersionedSegment::recover(), SpillOutputStream::SpillOutputStream(), SegPageLock::swapBuffers(), and RandomAllocationSegmentTest::testAllocateAndDeallocate().
00275 { 00276 assert(isExclusiveLockHeld()); 00277 assert(!isDataError()); 00278 assert(!isTransferInProgress()); 00279 // REVIEW: is thread-safety ever an issue here? If so, it's also an 00280 // issue for the previous assertions. 00281 if (!isDirty()) { 00282 getCache().markPageDirty(*this); 00283 } 00284 return pBuffer; 00285 }
bool CachePage::isScratchLocked | ( | ) | const |
Definition at line 72 of file CachePage.cpp.
References getBlockId(), CompoundId::getDeviceId(), and Cache::NULL_DEVICE_ID.
00073 { 00074 return CompoundId::getDeviceId(getBlockId()) == Cache::NULL_DEVICE_ID; 00075 }
MappedPageListener* CachePage::getMappedPageListener | ( | ) | const [inline] |
Definition at line 295 of file CachePage.h.
Referenced by MappedPageListenerPredicate::operator()().
00296 { 00297 assert(hasBlockId()); 00298 return pMappedPageListener; 00299 }
bool CachePage::tryUpgrade | ( | TxnId | txnId | ) | [inline] |
Attempts to upgrade from LOCKMODE_S (which caller must already have acquired) to LOCKMODE_X.
This is a NOWAIT operation; it fails immediately if any other thread already holds a lock on the same page, or when a transfer is already in progress.
Definition at line 309 of file CachePage.h.
References CacheImpl< PageT, VictimPolicyT >::getAllocator(), Cache::getCache(), and Cache::getPageSize().
00310 { 00311 StrictMutexGuard pageGuard(mutex); 00312 if (isTransferInProgress()) { 00313 return false; 00314 } 00315 #ifdef DEBUG 00316 int errorCode; 00317 if (getCache().getAllocator().setProtection( 00318 pBuffer, getCache().getPageSize(), false, &errorCode)) 00319 { 00320 throw SysCallExcn("memory protection failed", errorCode); 00321 } 00322 #endif 00323 return lock.tryUpgrade(txnId); 00324 }
void CachePage::upgrade | ( | TxnId | txnId | ) | [inline] |
Upgrades from LOCKMODE_S (which caller must already have acquired) to LOCKMODE_X.
This is a WAIT operation if a page transfer is in progress. It's assumed that there are no other threads holding a lock on the same page.
Definition at line 332 of file CachePage.h.
References CacheImpl< PageT, VictimPolicyT >::getAllocator(), Cache::getCache(), and Cache::getPageSize().
00333 { 00334 StrictMutexGuard pageGuard(mutex); 00335 while (isTransferInProgress()) { 00336 waitForPendingIO(pageGuard); 00337 } 00338 #ifdef DEBUG 00339 int errorCode; 00340 if (getCache().getAllocator().setProtection( 00341 pBuffer, getCache().getPageSize(), false, &errorCode)) 00342 { 00343 throw SysCallExcn("memory protection failed", errorCode); 00344 } 00345 #endif 00346 bool rc = lock.tryUpgrade(txnId); 00347 assert(rc); 00348 }
void CachePage::swapBuffers | ( | CachePage & | other | ) |
Swaps this page's buffer with another page.
You almost certainly shouldn't be calling this directly (see SegPageLock::swapBuffers).
other | page to swap with |
Definition at line 65 of file CachePage.cpp.
References isExclusiveLockHeld(), and pBuffer.
00066 { 00067 assert(isExclusiveLockHeld()); 00068 assert(other.isExclusiveLockHeld()); 00069 std::swap(pBuffer,other.pBuffer); 00070 }
friend class CacheImpl [friend] |
Definition at line 100 of file CachePage.h.
Cache& CachePage::cache [private] |
StrictMutex CachePage::mutex [private] |
Mutex protecting this Page's state variables.
This is only held internally by CacheImpl for very short durations.
Definition at line 114 of file CachePage.h.
Referenced by CacheImpl< PageT, VictimPolicyT >::flushPage(), CacheImpl< PageT, VictimPolicyT >::markPageDirty(), and CacheImpl< PageT, VictimPolicyT >::notifyTransferCompletion().
SXMutex CachePage::lock [private] |
Synchronization object used to implement shared and exclusive locks.
This is held for long durations (across cache lock/unlock calls).
Definition at line 120 of file CachePage.h.
PBuffer CachePage::pBuffer [private] |
Allocated buffer memory, or NULL if page is currently unallocated.
Definition at line 125 of file CachePage.h.
Referenced by CachePage(), getBuffer(), and swapBuffers().
BlockId CachePage::blockId [private] |
The BlockId to which this page is currently mapped, or NULL_BLOCK_ID if unmapped.
Definition at line 135 of file CachePage.h.
Referenced by CachePage(), and ~CachePage().
uint CachePage::nReferences [private] |
Reference count used to pin page so that it can't be victimized; this is equal to at least the number of locks currently held on this page, but may be higher due to the presence of threads which are still in the process of locking the page or otherwise manipulating it.
Definition at line 143 of file CachePage.h.
Referenced by CachePage(), and ~CachePage().
Condition variable used for notification of pending I/O completion.
This is coupled with mutex.
Definition at line 149 of file CachePage.h.
Referenced by CacheImpl< PageT, VictimPolicyT >::notifyTransferCompletion().
MappedPageListener* CachePage::pMappedPageListener [private] |
Listener to receive notifications of page writes, or NULL if no listener defined.
Definition at line 155 of file CachePage.h.
Referenced by CachePage(), CacheImpl< PageT, VictimPolicyT >::flushPage(), and CacheImpl< PageT, VictimPolicyT >::notifyTransferCompletion().
DataStatus CachePage::dataStatus [private] |
Status of page data.
Definition at line 160 of file CachePage.h.
Referenced by CachePage(), CacheImpl< PageT, VictimPolicyT >::flushPage(), CacheImpl< PageT, VictimPolicyT >::markPageDirty(), CacheImpl< PageT, VictimPolicyT >::notifyTransferCompletion(), and ~CachePage().