📄 allocpage.java
字号:
return extent.canAddFreePage(lastAllocatedPage); } public long getNextAllocPageOffset() { if (SanityManager.DEBUG) { SanityManager.ASSERT( !isLast(), "next alloc page not present for last alloc page"); SanityManager.ASSERT(isLatched()); } return nextAllocPageOffset; } public void chainNewAllocPage(BaseContainerHandle allocHandle, long newAllocPageNum, long newAllocPageOffset) throws StandardException { if (SanityManager.DEBUG) { SanityManager.ASSERT(isLatched()); if (SanityManager.DEBUG_ON(FileContainer.SPACE_TRACE)) SanityManager.DEBUG(FileContainer.SPACE_TRACE, "chaining new alloc page " + newAllocPageNum + " to " + getPageNumber()); } owner.getAllocationActionSet(). actionChainAllocPage(allocHandle.getTransaction(), this, newAllocPageNum, newAllocPageOffset); } public long getNextAllocPageNumber() { if (SanityManager.DEBUG) { SanityManager.ASSERT(isLatched()); SanityManager.ASSERT( !isLast(), "next alloc page not present for last alloc page"); } return nextAllocPageNumber; } public boolean isLast() { if (SanityManager.DEBUG) SanityManager.ASSERT(isLatched()); return nextAllocPageNumber == ContainerHandle.INVALID_PAGE_NUMBER; } /* * get the last pagenumber currently managed by this alloc page */ public long getLastPagenum() { if (SanityManager.DEBUG) SanityManager.ASSERT(isLatched()); return extent.getLastPagenum(); } /* * get the largest page number this alloc page can manage. * This is the different from the last pagenumber currently managed by this * alloc page unless the alloc page is full and all the pages have been * allocated */ public long getMaxPagenum() { return extent.getExtentEnd(); } /* * get the last preallocated pagenumber managed by this alloc page */ protected long getLastPreallocPagenum() { if (SanityManager.DEBUG) SanityManager.ASSERT(isLatched()); return extent.getLastPreallocPagenum(); } protected int getPageStatus(long pageNumber) { if (SanityManager.DEBUG) SanityManager.ASSERT(isLatched()); return extent.getPageStatus(pageNumber); } /** Do the actual page allocation/deallocation/ree underneath a log operation. Change the page status to new status @exception StandardException If the page cannot be allocated */ protected void setPageStatus(LogInstant instant, long pageNumber, int newStatus) throws StandardException { if (SanityManager.DEBUG) { SanityManager.ASSERT(isLatched(), "page is not latched"); SanityManager.ASSERT(extent != null, "extent is null"); } logAction(instant); switch(newStatus) { case AllocExtent.ALLOCATED_PAGE: extent.allocPage(pageNumber); break; case AllocExtent.DEALLOCATED_PAGE: extent.deallocPage(pageNumber); break; case AllocExtent.FREE_PAGE: extent.deallocPage(pageNumber); break; } } /** Chain the next page number and offset underneath a log record @exception StandardException Standard Cloudscape error policy */ protected void chainNextAllocPage(LogInstant instant, long newAllocPageNum, long newAllocPageOffset) throws StandardException { if (SanityManager.DEBUG) SanityManager.ASSERT(isLatched(), "page is not latched"); logAction(instant); nextAllocPageNumber = newAllocPageNum; nextAllocPageOffset = newAllocPageOffset; } /** * Compress free pages. * <p> * Compress the free pages at the end of the range maintained by * this allocation page. All pages being compressed should be FREE. * Only pages in the last allocation page can be compressed. * <p> * * @param instant log address for this operation. * @param new_highest_page The new highest page on this allocation * page. The number is the offset of the page * in the array of pages maintained by this * allocation page, for instance a value of 0 * indicates all page except the first one are * to be truncated. If all pages are * truncated then the offset is set to -1. * @param num_pages_truncated The number of allocated pages in this * allocation page prior to the truncate. * Note that all pages from NewHighestPage+1 * through newHighestPage+num_pages_truncated * should be FREE. * * @exception StandardException Standard exception policy. **/ protected void compressSpace( LogInstant instant, int new_highest_page, int num_pages_truncated) throws StandardException { if (SanityManager.DEBUG) { SanityManager.ASSERT(isLatched(), "page is not latched"); SanityManager.ASSERT(isLast(), "compress on non last alloc page."); SanityManager.ASSERT(new_highest_page >= 0, "negative new high page."); } logAction(instant); extent.compressPages(new_highest_page, num_pages_truncated); } /** * Handle undo of compress space operation. **/ protected void undoCompressSpace( LogInstant instant, int new_highest_page, int num_pages_truncated) throws StandardException { logAction(instant); extent.undoCompressPages(new_highest_page, num_pages_truncated); } public String toString() { if (SanityManager.DEBUG) { String str = "*** Alloc page ***\n" + "nextAllocPageNumber = " + nextAllocPageNumber + "\nnextAllocPageOffset = " + nextAllocPageOffset + "\nreserved1 = " + reserved1 + "\nreserved2 = " + reserved2 + "\nreserved3 = " + reserved3 + "\nreserved4 = " + reserved4 + "\nborrowedSpace = " + borrowedSpace + "\nextent = " + extent.toDebugString() + "\n" + super.toString(); return str; } else { return null; } } /** Return a copy of the allocExtent to be cached by the container. the container must take care to maintain its coherency by invalidating the cache before any update. */ protected AllocExtent getAllocExtent() { return extent; // return new AllocExtent(extent); } /** Preallocate user page if needed. @param myContainer the container object @param preAllocThreshold start preallocating after this threshold @param preAllocSize preallocate this number of pages */ protected void preAllocatePage(FileContainer myContainer, int preAllocThreshold, int preAllocSize) { if (SanityManager.DEBUG) SanityManager.ASSERT(isLatched(), "page is not latched"); long lastPreallocatedPagenum = extent.getLastPreallocPagenum(); if (lastPreallocatedPagenum < preAllocThreshold) return; // don't pre-allocate more than we the extent can handle - this is // because if I preallocate the next alloc page as a stored page, // that's going to be problem when we try to get it as an alloc page // later. We don't handle changing from a store page type to an alloc // page type on disk very well. if (extent.getExtentEnd() < (lastPreallocatedPagenum+preAllocSize)) preAllocSize = (int)(extent.getExtentEnd() - lastPreallocatedPagenum); if (preAllocSize <= 0) return; // pre-allocate - only a container knows how to write pages // preAllocSize may exceed what this allocation page can really // handle, but no harm done. The next allocation page will benefit // from the work we have done... int n = myContainer.preAllocate(lastPreallocatedPagenum, preAllocSize); if (n > 0) // successfully preallocated some pages { // this is purely a performance issue during runtime. During // recovery, any page that is actually initialized will have its // own initPage log record. Update extent's preAllocpageNumber // unlogged. // // We could have logged a redo-only log record, but we are counting // on myContainer.preAllocate to do the right thing if we recovered // and have out of date preallocate information. A reason why // logging this is undesirable is that the alloc page may think the // preallocation happened, but the container may actually choose to // lie about it - if it thinks there is no advantage in actually // doing the I/O now. So best to leave it alone. extent.setLastPreallocPagenum(lastPreallocatedPagenum + n); // don't dirty the page - the new preAlloc page number is only set // in memory. A page should only get 'dirtied' by a log operation, // we are cheating here. Same with updating the extentStatus bit // without logging. } } /** * compress out empty pages at end of container. * <p> * Call the extent to update the data structure make the bit map look * like contiguous free pages at the end of the extent no longer exist. * Similar to preallocate do the operation unlogged, need to force the * change to the extent before actually removing the space from the * file. * <p> * The sequence is: * 1) update extent data structure * 2) force extent changes to disk * 3) truncate pages * * If the system crashes between 1 and 2 then no changes are on disk. * If the system crashes between 2 and 3 then there are extra pages in * the file that extent does not know about, this is the same case * as preallocation which the code already handes. It will handle * any set of pages from 0 to all of the intended pages being * truncated. The next allocate looks at actual size of file as * does the right thing. * * <p) * MT - expect Container level X lock * * @exception StandardException Standard exception policy. **/ protected boolean compress( RawTransaction ntt, FileContainer myContainer) throws StandardException { boolean all_pages_compressed = false; if (SanityManager.DEBUG) { SanityManager.ASSERT(isLatched(), "page is not latched"); } int last_valid_page = extent.compress(owner, ntt, this); if (last_valid_page >= 0) { // a non-negative return means that pages can be returned to // the operating system. myContainer.truncatePages(extent.getPagenum(last_valid_page)); if (last_valid_page == this.getPageNumber()) { // all pages of the extent have been returned to OS. all_pages_compressed = true; } } return(all_pages_compressed); } /********************************************************************* * Extent Testing * * Use these strings to simulate error conditions for * testing purposes. * *********************************************************************/ public static final String TEST_MULTIPLE_ALLOC_PAGE = SanityManager.DEBUG ? "TEST_MULTI_ALLOC_PAGE" : null;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -