📄 allocpage.java
字号:
if (pageData.length < BORROWED_SPACE_OFFSET + BORROWED_SPACE_LEN + n) { throw dataFactory.markCorrupt( StandardException.newException( SQLState.DATA_CORRUPT_PAGE, newIdentity)); } // blot out borrowed space before checksum is verified if (borrowedSpace > 0) { clearSection(BORROWED_SPACE_OFFSET + BORROWED_SPACE_LEN, borrowedSpace); } super.initFromData(myContainer, newIdentity); try { // now init alloc page header fields readAllocPageHeader(); // now init the allocation extent - read it from offset int offset = BORROWED_SPACE_OFFSET + BORROWED_SPACE_LEN + borrowedSpace; extent = readExtent(offset); } catch (IOException ioe) { throw dataFactory.markCorrupt( StandardException.newException( SQLState.DATA_CORRUPT_PAGE, ioe, newIdentity)); } catch (ClassNotFoundException cnfe) { throw dataFactory.markCorrupt( StandardException.newException( SQLState.DATA_CORRUPT_PAGE, cnfe, newIdentity)); } } /** Write the page out @exception StandardException If the page cannot be written */ protected void writePage(PageKey identity) throws StandardException { try { updateAllocPageHeader(); // write out the next alloc page chain // blot out borrowed space before checksum is calculated - even // though the page is first read in with borrowed space blotted // out, whenever this page got cleaned the container will overlay // the container info in the borrowed space. int n = (int)pageData[BORROWED_SPACE_OFFSET]; if (SanityManager.DEBUG) { if (n != borrowedSpace) SanityManager.THROWASSERT( "different borrowed space " + n + ", " + borrowedSpace); } if (n > 0) { clearSection(BORROWED_SPACE_OFFSET + BORROWED_SPACE_LEN, n); } int offset = BORROWED_SPACE_OFFSET + BORROWED_SPACE_LEN + n; writeExtent(offset); } catch (IOException ioe) { // i/o methods on the byte array have thrown an IOException throw dataFactory.markCorrupt( StandardException.newException( SQLState.DATA_CORRUPT_PAGE, ioe, identity)); } // let store page write out the rest and do the checksum super.writePage(identity); } private void readAllocPageHeader() throws IOException { ArrayInputStream lrdi = rawDataIn; lrdi.setPosition(ALLOC_PAGE_HEADER_OFFSET); nextAllocPageNumber = lrdi.readLong(); nextAllocPageOffset = lrdi.readLong(); reserved1 = lrdi.readLong(); reserved2 = lrdi.readLong(); reserved3 = lrdi.readLong(); reserved4 = lrdi.readLong(); } private void updateAllocPageHeader() throws IOException { // rawDataOut and logicalDataOut are defined by StoredPage rawDataOut.setPosition(ALLOC_PAGE_HEADER_OFFSET); logicalDataOut.writeLong(nextAllocPageNumber); logicalDataOut.writeLong(nextAllocPageOffset); logicalDataOut.writeLong(0); // reserved1 logicalDataOut.writeLong(0); // reserved2 logicalDataOut.writeLong(0); // reserved3 logicalDataOut.writeLong(0); // reserved4 } private AllocExtent readExtent(int offset) throws IOException, ClassNotFoundException { ArrayInputStream lrdi = rawDataIn; rawDataIn.setPosition(offset); AllocExtent newExtent = new AllocExtent(); newExtent.readExternal(lrdi); // in 1.3 or later, make sure the upgrade from before 1.3 is legal. if (SanityManager.DEBUG) { int max_range = newExtent.MAX_RANGE(getMaxFreeSpace()); long extent_start = newExtent.getFirstPagenum(); long extent_end = newExtent.getExtentEnd(); // extent_start + max_range - 1 is the absolute last page this // extent can hope to manage. See if it did the calculation // correctly after upgrade. if ((extent_start+max_range-1) < extent_end) { SanityManager.THROWASSERT( "extent range exceed what extent's space can handle "); } } return newExtent; } private void writeExtent(int offset) throws IOException { // rawDataOut and logicalDataOut are defined by StoredPage rawDataOut.setPosition(offset); extent.writeExternal(logicalDataOut); } /* * borrowed space management */ /** Write the container information into the container information area. @param containerInfo the container information @param epage the allocation page data which may not be fully formed, but is guarenteed to be big enough to cover the area inhibited by the container info @param create if create, write out the length of the container info also. Else check to make sure epage's original container info is of the same length @exception StandardException Cloudscape standard error policy */ public static void WriteContainerInfo(byte[] containerInfo, byte[] epage, boolean create) throws StandardException { int N = (containerInfo == null) ? 0 : containerInfo.length; if (SanityManager.DEBUG) { if (create) SanityManager.ASSERT( containerInfo != null, "containerInfo is null"); SanityManager.ASSERT(epage != null, "page array is null"); if (!((containerInfo == null) || ((containerInfo.length + BORROWED_SPACE_OFFSET + BORROWED_SPACE_LEN) < epage.length))) { SanityManager.THROWASSERT( "containerInfo too big for page array: " + containerInfo.length); } if (BORROWED_SPACE_OFFSET + BORROWED_SPACE_LEN + N >= MAX_BORROWED_SPACE) SanityManager.THROWASSERT( "exceed max borrowable space: " + N); } if ((N + BORROWED_SPACE_LEN + BORROWED_SPACE_OFFSET) > epage.length) { if (SanityManager.DEBUG) SanityManager.THROWASSERT( "exceed max borrowable space on page: " + N); } if (create) { epage[BORROWED_SPACE_OFFSET] = (byte)N; } else { int oldN = (int)epage[BORROWED_SPACE_OFFSET]; if (oldN != N) { throw StandardException.newException( SQLState.DATA_CHANGING_CONTAINER_INFO, new Long(oldN), new Long(N)); } } if (N != 0) System.arraycopy(containerInfo, 0, epage, BORROWED_SPACE_OFFSET + BORROWED_SPACE_LEN, N); } /** Extract the container information from epage. @param containerInfo where to put the extracted information @param epage the allocation page which has the container information. Epage may not be fully formed, but is guarenteed to be big enough to cover the area inhibited by the container info */ public static void ReadContainerInfo(byte[] containerInfo, byte[] epage) { int N = (int)epage[BORROWED_SPACE_OFFSET]; if (SanityManager.DEBUG) { if (N != containerInfo.length) SanityManager.THROWASSERT("N not what is expected : " + N); if (BORROWED_SPACE_OFFSET + BORROWED_SPACE_LEN + N >= MAX_BORROWED_SPACE) { SanityManager.THROWASSERT("exceed max borrowable space: " + N); } } if (N != 0) System.arraycopy(epage, BORROWED_SPACE_OFFSET+BORROWED_SPACE_LEN, containerInfo, 0, N); } /* * specific methods to AllocPage */ /** Return the next free page number after given page number */ public long nextFreePageNumber(long pnum) { return extent.getFreePageNumber(pnum); } /** Add a page which is managed by this alloc page. Return the page number of the newly added page. <BR> MT - thread aware (latched) @param mycontainer (future) allows the alloc page to call back to the container to grow the container by creating and syncing multiple pages at once @param ntt the nested top action that is the allocation transaction. NTT will comit before the user transaction @param userHandle the container handle that is opened by the user transaction. Use the userHandle to latch the new page so that it may remain latched after NTT is committed so the user transaction can guarentee to have an empty page @exception StandardException If the page cannot be added */ public void addPage(FileContainer mycontainer, long newPageNumber, RawTransaction ntt, BaseContainerHandle userHandle) throws StandardException { // RESOLVED: // // to prevent allocating a free page before the freeing transaction has // commit, need to grab the DEALLOCATE_PROTECTION_HANDLE // the lock probably should be gotten in FileContainer // and not here // page allocation is logged under the nested top action owner.getAllocationActionSet(). actionAllocatePage( ntt, this, newPageNumber, AllocExtent.ALLOCATED_PAGE, AllocExtent.FREE_PAGE); } /* Deallocate page */ public void deallocatePage(BaseContainerHandle userHandle, long pageNumber) throws StandardException { if (SanityManager.DEBUG) { SanityManager.ASSERT(isLatched()); } // RESOLVED: // // to prevent this page from being freed before this transaction commits, // need to grab the DEALLOCATE_PROTECTION_HANDLE lock on the // deallocated page // the lock probably should be gotten in FileContainer // and not here owner.getAllocationActionSet(). actionAllocatePage(userHandle.getTransaction(), this, pageNumber, AllocExtent.DEALLOCATED_PAGE, AllocExtent.ALLOCATED_PAGE); } /* * update unfilled page information * We will be using inputExtent's unfilledPage bitmap as the new bitmap, so * caller of this routine need to not touch the bitmap after this call (in * other words, call this ONLY in allocationCache invalidate and throw away * the reference to the bitImpl) */ protected void updateUnfilledPageInfo(AllocExtent inputExtent) { if (SanityManager.DEBUG) { SanityManager.ASSERT(isLatched()); } // update the unfilled page bit map unlogged - it is just a hint, not // worth logging it - don't dirty the page either, since we didn't log // it. It will be dirtied soon enough by addPage or deallocPage, // that is the only reasons why we are invalidataing the // allocation cache and updating the unfilled page info. // If we dirty the page, the BI will be copied to the side log extent.updateUnfilledPageInfo(inputExtent); } public boolean canAddFreePage(long lastAllocatedPage) { if (SanityManager.DEBUG) SanityManager.ASSERT(isLatched()); if (extent.isRetired()) return false; // if we want to try allocating not from the beginning of the bit map // and this alloc page is before that point and this is not the last // alloc page, then skip over this alloc page if (lastAllocatedPage != ContainerHandle.INVALID_PAGE_NUMBER && extent.getLastPagenum() <= lastAllocatedPage && !isLast()) return false; // Else we either want to start examining from this alloc page, or this // is the last page, see if we can add a page.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -