📄 allocextent.java
字号:
else { // reuseing a page, make sure it is in range and is not already in use checkInRange(pagenum); int bitnum = (int)(pagenum-extentStart); // either the pagenum is now free (do) or deallocated (undo) if (!freePages.isSet(bitnum)) { SanityManager.THROWASSERT( "trying to re-allocate a page ( " + pagenum + " ) that is already allocated "); } } } // don't know if we are redoing (from free -> valid) // or undoing (from dealloc -> valid), reset them both int bitnum = (int)(pagenum-extentStart); if (bitnum >= freePages.getLength()) // expand the bit map { int numbits = (1+(bitnum/8))*8; if (numbits > (int)(extentEnd - extentStart + 1)) numbits = (int)(extentEnd - extentStart + 1); freePages.grow(numbits); unFilledPages.grow(numbits); } // the first page to be allocated has pagenum == extentStart. int numPageAlloced = (int)(pagenum-extentStart+1); if (numPageAlloced > extentLength) { extentLength = numPageAlloced; } freePages.clear(bitnum); // do not set the unfilled bit on a newly allocated page because // we only keep track of unfilled HEAD page, not unfilled overflow // page. } /** Deallocate logical page pagenum - this is called underneath the log record. pagenum must be a page managed by this extent and it must be valid @exception StandardException Standard Cloudscape error policy */ protected void deallocPage(long pagenum) throws StandardException { int bitnum = (int)(pagenum-extentStart); // the pagenum must now be either valid (do) or free (undo) if (SanityManager.DEBUG) { if (freePages.isSet(bitnum)) SanityManager.THROWASSERT( "trying to deallocate a deallocated page " + pagenum); } freePages.set(bitnum); unFilledPages.clear(bitnum); // deallocated page is never unfilled setExtentFreePageStatus(true); } /** * Compress free pages at end of this extent. * <p> * Search backward from end of extent and prepare data structures * to return pages at end of extent to the OS. Returns the lowest * page that can be returned to the OS. * <p> * * @return Return bit of page where all pages that follow can * be returned to the OS. **/ protected int compress( BaseContainerHandle owner, RawTransaction ntt, AllocPage alloc_page) throws StandardException { int compress_bitnum = -1; int num_pages_compressed = 0; for (int i = (extentLength - 1); i >= 0; i--) { if (freePages.isSet(i)) { compress_bitnum = i; num_pages_compressed++; } else { break; } } // new_highest_page is the last page to remain in the file after // the truncate, the above loop set compress_bitnum to lowest // free page in the set of contiguous free pages at end of extent. int new_highest_page = compress_bitnum - 1; if (num_pages_compressed > 0) { if (SanityManager.DEBUG) { for (int i = new_highest_page + 1; i < extentLength; i++) { if (!freePages.isSet(i)) { SanityManager.THROWASSERT( "compressPages with nonfree pg to truncate," + "new_highest_page = " + new_highest_page + "num_pages_truncated = " + num_pages_compressed + ";extentLength = " + extentLength + ";extentStart = " + extentStart + ";freePages.isSet(" + i + ") = " + freePages.isSet(i) + "\nextent:\n" + toDebugString()); } } SanityManager.ASSERT( (new_highest_page + num_pages_compressed + 1) == extentLength, "truncate page count did not match: " + ";new_highest_page = " + new_highest_page + ";num_pages_truncated = " + num_pages_compressed + ";extentLength = " + extentLength); // the following assert could be made invalid by a new type of // access method, but currently page 1 of btree and heap contain // control rows, so will never become free and thus should never // be compressed. if (extentStart == 1) { SanityManager.ASSERT(new_highest_page >= 0); if (num_pages_compressed >= extentLength) { SanityManager.THROWASSERT( "new_highest_page = " + new_highest_page + "num_pages_compressed = " + num_pages_compressed + "; extentLength = " + extentLength + "extent:\n" + toDebugString()); } } } /* SanityManager.DEBUG_PRINT("AllocExtent", "calling actionCompressSpaceOperation:" + ";new_highest_page = " + new_highest_page + ";num_pages_compressed = " + num_pages_compressed + ";extentLength = " + extentLength + ";extent: \n" + toDebugString()); */ owner.getAllocationActionSet().actionCompressSpaceOperation( ntt, alloc_page, new_highest_page, num_pages_compressed); return(compress_bitnum); } else { return(-1); } } protected void compressPages( int new_highest_page, int num_pages_truncated) { if (SanityManager.DEBUG) { if (new_highest_page >= 0) { for (int i = new_highest_page + 1; i < extentLength; i++) { if (!freePages.isSet(i)) { SanityManager.THROWASSERT( "compressPages with non free page to truncate," + "new_highest_page = " + new_highest_page + "num_pages_truncated = " + num_pages_truncated + ";extentLength = " + extentLength + ";extentStart = " + extentStart + ";freePages.isSet(" + i + ") = " + freePages.isSet(i) + "\nextent:\n" + toDebugString()); } } } SanityManager.ASSERT( (new_highest_page + num_pages_truncated + 1) == extentLength, "truncate page count did not match: " + ";new_highest_page = " + new_highest_page + ";num_pages_truncated = " + num_pages_truncated + ";extentLength = " + extentLength); // the following assert could be made invalid by a new type of // access method, but currently page 1 of btree and heap contain // control rows, so will never become free and thus should never // be compressed. if (extentStart == 1) { SanityManager.ASSERT(new_highest_page >= 0); SanityManager.ASSERT(num_pages_truncated < extentLength); } } if (new_highest_page >= 0) { freePages.shrink(new_highest_page + 1); unFilledPages.shrink(new_highest_page + 1); // This routine assumes the caller // will be doing the truncate, and just updates the data structures. preAllocLength = extentLength = (new_highest_page + 1); } return; } /** * Undo the compress space operation. * <p> * Undo of this operation doesn't really "undo" the operation, it just * makes sure the data structures are ok after the undo. We are * guaranteed at the point of the transaction doing the * Undo of the compress space operation fixes up the bit maps to * only point at pages within the new_highest_page range. * <p> * Prior to logging the compress space operation all pages greater * than * There are only 2 possibilities at this point: * 1) the truncate of pages greater than new_highest_page happened before * the abort took place. W * 2) * * @return The identifier to be used to open the conglomerate later. * * @param param1 param1 does this. * @param param2 param2 does this. * * @exception StandardException Standard exception policy. **/ protected void undoCompressPages( int new_highest_page, int num_pages_truncated) { if (new_highest_page >= 0) { freePages.shrink(new_highest_page + 1); unFilledPages.shrink(new_highest_page + 1); preAllocLength = extentLength = (new_highest_page + 1); } return; } protected long getExtentEnd() { return extentEnd; } /* * read operation that is called above the log */ /** Get a page number that is free */ protected long getFreePageNumber(long pnum) { // if we can reuse page, do so, otherwise add a brand new page if (mayHaveFreePage()) { // The last allocated page may be from a previous alloc extent, but // if that extent is full and we are the first extent that can // accomodate a new page, we may be picked. In that case, pnum may // be before the start of this extent. int i = (pnum < extentStart) ? freePages.anySetBit() : freePages.anySetBit((int)(pnum-extentStart)); if (i != -1) { if (SanityManager.DEBUG) { if (i >= extentLength) SanityManager.THROWASSERT("returned bit = " + i + " extent length = " + extentLength); } return i+extentStart; } // the hint is wrong, no free page in the extent // do this unlogged, it is just a hint, don't care if it is lost if (pnum < extentStart) setExtentFreePageStatus(false); } // maximally, we can have up to extendEnd page if (SanityManager.DEBUG) SanityManager.ASSERT(extentStart+extentLength <= extentEnd); // need to add a brand new page, current end of extent is at page // extentStart+extentLength-1; return extentStart+extentLength; } /** Get the physical offset of pagenum. If deallocOK is true, then even if pagenum is deallocated, it is OK. If deallocOK is false, then an exception is thrown if pagenum is deallocated. An exception is always thrown if pagenum is a free page @exception StandardException Standard Cloudscape error policy */ protected long getPageOffset(long pagenum, int pagesize, boolean deallocOK) throws StandardException { return pagenum * pagesize; } /** Return the status of this extent */ protected boolean isRetired() { return ((extentStatus & RETIRED) != 0); } private boolean mayHaveFreePage() { return ((extentStatus & HAS_FREE) != 0); } private void setExtentFreePageStatus(boolean hasFree) { if (hasFree) extentStatus |= HAS_FREE; else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -