📄 allocationcache.java
字号:
/* Derby - Class org.apache.derby.impl.store.raw.data.AllocationCache Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */package org.apache.derby.impl.store.raw.data;import org.apache.derby.iapi.services.sanity.SanityManager;import org.apache.derby.iapi.error.StandardException;import org.apache.derby.iapi.store.raw.ContainerHandle;import org.apache.derby.impl.store.raw.data.BaseContainerHandle;/** An auxiliary object to cache the allocation information for a file container. <B>Only a FileContainer should use this object</B> <P> The allocation cache contains an array of AllocExtents and 3 arrays of longs: <OL><LI>ExtentPageNums[i] is the page number of the i'th extent <LI>lowRange[i] is the smallest page number managed by extent i <LI>hiRange[i] is the largest page number managed by extent i </OL> <P> Note thate extentPageNums and lowRange does not change once the extent has been created, but hiRange will change for the last extent as more pages are allocated. <P> Extents can be individually invalidated or the entire cache (all extends) can be invalidated at once. <P> MT - unsafe Synrhonized access to all methods must be enforced by the caller of AllocationCache*/class AllocationCache{ private int numExtents; private long[] lowRange; // lowRange[i] to hiRange[i] defines the private long[] hiRange; // smallest and largest logical page number // manages by extent i private boolean[] isDirty; // changes to the in memory allocation cache private AllocExtent[] extents; private long[] extentPageNums; private boolean isValid; protected AllocationCache() { numExtents = 0; isValid = false; } /* reset the allocation cache in case when filecontainer object is reused */ protected void reset() { numExtents = 0; isValid = false; if (lowRange != null) { for (int i = 0; i < lowRange.length; i++) { lowRange[i] = ContainerHandle.INVALID_PAGE_NUMBER; hiRange[i] = ContainerHandle.INVALID_PAGE_NUMBER; extentPageNums[i] = ContainerHandle.INVALID_PAGE_NUMBER; extents[i] = null; isDirty[i] = false; } } } /** Get the page number for the allocation page that is managing this page number */ protected long getAllocPageNumber(BaseContainerHandle handle, long pageNumber, long firstAllocPageNumber) throws StandardException { // try to see if we can figure this out without validating the cache for (int i = 0; i < numExtents; i++) { if (lowRange[i] <= pageNumber && pageNumber <= hiRange[i]) return extentPageNums[i]; } if (!isValid) { /* can't find the page. Validate the cache first, then try to find it again */ validate(handle, firstAllocPageNumber); for (int i = 0; i < numExtents; i++) { if (lowRange[i] <= pageNumber && pageNumber <= hiRange[i]) return extentPageNums[i]; } } return ContainerHandle.INVALID_PAGE_NUMBER; } /** Get the last (allocated) page of the container */ protected long getLastPageNumber(BaseContainerHandle handle, long firstAllocPageNumber) throws StandardException { if (!isValid) validate(handle, firstAllocPageNumber); return hiRange[numExtents-1]; } /** Set the page number to be unfilled */ protected void trackUnfilledPage(long pagenumber, boolean unfilled) { // do not validate the alloc cache just for the purpose of updating the // unfilled bit if (!isValid || numExtents <= 0) { return; } // we are calling this without getting the allocCache semaphore - be // careful that extents[i] will go null at any time. for (int i = 0; i < numExtents; i++) { if (lowRange[i] <= pagenumber && pagenumber <= hiRange[i]) { AllocExtent ext = extents[i]; if (ext != null && ext.trackUnfilledPage(pagenumber, unfilled) && extents[i] != null) { isDirty[i] = true; } break; } } } protected long getUnfilledPageNumber(BaseContainerHandle handle, long firstAllocPageNumber, long pagenum) throws StandardException { // get the next unfilled page number if (!isValid) { validate(handle, firstAllocPageNumber); } if (pagenum == ContainerHandle.INVALID_PAGE_NUMBER) { for (int i = 0; i < numExtents; i++) { if (extents[i] != null) return extents[i].getUnfilledPageNumber(pagenum); } } else { for (int i = 0; i < numExtents; i++) { if (pagenum <= hiRange[i]) { if (extents[i] != null) return extents[i].getUnfilledPageNumber(pagenum); } } } return ContainerHandle.INVALID_PAGE_NUMBER; } /** returns estimated number of allocated pages **/ protected long getEstimatedPageCount(BaseContainerHandle handle, long firstAllocPageNumber) throws StandardException { if (!isValid) validate(handle, firstAllocPageNumber); long estPageCount = 0; for (int i = 0; i < numExtents; i++) { if (extents[i] != null) estPageCount += extents[i].getAllocatedPageCount(); } return estPageCount; } protected SpaceInformation getAllPageCounts( BaseContainerHandle handle, long firstAllocPageNumber) throws StandardException { long currAllocPages = 0; long numAllocatedPages = 0; long numFreePages = 0; long numUnfilledPages = 0; if (!isValid) validate(handle, firstAllocPageNumber); for (int i = 0; i < numExtents; i++) { if (extents[i] != null) { currAllocPages = extents[i].getAllocatedPageCount(); numAllocatedPages += currAllocPages; numUnfilledPages += extents[i].getUnfilledPageCount(); numFreePages += (extents[i].getTotalPageCount() - currAllocPages); } if (SanityManager.DEBUG) { SanityManager.ASSERT(numUnfilledPages <= numAllocatedPages, "more unfilled pages than allocated pages on extent[" + i + "], " + "numUnfilledPages = " + numUnfilledPages + ", numAllocatedPages = " + numAllocatedPages + ", numFreePages = " + numFreePages); } } return new SpaceInformation( numAllocatedPages, numFreePages, numUnfilledPages); } /* invalidate all extents */ protected void invalidate() { if (SanityManager.DEBUG) { if (SanityManager.DEBUG_ON(FileContainer.SPACE_TRACE)) { SanityManager.DEBUG( FileContainer.SPACE_TRACE, "alloc cache invalidated"); } } for (int i = 0; i < numExtents; i++) { isDirty[i] = false; extents[i] = null; } isValid = false; } /* invalidate the extent that is managed by this alloc page */ protected void invalidate(AllocPage allocPage, long allocPagenum) throws StandardException { if (SanityManager.DEBUG) { if (SanityManager.DEBUG_ON(FileContainer.SPACE_TRACE)) { SanityManager.DEBUG( FileContainer.SPACE_TRACE, "alloc cache for page " + allocPagenum + " invalidated"); } } isValid = false; if (numExtents == 0) return; for (int i = 0; i < numExtents; i++) { if (extentPageNums[i] == allocPagenum) { // update unfilled page info if (allocPage != null && extents[i] != null && isDirty[i]) { // replace unFilledPage bitmap with the one in the allocation // cache, which has the more current information // call this ONLY in invalidate, when the reference to the // extent is about to be nulled out allocPage.updateUnfilledPageInfo(extents[i]); isDirty[i] = false; } extents[i] = null; return; } } // handle the case where a new alloc page that has never been entered // into the cache is asked to be invalidated if (allocPagenum > hiRange[numExtents-1]) return; if (SanityManager.DEBUG) SanityManager.THROWASSERT("cannot find extent managed by " + allocPagenum); } /* invalidate the last extent */ protected void invalidateLastExtent() { if (SanityManager.DEBUG) { if (SanityManager.DEBUG_ON(FileContainer.SPACE_TRACE)) { SanityManager.DEBUG( FileContainer.SPACE_TRACE, "last extent (" + extentPageNums[numExtents-1] + ") invalidated"); } } isValid = false; if (numExtents > 0) extents[numExtents - 1] = null; } /** Get the last valid page of the file container. A valid page is one that is not deallocated or freed. */ protected long getLastValidPage(BaseContainerHandle handle, long firstAllocPageNumber)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -