Fennel: /home/pub/open/dev/fennel/segment/RandomAllocationSegmentBaseImpl.h Source File (original) (raw)

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_RandomAllocationSegmentBaseImpl_Included 00025 #define Fennel_RandomAllocationSegmentBaseImpl_Included 00026 00027 #include "fennel/segment/RandomAllocationSegmentBase.h" 00028 #include "fennel/segment/SegPageLock.h" 00029 00030 FENNEL_BEGIN_NAMESPACE 00031 00032 00033 00034 00038 static const PageOwnerId UNALLOCATED_PAGE_OWNER_ID = PageOwnerId(0); 00039 00044 struct FENNEL_SEGMENT_EXPORT SegmentAllocationNode 00045 : public StoredNode 00046 { 00047 static const MagicNumber MAGIC_NUMBER = 0xa3db80b98208bfd4LL; 00048 00052 struct ExtentEntry 00053 { 00054
00055
00056
00057
00058 uint32_t nUnallocatedPages; 00059 }; 00060 00067 BlockNum nPagesPerExtent; 00068 00077 PageId nextSegAllocPageId; 00078 00082 uint nExtents; 00083 00084 ExtentEntry &getExtentEntry(uint i) 00085 { 00086 assert(i < nExtents); 00087 return reinterpret_cast<ExtentEntry *>(this+1)[i]; 00088 } 00089 00090 ExtentEntry const &getExtentEntry(uint i) const 00091 { 00092 assert(i < nExtents); 00093 return reinterpret_cast<ExtentEntry const *>(this+1)[i]; 00094 } 00095 }; 00096 00097 typedef SegNodeLock SegAllocLock; 00098 00099 inline PageId RandomAllocationSegmentBase::getFirstSegAllocPageId() const 00100 { 00101 return FIRST_LINEAR_PAGE_ID; 00102 } 00103 00104 inline PageId RandomAllocationSegmentBase::getSegAllocPageId( 00105 uint iSegPage) const 00106 { 00107 return getLinearPageId(nPagesPerSegAllociSegPage); 00108 } 00109 00110 inline BlockNum RandomAllocationSegmentBase::makePageNum( 00111 ExtentNum extentNum,BlockNum iPageInExtent) const 00112 { 00113
00114 uint nSegPages = extentNum / nExtentsPerSegAlloc + 1; 00115 return iPageInExtent + extentNum
nPagesPerExtent + nSegPages; 00116 } 00117 00118 inline PageId RandomAllocationSegmentBase::getExtentAllocPageId( 00119 ExtentNum extentNum) const 00120 { 00121 return getLinearPageId(makePageNum(extentNum,0)); 00122 } 00123 00124 template <class ExtentAllocationNodeT, 00125 class ExtentAllocLockT, 00126 class PageEntryT> 00127 PageId RandomAllocationSegmentBase::allocateFromExtentTemplate( 00128 ExtentNum extentNum, 00129 PageOwnerId ownerId, 00130 SharedSegment allocNodeSegment) 00131 { 00132 permAssert(ownerId != UNALLOCATED_PAGE_OWNER_ID); 00133 00134 SegmentAccessor segAccessor(allocNodeSegment, pCache); 00135 ExtentAllocLockT extentAllocLock(segAccessor); 00136 extentAllocLock.lockExclusive(getExtAllocPageIdForWrite(extentNum)); 00137 ExtentAllocationNodeT &node = extentAllocLock.getNodeForWrite(); 00138 return 00139 allocateFromLockedExtentTemplate<ExtentAllocationNodeT, PageEntryT>( 00140 node, 00141 extentNum, 00142 ownerId); 00143 } 00144 00145 template <class ExtentAllocationNodeT, class ExtentAllocLockT, class PageEntryT> 00146 void RandomAllocationSegmentBase::formatPageExtentsTemplate( 00147 SegmentAllocationNode &segAllocNode, 00148 ExtentNum &extentNum) 00149 { 00150 SegmentAccessor selfAccessor(getTracingSegment(), pCache); 00151 ExtentAllocLockT extentAllocLock(selfAccessor); 00152 uint startOffset = extentNum % nExtentsPerSegAlloc; 00153 for (uint i = startOffset; i < segAllocNode.nExtents; ++i, ++extentNum) { 00154
00155 segAllocNode.getExtentEntry(i).nUnallocatedPages = 00156 nPagesPerExtent - 1; 00157 extentAllocLock.lockExclusive(getExtentAllocPageId(extentNum)); 00158 extentAllocLock.setMagicNumber(); 00159 formatExtentTemplate< 00160 ExtentAllocationNodeT, 00161 ExtentAllocLockT, 00162 PageEntryT>( 00163 extentAllocLock.getNodeForWrite()); 00164 } 00165 } 00166 00167 template <class ExtentAllocationNodeT, class ExtentAllocLockT, class PageEntryT> 00168 void RandomAllocationSegmentBase::formatExtentTemplate( 00169 ExtentAllocationNodeT &extentNode) 00170 { 00171
00172 for (uint i = 0; i < nPagesPerExtent; i++) { 00173 PageEntryT &pageEntry = extentNode.getPageEntry(i); 00174 markPageEntryUnused(pageEntry); 00175 } 00176 00177
00178
00179 extentNode.getPageEntry(0).ownerId = ANON_PAGE_OWNER_ID; 00180 } 00181 00182 template <class ExtentAllocationNodeT, class ExtentAllocLockT, class PageEntryT> 00183 PageId RandomAllocationSegmentBase::allocateFromNewExtentTemplate( 00184 ExtentNum extentNum, 00185 PageOwnerId ownerId, 00186 SharedSegment allocNodeSegment) 00187 { 00188 SegmentAccessor segAccessor(allocNodeSegment, pCache); 00189 ExtentAllocLockT extentAllocLock(segAccessor); 00190 extentAllocLock.lockExclusive(getExtAllocPageIdForWrite(extentNum)); 00191 extentAllocLock.setMagicNumber(); 00192 ExtentAllocationNodeT &extentNode = extentAllocLock.getNodeForWrite(); 00193 formatExtentTemplate<ExtentAllocationNodeT, ExtentAllocLockT, PageEntryT>( 00194 extentNode); 00195 return 00196 allocateFromLockedExtentTemplate<ExtentAllocationNodeT, PageEntryT>( 00197 extentNode, 00198 extentNum, 00199 ownerId); 00200 } 00201 00202 template <class ExtentAllocationNodeT, class PageEntryT> 00203 PageId RandomAllocationSegmentBase::allocateFromLockedExtentTemplate( 00204 ExtentAllocationNodeT &node, ExtentNum extentNum, PageOwnerId ownerId) 00205 { 00206
00207 for (uint i = 0; i < nPagesPerExtent; i++) { 00208 PageEntryT &pageEntry = node.getPageEntry(i); 00209 if (pageEntry.ownerId == UNALLOCATED_PAGE_OWNER_ID) { 00210 if (i == 0) { 00211
00212
00213 permAssert(false); 00214 } 00215 pageEntry.ownerId = ownerId; 00216 PageId pageId = getLinearPageId(makePageNum(extentNum,i)); 00217 return pageId; 00218 } 00219 } 00220 00221 permAssert(false); 00222 } 00223 00224 template <class ExtentAllocationNodeT, class ExtentAllocLockT, class PageEntryT> 00225 void RandomAllocationSegmentBase::freePageEntryTemplate( 00226 ExtentNum extentNum, 00227 BlockNum iPageInExtent) 00228 { 00229 SegmentAccessor segAccessor(getTracingSegment(), pCache); 00230 ExtentAllocLockT extentAllocLock(segAccessor); 00231 00232 extentAllocLock.lockExclusive(getExtentAllocPageId(extentNum)); 00233 ExtentAllocationNodeT &extentNode = extentAllocLock.getNodeForWrite(); 00234 PageEntryT &pageEntry = extentNode.getPageEntry(iPageInExtent); 00235 permAssert(pageEntry.ownerId != UNALLOCATED_PAGE_OWNER_ID); 00236 markPageEntryUnused(pageEntry); 00237 } 00238 00239 template <class ExtentAllocationNodeT, class ExtentAllocLockT> 00240 void RandomAllocationSegmentBase::setPageSuccessorTemplate( 00241 PageId pageId, 00242 PageId successorId, 00243 SharedSegment allocNodeSegment) 00244 { 00245 assert(isPageIdAllocated(pageId)); 00246 assert((successorId == NULL_PAGE_ID) || isPageIdAllocated(successorId)); 00247 00248 uint iSegAlloc; 00249 ExtentNum extentNum; 00250 BlockNum iPageInExtent; 00251 splitPageId(pageId, iSegAlloc, extentNum, iPageInExtent); 00252 permAssert(iPageInExtent); 00253 00254 SegmentAccessor segAccessor(allocNodeSegment, pCache); 00255 ExtentAllocLockT extentAllocLock(segAccessor); 00256 extentAllocLock.lockExclusive(getExtAllocPageIdForWrite(extentNum)); 00257 ExtentAllocationNodeT &node = extentAllocLock.getNodeForWrite(); 00258 node.getPageEntry(iPageInExtent).successorId = successorId; 00259 } 00260 00261 template 00262 PageOwnerId RandomAllocationSegmentBase::getPageOwnerIdTemplate( 00263 PageId pageId, 00264 bool thisSegment) 00265 { 00266 PageEntryT pageEntry; 00267 00268 getPageEntryCopy(pageId, pageEntry, false, thisSegment); 00269 return pageEntry.ownerId; 00270 } 00271 00272 template <class ExtentAllocationNodeT, class ExtentAllocLockT, class PageEntryT> 00273 void RandomAllocationSegmentBase::getPageEntryCopyTemplate( 00274 PageId pageId, 00275 PageEntryT &pageEntryCopy, 00276 bool isAllocated, 00277 bool thisSegment) 00278 { 00279 if (isAllocated) { 00280 assert(testPageId(pageId, true, thisSegment)); 00281 } 00282 00283 ExtentNum extentNum; 00284 BlockNum iPageInExtent; 00285 uint iSegAlloc; 00286 splitPageId(pageId, iSegAlloc, extentNum, iPageInExtent); 00287 assert(iPageInExtent); 00288 00289 SharedSegment allocNodeSegment; 00290 PageId extentPageId; 00291 if (thisSegment) { 00292 allocNodeSegment = getTracingSegment(); 00293 extentPageId = getExtentAllocPageId(extentNum); 00294 } else { 00295 extentPageId = getExtAllocPageIdForRead(extentNum, allocNodeSegment); 00296 } 00297 00298 SegmentAccessor segAccessor(allocNodeSegment, pCache); 00299 ExtentAllocLockT extentAllocLock(segAccessor); 00300 extentAllocLock.lockShared(extentPageId); 00301 ExtentAllocationNodeT const &extentNode = 00302 extentAllocLock.getNodeForRead(); 00303 00304 PageEntryT const &pageEntry = 00305 extentNode.getPageEntry(iPageInExtent); 00306 00307 pageEntryCopy = pageEntry; 00308 } 00309 00310 FENNEL_END_NAMESPACE 00311 00312 #endif 00313 00314