Cacheable
, TypedFormat
, DerbyObserver
, Page
public class AllocPage extends StoredPage
This class extends a normal Stored page, with the exception that a hunk of space may be 'borrowed' by the file container to store the file header.
The borrowed space is not visible to the alloc page even though it is present in the page data array. It is accessed directly by the FileContainer. Any change made to the borrowed space is not managed or seen by the allocation page.
The reason for having this borrowed space is so that the container header does not need to have a page of its own.
Page Format
An allocation page extends a stored page, the on disk format is different
from a stored page in that N bytes are 'borrowed' by the container and the
page header of an allocation page will be slightly bigger than a normal
stored page. This N bytes are stored between the page header and the
record space.
The reason why this N bytes can't simply be a row is because it needs to be statically accessible by the container object to avoid a chicken and egg problem of the container object needing to instantiate an alloc page object before it can be objectified, and an alloc page object needing to instantiate a container object before it can be objectified. So this N bytes must be stored outside of the normal record interface yet it must be settable because only the first alloc page has this borrowed space. Other (non-first) alloc page have N == 0.
[ borrowed ] +----------+-------------+---+---------+-------------------+-------------+--------+ | FormatId | page header | N | N bytes | alloc extend rows | slot offset |checksum| +----------+-------------+---+---------+-------------------+-------------+--------+N is a byte that indicates the size of the borrowed space. Once an alloc page is initialized, the value of N cannot change.
The maximum space that can be borrowed by the container is 256 bytes.
The allocation page are of the same page size as any other pages in the container. The first allocation page of the FileContainer starts at the first physical byte of the container. Subsequent allocation pages are chained via the nextAllocPageOffset. Each allocation page is expected to manage at least 1000 user pages (for 1K page size) so this chaining may not be a severe performance hit. The logical -> physical mapping of an allocation page is stored in the previous allocation page. The container object will need to maintain this mapping.
The following fields are stored in the page header
AllocExtent
Format ID | RAW_STORE_ALLOC_PAGE |
Purpose | |
manage page allocation | |
Upgrade | |
Disk Layout | FormatId(int) StoredPageHeader see StoredPage nextAllocPageNubmer(long) the next allocation page's number nextAllocPageOffset(long) the file offset of the next allocation page reserved1(long) reserved for future usage reserved2(long) reserved for future usage reserved3(long) reserved for future usage reserved4(long) reserved for future usage N(byte) the size of the borrowed container info containerInfo(byte[N]) the content of the borrowed container info AllocExtent the one and only extent on this alloc page |
Modifier and Type | Field | Description |
---|---|---|
protected static int |
ALLOC_PAGE_HEADER_OFFSET |
constants
|
protected static int |
ALLOC_PAGE_HEADER_SIZE |
|
protected static int |
BORROWED_SPACE_LEN |
|
protected static int |
BORROWED_SPACE_OFFSET |
|
private int |
borrowedSpace |
|
private AllocExtent |
extent |
|
static int |
FORMAT_NUMBER |
|
protected static int |
MAX_BORROWED_SPACE |
|
private long |
nextAllocPageNumber |
alloc page header
|
private long |
nextAllocPageOffset |
|
private long |
reserved1 |
|
private long |
reserved2 |
|
private long |
reserved3 |
|
private long |
reserved4 |
|
static java.lang.String |
TEST_MULTIPLE_ALLOC_PAGE |
Extent Testing
Use these strings to simulate error conditions for
testing purposes.
|
identity, inClean, INIT_PAGE_OVERFLOW, INIT_PAGE_REUSE, INIT_PAGE_REUSE_RECORDID, INVALID_PAGE, LOG_RECORD_DEFAULT, LOG_RECORD_FOR_PURGE, LOG_RECORD_FOR_UPDATE, owner, preLatch, VALID_PAGE
alreadyReadPage, containerCache, dataFactory, initialRowCount, isDirty, PAGE_FORMAT_ID_SIZE, pageCache, pageData, preDirty, WRITE_NO_SYNC, WRITE_SYNC
DIAG_BYTES_FREE, DIAG_BYTES_RESERVED, DIAG_MAXROWSIZE, DIAG_MINIMUM_REC_SIZE, DIAG_MINROWSIZE, DIAG_NUMOVERFLOWED, DIAG_PAGE_SIZE, DIAG_PAGEOVERHEAD, DIAG_RESERVED_SPACE, DIAG_ROWSIZE, DIAG_SLOTTABLE_SIZE, FIRST_SLOT_NUMBER, INSERT_CONDITIONAL, INSERT_DEFAULT, INSERT_FOR_SPLIT, INSERT_INITIAL, INSERT_OVERFLOW, INSERT_UNDO_WITH_PURGE, INVALID_SLOT_NUMBER
bh, CHECKSUM_SIZE, COLUMN_CREATE_NULL, COLUMN_FIRST, COLUMN_LONG, COLUMN_NONE, freeSpace, LARGE_SLOT_SIZE, logicalDataOut, minimumRecordSize, OVERFLOW_POINTER_SIZE, OVERFLOW_PTR_FIELD_SIZE, PAGE_HEADER_OFFSET, PAGE_HEADER_SIZE, PAGE_VERSION_OFFSET, rawDataIn, rawDataOut, RECORD_SPACE_OFFSET, SMALL_SLOT_SIZE, spareSpace, totalSpace
Constructor | Description |
---|---|
AllocPage() |
Modifier and Type | Method | Description |
---|---|---|
void |
addPage(FileContainer mycontainer,
long newPageNumber,
RawTransaction ntt,
BaseContainerHandle userHandle) |
Add a page which is managed by this alloc page.
|
boolean |
canAddFreePage(long lastAllocatedPage) |
|
void |
chainNewAllocPage(BaseContainerHandle allocHandle,
long newAllocPageNum,
long newAllocPageOffset) |
|
protected void |
chainNextAllocPage(LogInstant instant,
long newAllocPageNum,
long newAllocPageOffset) |
Chain the next page number and offset underneath a log record
|
protected boolean |
compress(RawTransaction ntt,
FileContainer myContainer) |
compress out empty pages at end of container.
|
protected void |
compressSpace(LogInstant instant,
int new_highest_page,
int num_pages_truncated) |
Compress free pages.
|
private AllocExtent |
createExtent(long pageNum,
int pageSize,
int pagesAlloced,
int availspace) |
|
protected void |
createPage(PageKey newIdentity,
PageCreationArgs args) |
Create a new alloc page.
|
void |
deallocatePage(BaseContainerHandle userHandle,
long pageNumber) |
|
protected AllocExtent |
getAllocExtent() |
Return a copy of the allocExtent to be cached by the container.
|
long |
getLastPagenum() |
|
protected long |
getLastPreallocPagenum() |
|
protected int |
getMaxFreeSpace() |
The maximum free space on this page possible.
|
long |
getMaxPagenum() |
|
long |
getNextAllocPageNumber() |
|
long |
getNextAllocPageOffset() |
|
protected int |
getPageStatus(long pageNumber) |
|
int |
getTypeFormatId() |
Return my format identifier.
|
protected void |
initFromData(FileContainer myContainer,
PageKey newIdentity) |
Initialize in memory structure using the buffer in pageData
|
boolean |
isLast() |
|
long |
nextFreePageNumber(long pnum) |
Return the next free page number after given page number
|
protected void |
preAllocatePage(FileContainer myContainer,
int preAllocThreshold,
int preAllocSize) |
Preallocate user page if needed.
|
private void |
readAllocPageHeader() |
|
static void |
ReadContainerInfo(byte[] containerInfo,
byte[] epage) |
Extract the container information from epage.
|
private AllocExtent |
readExtent(int offset) |
|
protected void |
setPageStatus(LogInstant instant,
long pageNumber,
int newStatus) |
Do the actual page allocation/deallocation/ree underneath a log operation.
|
java.lang.String |
toString() |
debugging, print this page
|
protected void |
undoCompressSpace(LogInstant instant,
int new_highest_page,
int num_pages_truncated) |
Handle undo of compress space operation.
|
private void |
updateAllocPageHeader() |
|
protected void |
updateUnfilledPageInfo(AllocExtent inputExtent) |
|
static void |
WriteContainerInfo(byte[] containerInfo,
byte[] epage,
boolean create) |
Write the container information into the container information area.
|
private void |
writeExtent(int offset) |
|
protected void |
writePage(PageKey identity) |
Write the page out
|
bumpPageVersion, bumpRecordCount, cleanPageForReuse, clearLastLogInstant, compactRecord, copyAndPurge, deallocatePage, deleteAtSlot, fetchFieldFromSlot, fetchFromSlot, fetchNumFields, fillInIdentity, findRecordById, getAuxObject, getHeaderAtSlot, getIdentity, getInvalidRecordHandle, getLastLogInstant, getNextSlotNumber, getPageId, getPageKey, getPageNumber, getPageStatus, getPageVersion, getRecordHandle, getRecordHandleAtSlot, getSlotNumber, initializeHeaders, initPage, insert, insertAllowOverflow, insertLongColumn, insertNoOverflow, internalNonDeletedRecordCount, isDeletedAtSlot, isDeletedOnPage, isLatched, isRepositionNeeded, makeRecordHandle, MakeRecordHandle, nonDeletedRecordCount, purgeAtSlot, recordCount, recordExists, removeAndShiftDown, setAuxObject, setDeleteStatus, setExclusive, setExclusiveNoWait, setHeaderAtSlot, setPageStatus, setPageVersion, setRepositionNeeded, shiftUp, shouldReclaimSpace, slotTableToString, unlatch, update, updateAtSlot, updateLastLogInstant
getIdentity
clean, clearIdentity, createIdentity, getPageArray, isActuallyDirty, isDirty, preDirty, setContainerRowCount, setDirty, setFactory, setIdentity, setPageArray
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
allowInsert, appendOverflowFieldHeader, clearSection, compactRecord, currentTimeStamp, doUpdateAtSlot, entireRecordOnPage, equalTimeStamp, expandPage, fetchNumFieldsAtSlot, getCurrentFreeSpace, getIsOverflow, getNewOverflowPage, getOverflowPage, getOverflowPageForInsert, getOverflowPageForInsert, getOverflowSlot, getPageDumpString, getPageSize, getRecordLength, getRecordPortionLength, getReservedCount, getSlotsInUse, getTotalSpace, initialize, initPage, insertAtSlot, internalDeletedRecordCount, isOverflowPage, logAction, logColumn, logField, logLongColumn, logRecord, logRow, moveRecordForCompressAtSlot, newRecordId, newRecordId, newRecordIdAndBump, purgeOverflowAtSlot, purgeRecord, purgeRowPieces, recordHeaderOnDemand, releaseExclusive, removeOrphanedColumnChain, reserveSpaceForSlot, restorePortionLongColumn, restoreRecordFromSlot, restoreRecordFromStream, setDeleteStatus, setPageStatus, setReservedSpace, setTimeStamp, skipField, skipRecord, spaceForCopy, spaceForCopy, spaceForInsert, spaceForInsert, storeField, storeRecord, toUncheckedString, unfilled, updateChecksum, updateFieldAtSlot, updateFieldOverflowDetails, updateOverflowDetails, updateOverflowed, usePageBuffer, validateChecksum, writeFormatId
public static final int FORMAT_NUMBER
private long nextAllocPageNumber
private long nextAllocPageOffset
private long reserved1
private long reserved2
private long reserved3
private long reserved4
private AllocExtent extent
private int borrowedSpace
protected static final int ALLOC_PAGE_HEADER_OFFSET
protected static final int ALLOC_PAGE_HEADER_SIZE
protected static final int BORROWED_SPACE_OFFSET
protected static final int BORROWED_SPACE_LEN
protected static final int MAX_BORROWED_SPACE
public static final java.lang.String TEST_MULTIPLE_ALLOC_PAGE
public int getTypeFormatId()
getTypeFormatId
in interface TypedFormat
getTypeFormatId
in class StoredPage
protected int getMaxFreeSpace()
StoredPage
The the maximum amount of space that can be used on the page for the records and the slot offset table. NOTE: subclass may have overwitten it to report less freeSpace
getMaxFreeSpace
in class StoredPage
protected void createPage(PageKey newIdentity, PageCreationArgs args) throws StandardException
createPage
in class StoredPage
newIdentity
- The key describing page (segment,container,page).args
- information stored about the page, once in the
container header and passed in through the object.StandardException
- Standard exception policy.private AllocExtent createExtent(long pageNum, int pageSize, int pagesAlloced, int availspace)
protected void initFromData(FileContainer myContainer, PageKey newIdentity) throws StandardException
initFromData
in class StoredPage
myContainer
- The container to read the page in from.newIdentity
- The key representing page being read in (segment,
container, page number)StandardException
- If the page cannot be read correctly, or is inconsistent.protected void writePage(PageKey identity) throws StandardException
writePage
in class StoredPage
identity
- The key of this page.StandardException
- If the page cannot be writtenprivate void readAllocPageHeader() throws java.io.IOException
java.io.IOException
private void updateAllocPageHeader() throws java.io.IOException
java.io.IOException
private AllocExtent readExtent(int offset) throws java.io.IOException, java.lang.ClassNotFoundException
java.io.IOException
java.lang.ClassNotFoundException
private void writeExtent(int offset) throws java.io.IOException
java.io.IOException
public static void WriteContainerInfo(byte[] containerInfo, byte[] epage, boolean create) throws StandardException
containerInfo
- the container informationepage
- 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 infocreate
- 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 lengthStandardException
- standard Derby error policypublic static void ReadContainerInfo(byte[] containerInfo, byte[] epage) throws StandardException
containerInfo
- where to put the extracted informationepage
- 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 infoStandardException
public long nextFreePageNumber(long pnum)
public void addPage(FileContainer mycontainer, long newPageNumber, RawTransaction ntt, BaseContainerHandle userHandle) throws StandardException
mycontainer
- (future) allows the alloc page to call back to the
container to grow the container by creating and syncing multiple
pages at oncentt
- the nested top action that is the allocation transaction.
NTT will comit before the user transactionuserHandle
- 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 pageStandardException
- If the page cannot be addedpublic void deallocatePage(BaseContainerHandle userHandle, long pageNumber) throws StandardException
StandardException
protected void updateUnfilledPageInfo(AllocExtent inputExtent)
public boolean canAddFreePage(long lastAllocatedPage)
public long getNextAllocPageOffset()
public void chainNewAllocPage(BaseContainerHandle allocHandle, long newAllocPageNum, long newAllocPageOffset) throws StandardException
StandardException
public long getNextAllocPageNumber()
public boolean isLast()
public long getLastPagenum()
public long getMaxPagenum()
protected long getLastPreallocPagenum()
protected int getPageStatus(long pageNumber)
protected void setPageStatus(LogInstant instant, long pageNumber, int newStatus) throws StandardException
StandardException
- If the page cannot be allocatedprotected void chainNextAllocPage(LogInstant instant, long newAllocPageNum, long newAllocPageOffset) throws StandardException
StandardException
- Standard Derby error policyprotected void compressSpace(LogInstant instant, int new_highest_page, int num_pages_truncated) throws StandardException
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.
instant
- log address for this operation.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.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.StandardException
- Standard exception policy.protected void undoCompressSpace(LogInstant instant, int new_highest_page, int num_pages_truncated) throws StandardException
StandardException
public java.lang.String toString()
StoredPage
toString
in class StoredPage
protected AllocExtent getAllocExtent()
protected void preAllocatePage(FileContainer myContainer, int preAllocThreshold, int preAllocSize)
myContainer
- the container objectpreAllocThreshold
- start preallocating after this thresholdpreAllocSize
- preallocate this number of pagesprotected boolean compress(RawTransaction ntt, FileContainer myContainer) throws StandardException
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.
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.
MT - expect Container level X lock
StandardException
- Standard exception policy.Apache Derby V10.14 Internals - Copyright © 2004,2018 The Apache Software Foundation. All Rights Reserved.