public class StoredPage extends CachedPage
Page Format
The page is broken into five sections
+----------+-------------+-------------------+-------------------+----------+ | formatId | page header | records | slot offset table | checksum | +----------+-------------+-------------------+-------------------+----------+
1 byte boolean is page an overflow page 1 byte byte page status (a field maintained in base page) 8 bytes long pageVersion (a field maintained in base page) 2 bytes unsigned short number of slots in slot offset table 4 bytes integer next record identifier 4 bytes integer generation number of this page (Future Use) 4 bytes integer previous generation of this page (Future Use) 8 bytes bipLocation the location of the beforeimage page (Future Use) 2 bytes unsigned short number of deleted rows on page. (new release 2.0) 2 bytes unsigned short % of the page to keep free for updates 2 bytes short spare for future use 4 bytes long spare for future use (encryption uses to write random bytes here). 8 bytes long spare for future use 8 bytes long spare for future useNote that spare space has been guaranteed to be writen with "0", so that future use of field should not either not use "0" as a valid data item or pick 0 as a valid default value so that on the fly upgrade can assume that 0 means field was never assigned.
Fields 1 byte Boolean - is null, if true no more data follows. 4 bytes Integer - length of field that follows (excludes these four bytes). StoredPage will use the static method provided by StoredFieldHeader to read/write field status and field data length. Field Header format is defined in the StoredFieldHeader class.
Page Access The page data is accessed in this class by one of three methods.
CRC32
,
ArrayInputStream
,
ArrayOutputStream
Modifier and Type | Field and Description |
---|---|
(package private) ByteHolder |
bh
In memory buffer used as scratch space for streaming columns.
|
private long |
bipLocation |
private java.util.zip.CRC32 |
checksum
holder for the checksum.
|
protected static int |
CHECKSUM_SIZE
Size of the checksum stored on the page.
|
protected static int |
COLUMN_CREATE_NULL |
protected static int |
COLUMN_FIRST |
protected static int |
COLUMN_LONG |
protected static int |
COLUMN_NONE
Constants used in call to logColumn.
|
private int |
deletedRowCount |
private int |
firstFreeByte |
static int |
FORMAT_NUMBER
static final Fields of the class
|
protected int |
freeSpace |
private int |
generation |
private boolean |
headerOutOfDate
Is the header in the byte array out of date wrt the fields.
|
private boolean |
isOverflowPage
The page header is a fixed size, 56 bytes, following are variables used
to access the fields in the header:
1 byte boolean isOverflowPage is page an overflow page
1 byte byte pageStatus page status (field in base page)
8 bytes long pageVersion page version (field in base page)
2 bytes ushort slotsInUse number of slots in slot offset table
4 bytes integer nextId next record identifier
4 bytes integer generation generation number of this page(FUTURE USE)
4 bytes integer prevGeneration previous generation of page (FUTURE USE)
8 bytes long bipLocation the location of the BI page (FUTURE USE)
2 bytes ushort deletedRowCount number of deleted rows on page.
|
protected static int |
LARGE_SLOT_SIZE |
protected FormatIdOutputStream |
logicalDataOut |
private int |
maxFieldSize
maxFieldSize is a worst case calculation for the size of a record
on an empty page, with a single field, but still allow room for
an overflow pointer if another field is to be added.
|
protected int |
minimumRecordSize
Minimum space to reserve for record portion length of row.
|
private int |
nextId |
protected static int |
OVERFLOW_POINTER_SIZE
OVERFLOW_POINTER_SIZE - Number of bytes to reserve for overflow pointer
The overflow pointer is the pointer that the takes the place of the
last column of a row if the row can't fit on the page.
|
protected static int |
OVERFLOW_PTR_FIELD_SIZE
OVERFLOW_PTR_FIELD_SIZE - Number of bytes of an overflow field
This is the length to reserve for either a column or row overflow
pointer field.
|
private StoredRecordHeader |
overflowRecordHeader
Scratch variable used when you need a overflowRecordHeader.
|
protected static int |
PAGE_HEADER_OFFSET
Start of page, formatId must fit in 4 bytes.
|
protected static int |
PAGE_HEADER_SIZE
Fixed size of the page header
|
protected static int |
PAGE_VERSION_OFFSET
offset of the page version number
|
private int |
prevGeneration |
protected ArrayInputStream |
rawDataIn
Input streams used to read/write bytes to/from the page byte array.
|
protected ArrayOutputStream |
rawDataOut |
protected static int |
RECORD_SPACE_OFFSET
Start of the record storage area.
|
private int |
slotEntrySize |
private int |
slotFieldSize
slot field and slot entry size.
|
private int |
slotsInUse |
private int |
slotTableOffsetToFirstEntry
Offset of the first entry in the slot table.
|
private int |
slotTableOffsetToFirstRecordLengthField
Offset of the record length entry in the 1st slot table entry.
|
private int |
slotTableOffsetToFirstReservedSpaceField
Offset of the reserved space length entry in the 1st slot table entry.
|
protected static int |
SMALL_SLOT_SIZE
SMALL_SLOT_SIZE are for pages smaller than 64K,
LARGE_SLOT_SIZE is for pages bigger than 64K.
|
protected int |
spareSpace
% of page to keep free for updates.
|
protected int |
totalSpace
total usable space on a page.
|
private int |
userRowSize
scratch variable used to keep track of the total user size for the row.
|
alreadyReadPage, containerCache, dataFactory, initialRowCount, isDirty, PAGE_FORMAT_ID_SIZE, pageCache, pageData, preDirty, WRITE_NO_SYNC, WRITE_SYNC
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
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
Constructor and Description |
---|
StoredPage()
Simple no-arg constructor for StoredPage.
|
Modifier and Type | Method and Description |
---|---|
private void |
addSlotEntry(int slot,
int recordOffset,
int recordPortionLength,
int reservedSpace)
Insert a new slot entry into the current slot array.
|
boolean |
allowInsert()
Is there enough space on the page to insert a minimum size row?
|
int |
appendOverflowFieldHeader(DynamicByteArrayOutputStream logBuffer,
RecordHandle overflowHandle)
Append an overflow pointer to a partly logged row,
to point to a long column that just been logged.
|
private int |
calculateSlotFieldSize(int pageSize)
Calculate the slot field size from the page size.
|
private boolean |
checkRowReservedSpace(int slot)
See if reserved space should be reclaimed for the input row.
|
private void |
cleanPage() |
private void |
clearAllSpace()
Initialize the freeSpace count and set the firstFreeByte on page
|
protected void |
clearSection(int offset,
int length)
Zero out a portion of the page.
|
protected void |
compactRecord(RawTransaction t,
int slot,
int id)
Subclass implementation of compactRecord.
|
private void |
compressPage(int startByte,
int endByte)
Compress out the space specified by startByte and endByte.
|
private void |
createOutStreams()
Create the output streams.
|
protected void |
createPage(PageKey newIdentity,
PageCreationArgs args)
Create a new StoredPage.
|
private void |
createSpaceForUpdate(int slot,
int offset,
int oldLength,
int newLength)
Create the space to update a portion of a record.
|
PageTimeStamp |
currentTimeStamp()
Get a time stamp for this page
|
void |
doUpdateAtSlot(RawTransaction t,
int slot,
int id,
java.lang.Object[] row,
FormatableBitSet validColumns)
Perform an update.
|
boolean |
entireRecordOnPage(int slot)
Is entire record on the page?
|
boolean |
equalTimeStamp(PageTimeStamp ts)
compare given PageVersion with pageVersion on page
|
protected void |
expandPage(int startOffset,
int requiredBytes)
Free up required bytes by shifting rows "down" the page.
|
int |
fetchNumFieldsAtSlot(int slot)
Get the number of fields on the row at slot
|
protected int |
getCurrentFreeSpace()
The current free space on the page.
|
private int |
getFieldOffset(int slot,
int fieldNumber)
Get the offset of the field header of the given field for
the record in the given slot.
|
protected boolean |
getIsOverflow(int slot) |
private int |
getMaxDataLength(int spaceAvailable,
int overflowThreshold)
return the max datalength allowed with the space available
|
protected int |
getMaxFreeSpace()
The maximum free space on this page possible.
|
protected BasePage |
getNewOverflowPage()
Get an empty overflow page.
|
private RecordHandle |
getNextColumnPiece(int slot)
Return the next recordHandle in a long column chain.
|
protected StoredPage |
getOverflowPage(long pageNumber)
Get the overflow page for a record that has already overflowed.
|
BasePage |
getOverflowPageForInsert(int currentSlot,
java.lang.Object[] row,
FormatableBitSet validColumns)
Get a overflow page that potentially can handle a new overflowed record.
|
BasePage |
getOverflowPageForInsert(int currentSlot,
java.lang.Object[] row,
FormatableBitSet validColumns,
int startColumn) |
private StoredRecordHeader |
getOverFlowRecordHeader()
get scratch space for over flow record header.
|
protected static int |
getOverflowSlot(BasePage overflowPage,
StoredRecordHeader recordHeader)
Get the overflow slot for a record that has already overflowed.
|
(package private) java.lang.String |
getPageDumpString() |
int |
getPageSize()
Get the full size of the page.
|
int |
getRecordLength(int slot)
Get the stored length of a record.
|
private int |
getRecordOffset(int slot)
Get the page offset of the record associated with the input slot.
|
protected int |
getRecordPortionLength(int slot)
Return length of row on this page.
|
int |
getReservedCount(int slot)
Return reserved length of row on this page.
|
private int |
getSlotOffset(int slot)
Get the page offset of a given slot entry.
|
protected int |
getSlotsInUse() |
int |
getTotalSpace(int slot)
Return the total number of bytes used, reserved, or wasted by the
record at this slot.
|
int |
getTypeFormatId()
Return my format identifier.
|
private void |
handleIncompleteLogRow(int slot,
int startColumn,
FormatableBitSet columnList,
DynamicByteArrayOutputStream out)
Handle an update of a record portion that is incomplete.
|
protected void |
initFromData(FileContainer myContainer,
PageKey newIdentity)
Initialize the page from values in the page buffer.
|
protected void |
initialize()
Initialize the StoredPage.
|
void |
initPage(LogInstant instant,
byte status,
int recordId,
boolean overflow,
boolean reuse)
Initialize the page.
|
private void |
initSlotTable(PageKey newIdentity)
Initialize the in-memory slot table.
|
private void |
initSpace()
initialize the in memory variables associated with space maintenance.
|
RecordHandle |
insertAtSlot(int slot,
java.lang.Object[] row,
FormatableBitSet validColumns,
LogicalUndo undo,
byte insertFlag,
int overflowThreshold)
Override insertAtSlot to provide long row support.
|
protected int |
internalDeletedRecordCount()
get record count without checking for latch
|
private boolean |
isColumnOrphaned(StoredRecordHeader recordHeader,
int columnId,
long oldPageId,
long oldRecordId)
See if there is a orphaned long colum chain or not.
|
private boolean |
isLong(int fieldSize,
int overflowThreshold)
return whether the field has exceeded the max threshold for this page
it compares the fieldSize with the largest possible field for this page
|
boolean |
isOverflowPage()
Return true if the page is an overflow page, false if not.
|
void |
logAction(LogInstant instant) |
void |
logColumn(int slot,
int fieldId,
java.lang.Object column,
DynamicByteArrayOutputStream out,
int overflowThreshold)
Log a Storable to a stream.
|
private int |
logColumn(java.lang.Object[] row,
int arrayPosition,
DynamicByteArrayOutputStream out,
int spaceAvailable,
int columnFlag,
int overflowThreshold)
Log column from input row to the given output stream.
|
void |
logField(int slot,
int fieldNumber,
java.io.OutputStream out)
Log a field to the ObjectOutput stream.
|
int |
logLongColumn(int slot,
int recordId,
java.lang.Object column,
DynamicByteArrayOutputStream out)
Log a long column into a DataOuput.
|
private int |
logOverflowField(DynamicByteArrayOutputStream out,
int spaceAvailable,
long overflowPage,
int overflowId) |
private int |
logOverflowRecord(int slot,
int spaceAvailable,
DynamicByteArrayOutputStream out)
Create and write a long row header to the log stream.
|
void |
logRecord(int slot,
int flag,
int recordId,
FormatableBitSet validColumns,
java.io.OutputStream out,
RecordHandle headRowHandle)
Log a record to the ObjectOutput stream.
|
private void |
logRecordDataPortion(int slot,
int flag,
StoredRecordHeader recordHeader,
FormatableBitSet validColumns,
java.io.OutputStream out,
RecordHandle headRowHandle) |
int |
logRow(int slot,
boolean forInsert,
int recordId,
java.lang.Object[] row,
FormatableBitSet validColumns,
DynamicByteArrayOutputStream out,
int startColumn,
byte insertFlag,
int realStartColumn,
int realSpaceOnPage,
int overflowThreshold)
Log a row into the StoreOuput stream.
|
int |
moveRecordForCompressAtSlot(int slot,
java.lang.Object[] row,
RecordHandle[] old_handle,
RecordHandle[] new_handle)
Move record to a page toward the beginning of the file.
|
private int |
moveSavedDataToPage(DynamicByteArrayOutputStream savedData,
int unusedSpace,
int pageOffset) |
int |
newRecordId()
Create a new record handle.
|
protected int |
newRecordId(int recordId)
Create a new record id based on current one passed in.
|
int |
newRecordIdAndBump()
Create a new record handle, and bump the id.
|
private static java.lang.String |
pagedataToHexDump(byte[] data)
Provide a hex dump of the data in the in memory version of the page.
|
private java.lang.String |
pageHeaderToString() |
private void |
purgeColumnChains(RawTransaction t,
int slot,
RecordHandle headRowHandle)
purge long columns chains which eminate from this page.
|
private void |
purgeOneColumnChain(long overflowPageId,
int overflowRecordId)
Purge the column chain that starts at overflowPageId, overflowRecordId
Purge just the column chain that starts at the input address.
|
protected void |
purgeOverflowAtSlot(int slot,
RecordHandle headRowHandle,
boolean needDataLogged)
Purge one row on an overflow page.
|
void |
purgeRecord(LogInstant instant,
int slot,
int recordId)
purgeRecord from page.
|
protected void |
purgeRowPieces(RawTransaction t,
int slot,
RecordHandle headRowHandle,
boolean needDataLogged)
Purge all the overflow columns and overflow rows of the record at slot.
|
private boolean |
qualifyRecordFromRow(java.lang.Object[] row,
Qualifier[][] qual_list)
Process the qualifier list on the row, return true if it qualifies.
|
private boolean |
qualifyRecordFromSlot(java.lang.Object[] row,
int offset_to_row_data,
FetchDescriptor fetchDesc,
StoredRecordHeader recordHeader,
RecordHandle recordToLock)
Process the list of qualifiers on the row in the stream.
|
private void |
readOneColumnFromPage(java.lang.Object[] row,
int colid,
int offset_to_field_data,
StoredRecordHeader recordHeader,
RecordHandle recordToLock)
Read just one column from stream into row.
|
private void |
readPageHeader()
Read the page header from the page array.
|
private boolean |
readRecordFromArray(java.lang.Object[] row,
int max_colid,
int[] vCols,
int[] mCols,
ArrayInputStream dataIn,
StoredRecordHeader recordHeader,
RecordHandle recordToLock) |
private boolean |
readRecordFromStream(java.lang.Object[] row,
int max_colid,
int[] vCols,
int[] mCols,
LimitObjectInput dataIn,
StoredRecordHeader recordHeader,
RecordHandle recordToLock)
restore a record from a stream.
|
StoredRecordHeader |
recordHeaderOnDemand(int slot)
create the record header for the specific slot.
|
private java.lang.String |
recordToString(int slot) |
protected void |
releaseExclusive()
Ensure that the page is released from the cache when it is unlatched.
|
(package private) void |
removeOrphanedColumnChain(ReclaimSpace work,
ContainerHandle containerHdl)
Remove a column chain that may have been orphaned by an update.
|
private void |
removeSlotEntry(int slot)
Remove slot entry from slot array.
|
void |
reserveSpaceForSlot(LogInstant instant,
int slot,
int spaceToReserve)
reserveSpaceForSlot
This method will reserve at least specified "spaceToReserve" bytes for the record
in the slot.
|
private void |
resetOutputStream()
Reset the logical output stream.
|
private StoredRecordHeader |
restoreLongRecordFromSlot(java.lang.Object[] row,
FetchDescriptor fetchDesc,
RecordHandle recordToLock,
StoredRecordHeader parent_recordHeader) |
void |
restorePortionLongColumn(OverflowInputStream fetchStream)
Restore a portion of a long column.
|
protected boolean |
restoreRecordFromSlot(int slot,
java.lang.Object[] row,
FetchDescriptor fetchDesc,
RecordHandle recordToLock,
StoredRecordHeader recordHeader,
boolean isHeadRow)
Read the record at the given slot into the given row.
|
void |
restoreRecordFromStream(LimitObjectInput in,
java.lang.Object[] row)
Restore a storable row from a LimitInputStream.
|
void |
setDeleteStatus(LogInstant instant,
int slot,
boolean delete)
Set the deleted status
|
private void |
setOutputStream(java.io.OutputStream out)
Tie the logical output stream to a passed in OutputStream.
|
void |
setPageStatus(LogInstant instant,
byte status)
Set page status
|
private void |
setRecordOffset(int slot,
int recordOffset)
Set the page offset of the record associated with the input slot.
|
void |
setReservedSpace(LogInstant instant,
int slot,
int value)
Set the row reserved space.
|
private void |
setSlotEntry(int slot,
int recordOffset,
int recordPortionLength,
int reservedSpace)
Set up a new slot entry.
|
void |
setTimeStamp(PageTimeStamp ts)
Set given pageVersion to be the as what is on this page
|
private int |
shiftRemainingData(int slot,
int offset,
int oldLength,
int newLength)
Shift data within a record to account for an update.
|
private void |
shrinkPage(int startOffset,
int shrinkBytes)
Shrink page.
|
void |
skipField(java.io.ObjectInput in)
Skip a field header and its data on the given stream.
|
void |
skipRecord(java.io.ObjectInput in) |
protected boolean |
spaceForCopy(int spaceNeeded,
int source_id)
Does this page have enough space to move the row to it.
|
boolean |
spaceForCopy(int num_rows,
int[] spaceNeeded)
Does this page have enough space to insert the input rows?
|
boolean |
spaceForInsert()
Is there minimal space for insert?
|
boolean |
spaceForInsert(java.lang.Object[] row,
FormatableBitSet validColumns,
int overflowThreshold)
Is row guaranteed to be inserted successfully on this page?
|
private boolean |
spaceForInsert(java.lang.Object[] row,
FormatableBitSet validColumns,
int spaceNeeded,
int startColumn,
int overflowThreshold)
Is row guaranteed to be inserted successfully on this page?
|
void |
storeField(LogInstant instant,
int slot,
int fieldNumber,
java.io.ObjectInput in)
storeField
|
void |
storeRecord(LogInstant instant,
int slot,
boolean insert,
java.io.ObjectInput in)
Store a record at the given slot.
|
private void |
storeRecordForInsert(int slot,
java.io.ObjectInput in) |
private void |
storeRecordForUpdate(int slot,
java.io.ObjectInput in) |
java.lang.String |
toString()
debugging, print this page
|
java.lang.String |
toUncheckedString() |
boolean |
unfilled()
Is this page unfilled?
|
protected void |
updateChecksum()
Recalculate checksum and write it to the page array.
|
RecordHandle |
updateFieldAtSlot(int slot,
int fieldId,
java.lang.Object newValue,
LogicalUndo undo)
Update field at specified slot
|
void |
updateFieldOverflowDetails(RecordHandle handle,
RecordHandle overflowHandle)
Update the overflow pointer for a long column
MT - latched - page latch must be held |
void |
updateOverflowDetails(RecordHandle handle,
RecordHandle overflowHandle)
Update a record handle to point to an overflowed record portion.
|
private void |
updateOverflowDetails(StoredPage handlePage,
RecordHandle handle,
RecordHandle overflowHandle) |
protected void |
updateOverflowed(RawTransaction t,
int slot,
java.lang.Object[] row,
FormatableBitSet validColumns,
StoredRecordHeader recordHeader)
Update an already overflowed record.
|
private void |
updatePageHeader()
Update the page header in the page array.
|
private void |
updatePageVersion()
Update the page version number in the byte array
|
private void |
updateRecordPortionLength(int slot,
int delta,
int reservedDelta)
Update the length of data stored on this page for this record
Update both the record length "field" and the reserved space "field"
of the slot table entry associated with "slot".
|
protected void |
usePageBuffer(byte[] pageBuffer)
use this passed in page buffer as this object's page data.
|
protected void |
validateChecksum(PageKey id)
Validate the check sum on the page.
|
protected void |
writeFormatId(PageKey identity)
Write out the format id of this page
|
protected void |
writePage(PageKey identity)
Write information about page from variables into page byte array.
|
clean, clearIdentity, createIdentity, getPageArray, isActuallyDirty, isDirty, preDirty, setContainerRowCount, setDirty, setFactory, setIdentity, setPageArray
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
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
getIdentity
public static final int FORMAT_NUMBER
protected static final int PAGE_HEADER_OFFSET
where the page header starts - page format is mandated by cached page
protected static final int PAGE_HEADER_SIZE
protected static final int RECORD_SPACE_OFFSET
Note: a subclass may change the start of the record storage area. Don't always count on this number.
protected static final int PAGE_VERSION_OFFSET
protected static final int SMALL_SLOT_SIZE
protected static final int LARGE_SLOT_SIZE
protected static final int CHECKSUM_SIZE
protected static final int OVERFLOW_POINTER_SIZE
protected static final int OVERFLOW_PTR_FIELD_SIZE
ByteHolder bh
protected static final int COLUMN_NONE
Action taken in this routine is determined by the kind of column as specified in the columnFlag: COLUMN_NONE - the column is insignificant COLUMN_FIRST - this is the first column in a logRow() call COLUMN_LONG - this is a known long column, therefore we will store part of the column on the current page and overflow the rest if necessary. COLUMN_CREATE_NULL - the column was recently added. it doesn't actually exist in the on-disk row yet. we will need to put a null in it as soon as possible. see DERBY-5679.
protected static final int COLUMN_FIRST
protected static final int COLUMN_LONG
protected static final int COLUMN_CREATE_NULL
private int maxFieldSize
private boolean isOverflowPage
1 byte boolean isOverflowPage is page an overflow page 1 byte byte pageStatus page status (field in base page) 8 bytes long pageVersion page version (field in base page) 2 bytes ushort slotsInUse number of slots in slot offset table 4 bytes integer nextId next record identifier 4 bytes integer generation generation number of this page(FUTURE USE) 4 bytes integer prevGeneration previous generation of page (FUTURE USE) 8 bytes long bipLocation the location of the BI page (FUTURE USE) 2 bytes ushort deletedRowCount number of deleted rows on page.(rel 2.0) 2 bytes long spare for future use 4 bytes long spare (encryption writes random bytes) 8 bytes long spare for future use 8 bytes long spare for future use Note that spare space has been guaranteed to be writen with "0", so that future use of field should not either not use "0" as a valid data item or pick 0 as a valid default value so that on the fly upgrade can assume that 0 means field was never assigned.
private int slotsInUse
private int nextId
private int generation
private int prevGeneration
private long bipLocation
private int deletedRowCount
private boolean headerOutOfDate
this field must be set to true whenever one of the above header fields is modified. Ie any of (isOverflowPage, slotsInUse, nextId, generation, prevGeneration, bipLocation, deletedRowCount)
private java.util.zip.CRC32 checksum
protected int minimumRecordSize
minimumRecordSize is stored in the container handle. It is used to reserve minimum space for recordPortionLength. Default is 1. To get the value from the container handle: myContainer.getMinimumRecordSize(); minimumRecordSize is the minimum user record size, excluding the space we use for the record header and field headers. When a record is inserted, it is stored in a space at least as large as the sum of the minimumRecordSize and total header size. For example, If minimumRecordSize is 10 bytes, the user record is 7 bytes, we used 5 bytes for record and field headers, this record will take (10 + 5) bytes of space, extra 3 bytes is put into reserve. If minimumRecordSize is 10 bytes, user record is 17 bytes, we used 5 bytes for record and field headers, this record will take (17 + 5) bytes of space, no reserve space here. minimumRecordSize is defined by user on per container basis. The default for minimumRecordSize is set to 1.
private int userRowSize
private int slotFieldSize
The size of these fields is dependant on the page size. These 2 variables should be set when pageSize is determined, and should not be changed for that page. Each slot entry contains 3 fields (slotOffet, recordPortionLength and reservedSpace) for the record the slot is pointing to. slotFieldSize is the size for each of the slot field. slotEntrySize is the total space used for a single slot entry.
private int slotEntrySize
private int slotTableOffsetToFirstEntry
Offset table is located at end of page, just before checksum. It grows backward as an array from this point toward the middle of the page.
slotTableOffsetToFirstEntry is the offset to the beginning of the first entry (slot[0]) in the slot table. This allows the following math to get to the offset of N'th entry in the slot table: offset of slot[N] = slotTableOffsetToFirstEntry + (N * slotEntrySize)
private int slotTableOffsetToFirstRecordLengthField
Offset table is located at end of page, just before checksum. It grows backward as an array from this point toward the middle of the page. The record length is stored as the second "field" of the slot table entry.
slotTableOffsetToFirstRecordLengthField is the offset to the beginning of the record length field in the first entry (slot[0]) in the slot table. This allows the following math to get to the record length field of N'th entry in the slot table: offset of record length of slot[N] slot entry = slotTableOffsetToFirstRecordLengthField + (N * slotEntrySize)
private int slotTableOffsetToFirstReservedSpaceField
Offset table is located at end of page, just before checksum. It grows backward as an array from this point toward the middle of the page. The reserved space length is stored as the third "field" of the slot table entry.
slotTableOffsetToFirstReservedSpaceField is the offset to the beginning of the reserved space field in the first entry (slot[0]) in the slot table. This allows the following math to get to the reserved space field of N'th entry in the slot table: offset of reserved space of slot[N] slot entry = slotTableOffsetToFirstReservedSpaceField + (N * slotEntrySize)
protected int totalSpace
This is the space not taken by page hdr, page table, and existing slot entries/rows.
protected int freeSpace
private int firstFreeByte
protected int spareSpace
How much of a head page should be reserved as "free" so that the space can be used by update which expands the row without needing to overflow it. 1 means save 1% of the free space for expansion.
private StoredRecordHeader overflowRecordHeader
protected ArrayInputStream rawDataIn
protected ArrayOutputStream rawDataOut
protected FormatIdOutputStream logicalDataOut
public int getTypeFormatId()
private StoredRecordHeader getOverFlowRecordHeader() throws StandardException
StandardException
- Standard exception policy.protected void initialize()
Initialize the object, ie. perform work normally perfomed in constructor. Called by setIdentity() and createIdentity() - the Cacheable interfaces which are used to move a page in/out of cache.
initialize
in class CachedPage
private void createOutStreams()
Create the output streams, these are created on demand to avoid creating unrequired objects for pages that are never modified during their lifetime in the cache.
StandardException
- Standard exception policy.private void setOutputStream(java.io.OutputStream out)
Tie the logical output stream to a passed in OutputStream with no limit as to the number of bytes that can be written.
private void resetOutputStream()
Reset the logical output stream (logicalDataOut) to be attached to the page array stream as is the norm, no limits are placed on any writes.
protected void usePageBuffer(byte[] pageBuffer)
The page content may not have been read in from disk yet. For pagesize smaller than 64K: Size of the record offset stored in a slot (unsigned short) Size of the record portion length stored in a slot (unsigned short) Size of the record portion length stored in a slot (unsigned short) For pagesize greater than 64K, but less than 2gig: Size of the record offset stored in a slot (int) Size of the record portion length stored in a slot (int) Size of the record portion length stored in a slot (int)
usePageBuffer
in class CachedPage
pageBuffer
- The array of bytes to use as the page buffer.private int calculateSlotFieldSize(int pageSize)
pageSize
- page size in bytesprotected void createPage(PageKey newIdentity, PageCreationArgs args) throws StandardException
Make this object represent a new page (ie. a page that never existed before, as opposed to reading in an existing page from disk).
createPage
in class CachedPage
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.protected void initFromData(FileContainer myContainer, PageKey newIdentity) throws StandardException
Initialize in memory structure using the buffer in pageData. This is how a StoredPage object is intialized to represent page read in from disk.
initFromData
in class CachedPage
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 validateChecksum(PageKey id) throws StandardException
Compare the check sum stored in the page on disk with the checksum calculated from the bytes on the page.
id
- The key that describes the page.StandardException
- Standard exception policy.protected void updateChecksum() throws java.io.IOException
Recalculate the checksum of the page, and write the result back into the last bytes of the page.
java.io.IOException
- if writing to end of array fails.protected void writePage(PageKey identity) throws StandardException
This routine insures that all information about the page is reflected in the page byte buffer. This involves moving information from local variables into encoded version on the page in page header and checksum.
writePage
in class CachedPage
identity
- The key of this page.StandardException
- Standard exception policy.protected void writeFormatId(PageKey identity) throws StandardException
writeFormatId
in class CachedPage
identity
- The key of this page.StandardException
- Standard exception policy.protected void releaseExclusive()
releaseExclusive
in class CachedPage
BasePage.releaseExclusive()
public int getTotalSpace(int slot) throws StandardException
The amount of space the record on this slot is currently taking on the page. If there is any reserve space or wasted space, count that in also Do NOT count the slot entry size
getTotalSpace
in class BasePage
slot
- look at row at this slot.StandardException
- Standard exception policy.public boolean spaceForInsert() throws StandardException
Does quick calculation to see if average size row on this page could be inserted on the page. This is done because the actual row size being inserted isn't known until we actually copy the columns from their object form into their on disk form which is expensive. So we use this calculation so that in the normal case we only do one copy of the row directly onto the page.
StandardException
- Standard exception policy.public boolean spaceForInsert(java.lang.Object[] row, FormatableBitSet validColumns, int overflowThreshold) throws StandardException
Return true if this record is guaranteed to be inserted successfully using insert() or insertAtSlot(). This guarantee is only valid while the row remains unchanged and the page latch is held.
row
- The row to check for insert.validColumns
- bit map to interpret valid columns in row.overflowThreshold
- The percentage of the page to use for the
insert. 100 means use 100% of the page,
50 means use 50% of page (ie. make sure
2 rows fit per page).StandardException
- Standard exception policy.private boolean spaceForInsert(java.lang.Object[] row, FormatableBitSet validColumns, int spaceNeeded, int startColumn, int overflowThreshold) throws StandardException
Return true if this record is guaranteed to be inserted successfully using insert() or insertAtSlot(). This guarantee is only valid while the row remains unchanged and the page latch is held.
This is a private call only used when calculating whether an overflow page can be used to insert part of an overflow row/column.
row
- The row to check for insert.validColumns
- bit map to interpret valid columns in row.overflowThreshold
- The percentage of the page to use for the
insert. 100 means use 100% of the page,
50 means use 50% of page (ie. make sure
2 rows fit per page).StandardException
- Standard exception policy.public boolean unfilled()
Returns true if page is relatively unfilled, which means the page is < 1/2 full and has enough space to insert an "average" sized row onto the page.
public boolean allowInsert()
Calculate whether there is enough space on the page to insert a minimum size row. The calculation includes maintaining the required reserved space on the page for existing rows to grow on the page.
allowInsert
in class BasePage
public boolean spaceForCopy(int num_rows, int[] spaceNeeded)
Can the rows with lengths spaceNeeded[0..num_rows-1] be copied onto this page?
spaceForCopy
in class BasePage
num_rows
- number of rows to check for.spaceNeeded
- array of lengths of the rows to insert.protected boolean spaceForCopy(int spaceNeeded, int source_id)
Calculate if a row of length "spaceNeeded" with current record id "source_id" will fit on this page.
spaceNeeded
- length of the row encoded with source_id record id.source_id
- record id of the row being moved.protected boolean restoreRecordFromSlot(int slot, java.lang.Object[] row, FetchDescriptor fetchDesc, RecordHandle recordToLock, StoredRecordHeader recordHeader, boolean isHeadRow) throws StandardException
This reads and initializes the columns in the row array from the raw bytes stored in the page associated with the given slot. If validColumns is non-null then it will only read those columns indicated by the bit set, otherwise it will try to read into every column in row[].
If there are more columns than entries in row[] then it just stops after every entry in row[] is full.
If there are more entries in row[] than exist on disk, the requested excess columns will be set to null by calling the column's object's restoreToNull() routine (ie. ((Object) column).restoreToNull() ).
If a qualifier list is provided then the row will only be read from disk if all of the qualifiers evaluate true. Some of the columns may have been read into row[] in the process of evaluating the qualifier.
This routine should only be called on the head portion of a row, it will call a utility routine to read the rest of the row if it is a long row.
restoreRecordFromSlot
in class BasePage
slot
- the slot numberrow
- (out) filled in sparse rowfetchDesc
- Information describing fetch, including what
columns to fetch and qualifiers.recordToLock
- the record handle for the row at top level,
and is used in OverflowInputStream to lock the
row for Blobs/Clobs.isHeadRow
- The row on this page includes the head record
handle. Will be false for the overflow portions
of a "long" row, where columns of a row span
multiple pages.StandardException
- Standard Derby error policyprivate StoredRecordHeader restoreLongRecordFromSlot(java.lang.Object[] row, FetchDescriptor fetchDesc, RecordHandle recordToLock, StoredRecordHeader parent_recordHeader) throws StandardException
StandardException
public int newRecordId()
Return the next record id for allocation. Callers of this interface expect the next id to get bumped some where else - probably by storeRecordForInsert().
newRecordId
in class BasePage
public int newRecordIdAndBump()
Create a new record handle, and bump the id while holding the latch so that no other user can ever see this record id. This will lead to unused record id's in the case where an insert fails because there is not enough space on the page.
newRecordIdAndBump
in class BasePage
protected int newRecordId(int recordId)
This interface is used for the "copy" insert interface of raw store where multiple rows are inserted into a page in a single logged operation. We don't want to bump the id until the operation is logged so we just allocated each id in order and then bump the next id at the end of the operation.
newRecordId
in class BasePage
recordId
- The id caller just used, return the next one.public boolean isOverflowPage()
BasePage
isOverflowPage
in class BasePage
public final int getPageSize()
protected final void clearSection(int offset, int length)
offset
- position of first byte to clearlength
- how many bytes to clearprotected int getMaxFreeSpace()
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
protected int getCurrentFreeSpace()
private void readPageHeader() throws java.io.IOException
Read the page header from byte form in the page array into in memory variables.
java.io.IOException
private void updatePageHeader() throws java.io.IOException
Write the bytes of the page header, taking the values from those in the in memory variables.
java.io.IOException
private void updatePageVersion() throws java.io.IOException
java.io.IOException
private int getSlotOffset(int slot)
Get the page offset of a slot entry, this is not the offset of the record stored in the slot, but the offset of the actual slot.
slot
- The array entry of the slot to find.private int getRecordOffset(int slot)
This is the actual offset on the page of the beginning of the record.
slot
- The array entry of the slot to find.private void setRecordOffset(int slot, int recordOffset) throws java.io.IOException
This is the actual offset on the page of the beginning of the record.
slot
- The array entry of the slot to set.recordOffset
- the new offset to set.java.io.IOException
protected int getRecordPortionLength(int slot) throws java.io.IOException
Return the total length of data and header stored on this page for this record. This length is stored as the second "field" of the slot table entry.
slot
- the slot of the row to look up the length of.java.io.IOException
public int getReservedCount(int slot) throws java.io.IOException
Return the reserved length of this record. This length is stored as the third "field" of the slot table entry.
getReservedCount
in class BasePage
slot
- the slot of the row to look up the length of.java.io.IOException
- Thrown by InputStream methods potential I/O errorsprivate void updateRecordPortionLength(int slot, int delta, int reservedDelta) throws java.io.IOException
Update both the record length "field" and the reserved space "field" of the slot table entry associated with "slot". This length is stored as the second "field" of the slot table entry. The changes to these 2 fields are represented as the delta to apply to each field as input in "delta" and "reservedDelta."
slot
- the slot of the record to set.delta
- The amount the record length changed.reservedDelta
- The amount the reserved length changed.StandardException
- Standard exception policy.java.io.IOException
private void initSlotTable(PageKey newIdentity) throws StandardException
Initialize the in-memory slot table, ie. that of our super-class BasePage. Go through all the records on the page and set the freeSpace and firstFreeByte on page.
newIdentity
- The identity of the page we are trying to
initialize, since we are in the middle of trying
to build the page existing info in the class is
not set up yet (like getIdentity()).StandardException
- Standard exception policy.private void setSlotEntry(int slot, int recordOffset, int recordPortionLength, int reservedSpace) throws java.io.IOException
slot
- the slot to initialize.recordOffset
- the offset on the page to find the record.recordPortionLength
- the actual length of record+hdr on page.reservedSpace
- the reserved length associated with record.StandardException
- Standard exception policy.java.io.IOException
private void addSlotEntry(int slot, int recordOffset, int recordPortionLength, int reservedSpace) throws java.io.IOException
Shift the existing slots from slot to (slotsInUse - 1) up by one. Up here means from low slot to high slot (e.g from slot 2 to slot 3). Our slot table grows backward so we have to be careful here.
slot
- Position the new slot will takerecordOffset
- Offset of the record for the new slotrecordPortionLength
- Length of the record stored in the new slotreservedSpace
- Length of reserved space of record in slotjava.io.IOException
private void removeSlotEntry(int slot) throws java.io.IOException
Remove a storage slot at slot. Shift the existing slots from slot+1 to (slotsInUse - 1) down by one.. Down here means from high slot to low slot (e.g from slot 3 to slot 2)
slot
- The slot to delete.java.io.IOException
public StoredRecordHeader recordHeaderOnDemand(int slot)
Create a new record header object, initialize it, and add it to the array of cache'd record headers on this page. Finally return reference to the initialized record header.
recordHeaderOnDemand
in class BasePage
slot
- return record header of this slot.public boolean entireRecordOnPage(int slot) throws StandardException
entireRecordOnPage
in class BasePage
slot
- Check record at this slot.StandardException
- Standard exception policy.protected void purgeOverflowAtSlot(int slot, RecordHandle headRowHandle, boolean needDataLogged) throws StandardException
HeadRowHandle is the recordHandle pointing to the head row piece.
slot
- slot number of row to purge.headRowHandle
- recordHandle of the head row piece.needDataLogged
- when true data is logged for purges otherwise just headers.StandardException
- Standard exception policy.private void purgeOneColumnChain(long overflowPageId, int overflowRecordId) throws StandardException
Purge just the column chain that starts at the input address. The long column chain is pointed at by a field in a row. The long column is then chained as a sequence of "rows", the last column then points to the next segment of the chain on each page. Long columns chains currently are only one row per page so the next slot of a row in a long row chain should always be the first slot.
overflowPageId
- The page where the long column chain starts.overflowRecordId
- The record id where long column chain starts.StandardException
- Standard exception policy.private void purgeColumnChains(RawTransaction t, int slot, RecordHandle headRowHandle) throws StandardException
Purge all the long column chains emanating from the record on this slot of this page. The headRowHandle is the record handle of the head row piece of this row - if this page is the head row, then headRowHandle is the record handle at the slot. Otherwise, headRowHandle points to a row on a different page, i.e., the head page.
t
- The raw transaction doing the purging.slot
- The slot of the row to purge.headRowHandle
- The RecordHandle of the head row.StandardException
- Standard exception policy.protected void purgeRowPieces(RawTransaction t, int slot, RecordHandle headRowHandle, boolean needDataLogged) throws StandardException
Purge all the overflow columns and overflow rows of the record at slot. This is called by BasePage.purgeAtSlot, the head row piece is purged there.
purgeRowPieces
in class BasePage
t
- The raw transaction doing the purging.slot
- The slot of the row to purge.headRowHandle
- The RecordHandle of the head row.needDataLogged
- when true data is logged for purges otherwise just headers.StandardException
- Standard exception policy.void removeOrphanedColumnChain(ReclaimSpace work, ContainerHandle containerHdl) throws StandardException
Remove a column chain that may have been orphaned by an update. This
is executed as a post commit operation. This page is the head page of
the row which used to point to the column chain in question. The
location of the orphaned column chain is in the ReclaimSpace record.
MT - latched. No lock will be gotten, the head record must already be
locked exclusive with no outstanding changes that can be rolled back.
work
- object describing the chain to remove.containerHdl
- open container handle to use to remove chain.StandardException
- Standard exception policy.private boolean isColumnOrphaned(StoredRecordHeader recordHeader, int columnId, long oldPageId, long oldRecordId) throws StandardException, java.io.IOException
See if there is a orphaned long colum chain or not. This is a helper function for removeOrphanedChain. This page, which may be a head page or overflow page, contains the column specified in columnId. It used to point to a long column chain at oldPageId and oldRecordId. Returns true if it no longer points to that long column chain.
recordHeader
- record header which used to point at the long columncolumnId
- column id of the long column in head.oldPageId
- the page id where the long column used to be.oldRecordId
- the record id where the long column used to be.StandardException
- Standard exception policy.java.io.IOException
private RecordHandle getNextColumnPiece(int slot) throws StandardException
Return a recordHandle pointing to the next piece of the column chain. This page must be an overflow page that is in a column chain. If this is the last piece of the overflow colum, return null.
slot
- The slot of the current long column piece.StandardException
- Standard exception policy.private void initSpace()
Get the total available space on an empty page. initSlotTable() must be called after the page has been read in.
private void clearAllSpace()
private void compressPage(int startByte, int endByte) throws java.io.IOException
As part of moving rows, updating rows, purging rows compact the space left between rows.
startByte
- compress out space starting at startByte offsetendByte
- compress out space ending at endByte offsetjava.io.IOException
protected void expandPage(int startOffset, int requiredBytes) throws java.io.IOException
Expand page, move all the data from start Offset down the page by the amount required to free up the required bytes.
startOffset
- offset on page to begin the shiftrequiredBytes
- the number of bytes that must be freed.java.io.IOException
- If IOException is raised during the page mod.private void shrinkPage(int startOffset, int shrinkBytes) throws java.io.IOException
move all the data from start Offset up the page by the amount shrunk.
startOffset
- offset on page to begin the shiftshrinkBytes
- the number of bytes that must be moved.java.io.IOException
- some IOException is raised during the page mod,
(unlikely as this is just writing to array).public int getRecordLength(int slot) throws java.io.IOException
BasePage
getRecordLength
in class BasePage
java.io.IOException
protected boolean getIsOverflow(int slot) throws java.io.IOException
java.io.IOException
public int logRow(int slot, boolean forInsert, int recordId, java.lang.Object[] row, FormatableBitSet validColumns, DynamicByteArrayOutputStream out, int startColumn, byte insertFlag, int realStartColumn, int realSpaceOnPage, int overflowThreshold) throws StandardException, java.io.IOException
Write the row in its record format to the stream. Record format is a record header followed by each field with its field header. See this class's description for the specifics of these headers. startColumn is used to specified which column for this logRow to start logging. When realStartColumn is specified, that means part of the row has already been logged. startColumn here indicates that the first column was logged in the logBuffer, need to continue log the rest of the row starting at realStartColumn. This is used when a longColumn is encountered during a long row. After done logging the long column, we need to continue logging the rest of the row. A -1 value for realStartColumn, means that it is not significant. logRow will not throw an noSpaceOnPage exception, if it is an overflow page, and the record we are inserting is the only record on the page. We are supporting rows expanding multiple pages through this mechanism. logRow expects row to be a sparse row.
logRow
in class BasePage
slot
- the slot of the row being logged.forInsert
- this is logging an insert (not update/delete).recordId
- record id of the row being logged.row
- actual data of row in object form. If row is
null then we are logging an overflow pointer.validColumns
- bit map describing valid columns in row.out
- stream to log to.startColumn
- what column to start with (see above for detail)insertFlag
- flag indicating mode we are in,
INSERT_DEFAULT - default insert
INSERT_SPLIT - splitting a row/column
across pages.realStartColumn
- If -1 ignore variable, else part of row has
already been logged, and should continue with
this column.realSpaceOnPage
- Use this as space on page if realStartColumn
is not -1.overflowThreshold
- How much of the page to use before deciding
to overflow a row.java.io.IOException
- RESOLVEStandardException
- Standard exception policy.BasePage.logRow(int, boolean, int, java.lang.Object[], org.apache.derby.iapi.services.io.FormatableBitSet, org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream, int, byte, int, int, int)
private void handleIncompleteLogRow(int slot, int startColumn, FormatableBitSet columnList, DynamicByteArrayOutputStream out) throws StandardException
Handle an update of a record portion that is incomplete. Ie. Columns have expanded that require other columns to move off the page into a new portion.
This method works out of the columns that need to be moved which are not being updated and makes a copy of their data. It then throws an exception with this data, much like the long column exception which will then allow the original insert to complete.
If no columns need to be saved (ie all the ones that would move are being updated) then no exception is thrown, logRow() will return and the update completes normally.
slot
- slot of the current update.startColumn
- column to start at, handles start in middle of rowcolumnList
- bit map indicating which columns are being updated.out
- place to lot to.StandardException
- Standard exception policy.public void restoreRecordFromStream(LimitObjectInput in, java.lang.Object[] row) throws StandardException, java.io.IOException
Restore a storable row from an LimitInputStream - user must supply two streams on top of the same data, one implements ObjectInput interface that knows how to restore the object, the other one implements LimitInputStream.
restoreRecordFromStream
in class BasePage
in
- the limit input streamrow
- (IN/OUT) row that is to be restored
(sparse representation)StandardException
- Standard exception policy.java.io.IOException
- object exceeds the available data in the stream.private boolean qualifyRecordFromRow(java.lang.Object[] row, Qualifier[][] qual_list) throws StandardException
A two dimensional array is to be used to pass around a AND's and OR's in conjunctive normal form. The top slot of the 2 dimensional array is optimized for the more frequent where no OR's are present. The first array slot is always a list of AND's to be treated as described above for single dimensional AND qualifier arrays. The subsequent slots are to be treated as AND'd arrays or OR's. Thus the 2 dimensional array qual[][] argument is to be treated as the following, note if qual.length = 1 then only the first array is valid and it is and an array of and clauses: (qual[0][0] and qual[0][0] ... and qual[0][qual[0].length - 1]) and (qual[1][0] or qual[1][1] ... or qual[1][qual[1].length - 1]) and (qual[2][0] or qual[2][1] ... or qual[2][qual[2].length - 1]) ... and (qual[qual.length - 1][0] or qual[1][1] ... or qual[1][2])
row
- The row being qualified.qual_list
- 2 dimensional array representing conjunctive
normal form of simple qualifiers.StandardException
- Standard exception policy.private final void readOneColumnFromPage(java.lang.Object[] row, int colid, int offset_to_field_data, StoredRecordHeader recordHeader, RecordHandle recordToLock) throws StandardException, java.io.IOException
The routine reads just one column from the row, it is mostly code taken from readRecordFromStream, but highly optimized to just get one column from a non-overflow row. It can only be called to read a row from the pageData array as it directly accesses the page array to avoid the Stream overhead while processing non-user data which does not need the limit functionality.
It is expected that this code will be called to read in a column associated with a qualifiers which are applied one column at a time, and has been specialized to proved the greatest peformance for processing qualifiers. This kind of access is done when scanning large datasets while applying qualifiers and thus any performance gain at this low level is multiplied by the large number of rows that may be iterated over.
The column is read into the object located in row[qual_colid].
row
- col is read into object in row[qual_colid].offset_to_field_data
- offset in bytes from top of page to fieldcolid
- the column id to read, colid N is row[N]recordHeader
- record header of row to read column from.recordToLock
- record handle to lock,
used by overflow column code.StandardException
- Standard exception policy.java.io.IOException
private final boolean qualifyRecordFromSlot(java.lang.Object[] row, int offset_to_row_data, FetchDescriptor fetchDesc, StoredRecordHeader recordHeader, RecordHandle recordToLock) throws StandardException, java.io.IOException
The rawDataIn stream is expected to be positioned after the record header.
Check all qualifiers in the qualifier array against row. Return true if all compares specified by the qualifier array return true, else return false.
This routine assumes client caller has already checked if the row is deleted or not. The row that it get's is expected to match the partial column list of the scan.
On entering this routine the stream should be positioned to the beginning of the row data, just after the row header. On exit the stream will also be positioned there. A two dimensional array is to be used to pass around a AND's and OR's in conjunctive normal form. The top slot of the 2 dimensional array is optimized for the more frequent where no OR's are present. The first array slot is always a list of AND's to be treated as described above for single dimensional AND qualifier arrays. The subsequent slots are to be treated as AND'd arrays or OR's. Thus the 2 dimensional array qual[][] argument is to be treated as the following, note if qual.length = 1 then only the first array is valid and it is and an array of and clauses: (qual[0][0] and qual[0][0] ... and qual[0][qual[0].length - 1]) and (qual[1][0] or qual[1][1] ... or qual[1][qual[1].length - 1]) and (qual[2][0] or qual[2][1] ... or qual[2][qual[2].length - 1]) ... and (qual[qual.length - 1][0] or qual[1][1] ... or qual[1][2])
row
- restore row into this object array.offset_to_row_data
- offset in bytes from top of page to rowfetchDesc
- Description of fetch including which cols
and qualifiers.recordHeader
- The record header of the row, it was read
in from stream and dataIn is positioned
after it.recordToLock
- The head row to use for locking, used to
lock head row of overflow columns/rows.StandardException
- Standard exception policy.java.io.IOException
private final boolean readRecordFromStream(java.lang.Object[] row, int max_colid, int[] vCols, int[] mCols, LimitObjectInput dataIn, StoredRecordHeader recordHeader, RecordHandle recordToLock) throws StandardException, java.io.IOException
The rawDataIn stream is expected to be positioned after the record header.
row
- restore row into this object array.max_colid
- The maximum numbered column id that will be
requested by caller. It should be:
min(row.length - 1, maximum bit set in vCols)
It is used to stop the inner most loop from
looking at more columns in the row.vCols
- If not null, bit map indicates valid cols.mCols
- If not null, int array indicates columns already
read in from the stream. A non-zero entry
means the column has already been read in.dataIn
- restore row from this stream.recordHeader
- The record header of the row, it was read in
from stream and dataIn is positioned after it.recordToLock
- The head row to use for locking, used to lock
head row of overflow columns/rows.StandardException
- Standard exception policy.java.io.IOException
private final boolean readRecordFromArray(java.lang.Object[] row, int max_colid, int[] vCols, int[] mCols, ArrayInputStream dataIn, StoredRecordHeader recordHeader, RecordHandle recordToLock) throws StandardException, java.io.IOException
StandardException
java.io.IOException
public void restorePortionLongColumn(OverflowInputStream fetchStream) throws StandardException, java.io.IOException
Restore a portion of a long column - user must supply two streams on top of the same data, one implements ObjectInput interface that knows how to restore the object, the other one implements LimitInputStream.
restorePortionLongColumn
in class BasePage
fetchStream
- the stream to read the next portion of long col fromStandardException
- Standard exception policy.java.io.IOException
public void logColumn(int slot, int fieldId, java.lang.Object column, DynamicByteArrayOutputStream out, int overflowThreshold) throws StandardException, java.io.IOException
Log a Storable into a stream. This is used by update field operations
Write the column in its field format to the stream. Field format is a field header followed the data of the column as defined by the data itself. See this class's description for the specifics of the header.
logColumn
in class BasePage
slot
- slot of the current recordfieldId
- field number of the column being updatedcolumn
- column version of the field.out
- Where to write the logged form.StandardException
- Standard Derby error policyjava.io.IOException
- RESOLVEpublic int logLongColumn(int slot, int recordId, java.lang.Object column, DynamicByteArrayOutputStream out) throws StandardException, java.io.IOException
Log a long column into a DataOuput. This is used by insert operations
Write the column in its field format to the stream. Field format is a field header followed the data of the column as defined by the data itself. See this class's description for the specifics of the header.
logLongColumn
in class BasePage
slot
- slot of the row with the columnrecordId
- record id of thecolumn
- the object form of the column to logout
- where to log to the column to.StandardException
- Standard Derby error policyjava.io.IOException
- I/O exception from writing to an array.BasePage.logColumn(int, int, java.lang.Object, org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream, int)
private int logColumn(java.lang.Object[] row, int arrayPosition, DynamicByteArrayOutputStream out, int spaceAvailable, int columnFlag, int overflowThreshold) throws StandardException, java.io.IOException
Read data from row[arrayPosition], and write the column data in raw store page format to the given column. Along the way determine if the column will fit on the current page.
Action taken in this routine is determined by the kind of column as specified in the columnFlag: COLUMN_NONE - the column is insignificant COLUMN_FIRST - this is the first column in a logRow() call COLUMN_LONG - this is a known long column, therefore we will store part of the column on the current page and overflow the rest if necessary.
Upon entry to this routine logicalDataOut is tied to the
DynamicByteArrayOutputStream out.
If a column is a long column and it does not totally fit on the current
page, then a LongColumnException is thrown. We package up info about
the current long column in the partially filled in exception so that
callers can take correct action. The column will now be set a as a
stream.
row
- array of column from which to read the column from.arrayPosition
- The array position of column to be reading from row.out
- The stream to write the raw store page format of the
the column to.spaceAvailable
- The number of bytes available on the page for
this column, this may differ from current page
as it may include bytes used by previous
columns.columnFlag
- one of: COLUMN_NONE, COLUMN_FIRST, or COLUMN_LONG.StandardException
- Standard exception policy.LongColumnException
- Thrown if column will not fit on a
single page. See notes abovejava.io.IOException
private int logOverflowRecord(int slot, int spaceAvailable, DynamicByteArrayOutputStream out) throws StandardException, java.io.IOException
Called to log a new overflow record, will check for space available and throw an exception if the record header will not fit on the page.
slot
- slot of record to log.spaceAvailable
- spaceAvaliable on page.out
- stream to log the record to.StandardException
- Standard exception policy.java.io.IOException
private int logOverflowField(DynamicByteArrayOutputStream out, int spaceAvailable, long overflowPage, int overflowId) throws StandardException, java.io.IOException
StandardException
java.io.IOException
public void logRecord(int slot, int flag, int recordId, FormatableBitSet validColumns, java.io.OutputStream out, RecordHandle headRowHandle) throws StandardException, java.io.IOException
Write out the complete on-page record to the store stream. Data is preceeded by a compressed int that gives the length of the following data.
logRecord
in class BasePage
slot
- Slot number the record is stored in.flag
- LOG_RECORD_*, the reason for logging the record.recordId
- Record identifier of the record.validColumns
- which columns needs to be loggedout
- Where to write the logged form.headRowHandle
- the recordHandle of the head row piece, used
for post commit cleanup for update.StandardException
- Standard Derby error policyjava.io.IOException
- on error writing to log stream.BasePage.logRecord(int, int, int, org.apache.derby.iapi.services.io.FormatableBitSet, java.io.OutputStream, org.apache.derby.iapi.store.raw.RecordHandle)
private void logRecordDataPortion(int slot, int flag, StoredRecordHeader recordHeader, FormatableBitSet validColumns, java.io.OutputStream out, RecordHandle headRowHandle) throws StandardException, java.io.IOException
StandardException
java.io.IOException
public void logField(int slot, int fieldNumber, java.io.OutputStream out) throws StandardException, java.io.IOException
Find the field in the record and then write out the complete field, i.e. header and data.
logField
in class BasePage
slot
- Slot number the record is stored in.fieldNumber
- Number of the field (starts at 0).out
- Where to write the logged form.StandardException
- Standard Derby error policyjava.io.IOException
- RESOLVEBasePage.logField(int, int, java.io.OutputStream)
public RecordHandle insertAtSlot(int slot, java.lang.Object[] row, FormatableBitSet validColumns, LogicalUndo undo, byte insertFlag, int overflowThreshold) throws StandardException
insertAtSlot
in interface Page
insertAtSlot
in class BasePage
slot
- The specified slotrow
- The row version of the datavalidColumns
- a bit map of which columns in the row is valid.
ValidColumns will not be changed by RawStore.undo
- if logical undo may be necessary, a function pointer
to the access code where the logical undo logic
resides. Null if logical undo is not necessary.insertFlag
- if INSERT_UNDO_WITH_PURGE set, then the undo of this
insert will purge the row rather than mark it as
deleted, which is the default bahavior for
insertAtSlot and insert.StandardException
- Standard Derby error policyPage.insertAtSlot(int, java.lang.Object[], org.apache.derby.iapi.services.io.FormatableBitSet, org.apache.derby.iapi.store.access.conglomerate.LogicalUndo, byte, int)
public RecordHandle updateFieldAtSlot(int slot, int fieldId, java.lang.Object newValue, LogicalUndo undo) throws StandardException
updateFieldAtSlot
in interface Page
updateFieldAtSlot
in class BasePage
slot
- is the slot numberfieldId
- is the column idnewValue
- has the new colum value to be stored in the recordundo
- if logical undo may be necessary, a function pointer to the
access code where the logical undo logic resides. Null if logical undo
is not necessary.StandardException
- Standard Derby error policyPage.updateFieldAtSlot(int, int, java.lang.Object, org.apache.derby.iapi.store.access.conglomerate.LogicalUndo)
public int fetchNumFieldsAtSlot(int slot) throws StandardException
fetchNumFieldsAtSlot
in interface Page
fetchNumFieldsAtSlot
in class BasePage
slot
- is the slot numberStandardException
- Standard Derby error policyPage.fetchNumFieldsAtSlot(int)
public int moveRecordForCompressAtSlot(int slot, java.lang.Object[] row, RecordHandle[] old_handle, RecordHandle[] new_handle) throws StandardException
As part of compressing the table records need to be moved from the end of the file toward the beginning of the file. Only the contiguous set of free pages at the very end of the file can be given back to the OS. This call is used to purge the row from the current page, insert it into a previous page, and return the new row location Mark the record identified by position as deleted. The record may be undeleted sometime later using undelete() by any transaction that sees the record.
The interface is optimized to work on a number of rows at a time, optimally processing all rows on the page at once. The call will process either all rows on the page, or the number of slots in the input arrays - whichever is smaller. Locking Policy
MUST be called with table locked, no locks are requested. Because
it is called with table locks the call will go ahead and purge any
row which is marked deleted. It will also use purge rather than
delete to remove the old row after it moves it to a new page. This
is ok since the table lock insures that no other transaction will
use space on the table before this transaction commits.
A page latch on the new page will be requested and released.
slot
- slot of original row to move.row
- a row template to hold all columns of row.old_handle
- An array to be filled in by the call with the
old handles of all rows moved.new_handle
- An array to be filled in by the call with the
new handles of all rows moved.StandardException
- Standard Derby error policyLockingPolicy
public void logAction(LogInstant instant) throws StandardException
StandardException
private void cleanPage()
public void initPage(LogInstant instant, byte status, int recordId, boolean overflow, boolean reuse) throws StandardException
initPage
in class BasePage
StandardException
- Derby Standard Error Policypublic void setPageStatus(LogInstant instant, byte status) throws StandardException
setPageStatus
in class BasePage
instant
- the log instant of the log recordstatus
- the page statusStandardException
- Derby Standard Error Policypublic void setReservedSpace(LogInstant instant, int slot, int value) throws StandardException, java.io.IOException
setReservedSpace
in class BasePage
StandardException
- Derby Standard Error Policyjava.io.IOException
public void storeRecord(LogInstant instant, int slot, boolean insert, java.io.ObjectInput in) throws StandardException, java.io.IOException
storeRecord
in class BasePage
StandardException
- Standard Derby error policyjava.io.IOException
- RESOLVEprivate void storeRecordForInsert(int slot, java.io.ObjectInput in) throws StandardException, java.io.IOException
StandardException
java.io.IOException
private void storeRecordForUpdate(int slot, java.io.ObjectInput in) throws StandardException, java.io.IOException
StandardException
java.io.IOException
private int moveSavedDataToPage(DynamicByteArrayOutputStream savedData, int unusedSpace, int pageOffset)
private void createSpaceForUpdate(int slot, int offset, int oldLength, int newLength) throws StandardException, java.io.IOException
StandardException
- Standard Derby error policyjava.io.IOException
- RESOLVEpublic void storeField(LogInstant instant, int slot, int fieldNumber, java.io.ObjectInput in) throws StandardException, java.io.IOException
storeField
in class BasePage
StandardException
- Standard Derby error policyjava.io.IOException
- RESOLVEpublic void reserveSpaceForSlot(LogInstant instant, int slot, int spaceToReserve) throws StandardException, java.io.IOException
reserveSpaceForSlot
in class BasePage
StandardException
- Standard Derby error policyjava.io.IOException
- RESOLVEpublic void skipField(java.io.ObjectInput in) throws java.io.IOException
public void skipRecord(java.io.ObjectInput in) throws java.io.IOException
skipRecord
in class BasePage
java.io.IOException
private int shiftRemainingData(int slot, int offset, int oldLength, int newLength) throws java.io.IOException
offset
- Offset where the update starts, need not be on a field boundry.oldLength
- length of the data being replacednewLength
- length of the data replacing the old datajava.io.IOException
public void setDeleteStatus(LogInstant instant, int slot, boolean delete) throws StandardException, java.io.IOException
setDeleteStatus
in class BasePage
slot
- the slot to delete or undeletedelete
- set delete status to this valueStandardException
- Standard Derby error policyjava.io.IOException
- RESOLVEBasePage.setDeleteStatus(int, boolean)
protected int internalDeletedRecordCount()
internalDeletedRecordCount
in class BasePage
public void purgeRecord(LogInstant instant, int slot, int recordId) throws StandardException, java.io.IOException
purgeRecord
in class BasePage
slot
- the slot to purgerecordId
- the id of the record that is to be purgedStandardException
- Standard Derby error policyjava.io.IOException
- RESOLVEprivate int getFieldOffset(int slot, int fieldNumber) throws java.io.IOException
java.io.IOException
public PageTimeStamp currentTimeStamp()
public void setTimeStamp(PageTimeStamp ts) throws StandardException
StandardException
- given time stamp is null or is not a time
stamp implementation this page knows how to deal withpublic boolean equalTimeStamp(PageTimeStamp ts) throws StandardException
ts
- the page version gotton from this page via a currentTimeStamp
or setTimeStamp call earlierStandardException
- given time stamp not gotton from this pagePageTimeStamp
public java.lang.String toString()
toString
in class java.lang.Object
public java.lang.String toUncheckedString()
private static java.lang.String pagedataToHexDump(byte[] data)
The output looks like: 00000000: 4d5a 9000 0300 0000 0400 0000 ffff 0000 MZ.............. 00000010: b800 0000 0000 0000 4000 0000 0000 0000 ........@....... 00000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000030: 0000 0000 0000 0000 0000 0000 8000 0000 ................ 00000040: 0e1f ba0e 00b4 09cd 21b8 014c cd21 5468 ........!..L.!Th 00000050: 6973 2070 726f 6772 616d 2063 616e 6e6f is program canno 00000060: 7420 6265 2072 756e 2069 6e20 444f 5320 t be run in DOS 00000070: 6d6f 6465 2e0d 0a24 0000 0000 0000 0050 mode...$.......P 00000080: 4500 004c 0109 008b abfd 3000 0000 0000 E..L......0..... 00000090: 0000 00e0 000e 210b 0102 3700 3405 0000 ......!...7.4... 000000a0: 8401 0000 6400 0000 6004 0000 1000 0000 ....d...`....... 000000b0: 5005 0000 0008 6000 1000 0000 0200 0001 P.....`......... 000000c0: 0000 0000 0000 0004 0000 0000 0000 0000 ................ 000000d0: 9007 0000 0400 0009 a207 0002 0000 0000 ................ 000000e0: 0010 0000 1000 0000 0010 0000 1000 0000 ................ 000000f0: 0000 0010 0000 0000 6006 00ef 8100 0000 ........`....... 00000100: 5006 00e6 0c00 0000 0007 00d0 0400 0000 P............... 00000110: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000120: 1007 00c8 7100 0000 0000 0000 0000 0000 ....q........... 00000130: 0000 0000 0000 0000 0000 0000 0000 0000 ................
data
- array of bytes to dump.private java.lang.String pageHeaderToString()
java.lang.String getPageDumpString()
private java.lang.String recordToString(int slot)
protected StoredPage getOverflowPage(long pageNumber) throws StandardException
StandardException
- Standard Derby error policyprotected BasePage getNewOverflowPage() throws StandardException
getNewOverflowPage
in class BasePage
StandardException
- Standard Derby error policyprotected static int getOverflowSlot(BasePage overflowPage, StoredRecordHeader recordHeader) throws StandardException
StandardException
- Standard Derby error policypublic BasePage getOverflowPageForInsert(int currentSlot, java.lang.Object[] row, FormatableBitSet validColumns) throws StandardException
StandardException
- Standard Derby error policypublic BasePage getOverflowPageForInsert(int currentSlot, java.lang.Object[] row, FormatableBitSet validColumns, int startColumn) throws StandardException
getOverflowPageForInsert
in class BasePage
StandardException
- Standard Derby error policyprotected void updateOverflowed(RawTransaction t, int slot, java.lang.Object[] row, FormatableBitSet validColumns, StoredRecordHeader recordHeader) throws StandardException
slot
- Slot of the original record on its original pagerow
- new version of the dataStandardException
- Standard Derby error policypublic void updateOverflowDetails(RecordHandle handle, RecordHandle overflowHandle) throws StandardException
updateOverflowDetails
in class BasePage
handle
- handle of the record for long rowoverflowHandle
- the overflow (continuation) pointer for the long rowStandardException
- Standard Derby error policyprivate void updateOverflowDetails(StoredPage handlePage, RecordHandle handle, RecordHandle overflowHandle) throws StandardException
StandardException
public void updateFieldOverflowDetails(RecordHandle handle, RecordHandle overflowHandle) throws StandardException
BasePage
updateFieldOverflowDetails
in class BasePage
handle
- handle of the record for long rowoverflowHandle
- the overflow (continuation) pointer for the long rowStandardException
- Standard Derby error policypublic int appendOverflowFieldHeader(DynamicByteArrayOutputStream logBuffer, RecordHandle overflowHandle) throws StandardException, java.io.IOException
BasePage
appendOverflowFieldHeader
in class BasePage
logBuffer
- The buffer that contains the partially logged row.overflowHandle
- the overflow (continuation) pointer
to the beginning of the long columnStandardException
- Standard Derby error policyjava.io.IOException
protected int getSlotsInUse()
private int getMaxDataLength(int spaceAvailable, int overflowThreshold)
private boolean isLong(int fieldSize, int overflowThreshold)
public void doUpdateAtSlot(RawTransaction t, int slot, int id, java.lang.Object[] row, FormatableBitSet validColumns) throws StandardException
doUpdateAtSlot
in class BasePage
StandardException
- Standard Derby policyprivate boolean checkRowReservedSpace(int slot) throws StandardException
See if the row on this page has reserved space that should be shrunk once the update commits. Will only indicate space should be reclaimed if at least RawTransaction.MINIMUM_RECORD_SIZE_DEFAULT bytes can be reclaimed.
StandardException
protected void compactRecord(RawTransaction t, int slot, int id) throws StandardException
BasePage
compactRecord
in class BasePage
StandardException
- Standard Derby error policyBasePage.compactRecord(org.apache.derby.iapi.store.raw.RecordHandle)
Apache Derby V10.13 Internals - Copyright © 2004,2016 The Apache Software Foundation. All Rights Reserved.