org.apache.derby.impl.store.raw.data
Class StoredPage

java.lang.Object
  extended by org.apache.derby.impl.store.raw.data.BasePage
      extended by org.apache.derby.impl.store.raw.data.CachedPage
          extended by org.apache.derby.impl.store.raw.data.StoredPage
All Implemented Interfaces:
java.util.Observer, Cacheable, TypedFormat, Page
Direct Known Subclasses:
AllocPage

public class StoredPage
extends CachedPage

StoredPage is a sub class of CachedPage that stores page data in a fixed size byte array and is designed to be written out to a file through a DataInput/DataOutput interface. A StoredPage can exist in its clean or dirty state without the FileContainer it was created from being in memory.

Page Format
The page is broken into five sections

  +----------+-------------+-------------------+-------------------+----------+
  | formatId | page header | records           | slot offset table | checksum |
  +----------+-------------+-------------------+-------------------+----------+
  

FormatId
The formatId is a 4 bytes array, it contains the format Id of this page.
Page Header
The page header is a fixed size, 56 bytes
  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 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.
Records The records section contains zero or more records, the format of each record follows. 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. This implementation always keeps occupied bytes at the low end of the record section. Thus removing (purging) a record moves all other records down, and their slots are also moved down. A page has no empty slot (an empty page has no slot)
Record & Field Format Record Header format is defined in the StoredRecordHeader class.
   
  
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.

Slot Offset Table
The slot offset table is a table of 6 or 12 bytes per record, depending on the pageSize being less or greater than 64K: 2 bytes (unsigned short) or 4 bytes (int) page offset for the record that is assigned to the slot, and 2 bytes (unsigned short) or 4 bytes (int) for the length of the record on this page. 2 bytes (unsigned short) or 4 bytes (int) for the length of the reserved number of bytes for this record on this page. First slot is slot 0. The slot table grows backwards. Slots are never left empty.
Checksum
8 bytes of a java.util.zip.CRC32 checksum of the entire's page contents without the 8 bytes representing the checksum.

Page Access The page data is accessed in this class by one of three methods.

  1. As a byte array using pageData (field in cachedPage). This is the fastest.
  2. As an ArrayInputStream (rawDataIn) and ArrayOutputStream (rawDataOut), this is used to set limits on any one reading the page logically.
  3. Logically through rawDataIn (ArrayInputStream) and logicalDataOut (FormatIdOutputStream), this provides the methods to write logical data (e.g. booleans and integers etc.) and the ObjectInput and ObjectOutput interfaces for DataValueDescriptor's. These logical streams are constructed using the array streams.

See Also:
CRC32, ArrayInputStream, ArrayOutputStream

Field Summary
(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_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 an 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.
 
Fields inherited from class org.apache.derby.impl.store.raw.data.CachedPage
alreadyReadPage, containerCache, dataFactory, initialRowCount, isDirty, PAGE_FORMAT_ID_SIZE, pageCache, pageData, preDirty, WRITE_NO_SYNC, WRITE_SYNC
 
Fields inherited from class org.apache.derby.impl.store.raw.data.BasePage
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
 
Fields inherited from interface org.apache.derby.iapi.store.raw.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 Summary
StoredPage()
          Simple no-arg constructor for StoredPage.
 
Method Summary
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 the row on this page has reserved space that can be shrunk once the update commits.
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.
 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
 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.
 
Methods inherited from class org.apache.derby.impl.store.raw.data.CachedPage
clean, clearIdentity, createIdentity, getPageArray, isActuallyDirty, isDirty, preDirty, setContainerRowCount, setDirty, setFactory, setIdentity, setPageArray
 
Methods inherited from class org.apache.derby.impl.store.raw.data.BasePage
bumpPageVersion, bumpRecordCount, cleanPageForReuse, clearLastLogInstant, compactRecord, copyAndPurge, deallocatePage, deleteAtSlot, fetchFieldFromSlot, fetchFromSlot, fetchNumFields, fillInIdentity, findRecordById, getAuxObject, getHeaderAtSlot, getIdentity, getInvalidRecordHandle, getLastLogInstant, getNextSlotNumber, getPageId, 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
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface org.apache.derby.iapi.services.cache.Cacheable
getIdentity
 

Field Detail

FORMAT_NUMBER

public static final int FORMAT_NUMBER
static final Fields of the class

See Also:
Constant Field Values

PAGE_HEADER_OFFSET

protected static final int PAGE_HEADER_OFFSET
Start of page, formatId must fit in 4 bytes.

where the page header starts - page format is mandated by cached page

See Also:
Constant Field Values

PAGE_HEADER_SIZE

protected static final int PAGE_HEADER_SIZE
Fixed size of the page header

See Also:
Constant Field Values

RECORD_SPACE_OFFSET

protected static final int RECORD_SPACE_OFFSET
Start of the record storage area.

Note: a subclass may change the start of the record storage area. Don't always count on this number.

See Also:
Constant Field Values

PAGE_VERSION_OFFSET

protected static final int PAGE_VERSION_OFFSET
offset of the page version number

See Also:
Constant Field Values

SMALL_SLOT_SIZE

protected static final int SMALL_SLOT_SIZE
SMALL_SLOT_SIZE are for pages smaller than 64K, LARGE_SLOT_SIZE is for pages bigger than 64K.

See Also:
Constant Field Values

LARGE_SLOT_SIZE

protected static final int LARGE_SLOT_SIZE
See Also:
Constant Field Values

CHECKSUM_SIZE

protected static final int CHECKSUM_SIZE
Size of the checksum stored on the page. The checksum is stored in the last 8 bytes of the page, the slot table grows backward up the page starting at the end of the page just before the checksum.

See Also:
Constant Field Values

OVERFLOW_POINTER_SIZE

protected static final 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. The pointer then points to another page where the next column of the row can be found. The overflow pointer can be bigger than a row, so when overflowing a row the code must overflow enough columns so that there is enough free space to write the row. Note this means that the minimum space a row can take on a page must allow for at least the size of the overflow pointers so that if the row is updated it can write the over flow pointer.

See Also:
Constant Field Values

OVERFLOW_PTR_FIELD_SIZE

protected static final int OVERFLOW_PTR_FIELD_SIZE
OVERFLOW_PTR_FIELD_SIZE - Number of bytes of an overflow field This is the length to reserve for either an column or row overflow pointer field. It includes the size of the field header plus the maxium length of the overflow pointer (it could be shorter due to compressed storage). The calcualtion is: OVERFLOW_PTR_FIELD_SIZE = OVERFLOW_POINTER_SIZE + sizeof(status byte) + sizeof(field length field for a field which is just an overflow ptr)

See Also:
Constant Field Values

bh

ByteHolder bh
In memory buffer used as scratch space for streaming columns.


COLUMN_NONE

protected static final int COLUMN_NONE
Constants used in call to logColumn.

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.

See Also:
Constant Field Values

COLUMN_FIRST

protected static final int COLUMN_FIRST
See Also:
Constant Field Values

COLUMN_LONG

protected static final int COLUMN_LONG
See Also:
Constant Field Values

maxFieldSize

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. See initSpace(). maxFieldSize is a worst case calculation for the size of a record This is used as the threshold for a long column. maxFieldSize = totalSpace - slotEntrySize - 16 - OVERFLOW_POINTER_SIZE;


isOverflowPage

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.(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.


slotsInUse

private int slotsInUse

nextId

private int nextId

generation

private int generation

prevGeneration

private int prevGeneration

bipLocation

private long bipLocation

deletedRowCount

private int deletedRowCount

headerOutOfDate

private boolean headerOutOfDate
Is the header in the byte array out of date wrt the fields.

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)


checksum

private java.util.zip.CRC32 checksum
holder for the checksum.


minimumRecordSize

protected int minimumRecordSize
Minimum space to reserve for record portion length of row.

minimumRecordSize is stored in the container handle. It is used to reserved 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.


userRowSize

private int userRowSize
scratch variable used to keep track of the total user size for the row. the information is used by logRow to maintain minimumRecordSize on Page. minimumRecordSize is only considered for main data pages, therefore, the page must be latched during an insert operation.


slotFieldSize

private int slotFieldSize
slot field and slot entry size.

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.


slotEntrySize

private int slotEntrySize

slotTableOffsetToFirstEntry

private int slotTableOffsetToFirstEntry
Offset of the first entry in the slot table.

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)


slotTableOffsetToFirstRecordLengthField

private int slotTableOffsetToFirstRecordLengthField
Offset of the record length entry in the 1st slot table entry.

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)


slotTableOffsetToFirstReservedSpaceField

private int slotTableOffsetToFirstReservedSpaceField
Offset of the reserved space length entry in the 1st slot table entry.

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)


totalSpace

protected int totalSpace
total usable space on a page.

This is the space not taken by page hdr, page table, and existing slot entries/rows.


freeSpace

protected int freeSpace

firstFreeByte

private int firstFreeByte

spareSpace

protected int spareSpace
% of page to keep free for updates.

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.


overflowRecordHeader

private StoredRecordHeader overflowRecordHeader
Scratch variable used when you need a overflowRecordHeader. Declared globally so that object is only allocated once per page.


rawDataIn

protected ArrayInputStream rawDataIn
Input streams used to read/write bytes to/from the page byte array.


rawDataOut

protected ArrayOutputStream rawDataOut

logicalDataOut

protected FormatIdOutputStream logicalDataOut
Constructor Detail

StoredPage

public StoredPage()
Simple no-arg constructor for StoredPage.

Method Detail

getTypeFormatId

public int getTypeFormatId()
Return my format identifier.

Returns:
The identifier. (A UUID stuffed in an array of 16 bytes).

getOverFlowRecordHeader

private StoredRecordHeader getOverFlowRecordHeader()
                                            throws StandardException
get scratch space for over flow record header.

Throws:
StandardException - Standard exception policy.

initialize

protected void initialize()
Initialize the StoredPage.

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.

Overrides:
initialize in class CachedPage

createOutStreams

private void createOutStreams()
Create the output streams.

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.

Throws:
StandardException - Standard exception policy.

setOutputStream

private void setOutputStream(java.io.OutputStream out)
Tie the logical output stream to a passed in OutputStream.

Tie the logical output stream to a passed in OutputStream with no limit as to the number of bytes that can be written.


resetOutputStream

private void resetOutputStream()
Reset the logical output stream.

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.


usePageBuffer

protected void usePageBuffer(byte[] pageBuffer)
use this passed in page buffer as this object's page data.

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)

Specified by:
usePageBuffer in class CachedPage
Parameters:
pageBuffer - The array of bytes to use as the page buffer.

calculateSlotFieldSize

private int calculateSlotFieldSize(int pageSize)
Calculate the slot field size from the page size.

Parameters:
pageSize - page size in bytes
Returns:
slot field size in bytes

createPage

protected void createPage(PageKey newIdentity,
                          PageCreationArgs args)
                   throws StandardException
Create a new StoredPage.

Make this object represent a new page (ie. a page that never existed before, as opposed to reading in an existing page from disk).

Specified by:
createPage in class CachedPage
Parameters:
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.
Throws:
StandardException - Standard exception policy.

initFromData

protected void initFromData(FileContainer myContainer,
                            PageKey newIdentity)
                     throws StandardException
Initialize the page from values in the page buffer.

Initialize in memory structure using the buffer in pageData. This is how a StoredPage object is intialized to represent page read in from disk.

Specified by:
initFromData in class CachedPage
Parameters:
myContainer - The container to read the page in from.
newIdentity - The key representing page being read in (segment, container, page number)
Throws:
StandardException - If the page cannot be read correctly, or is inconsistent.

validateChecksum

protected void validateChecksum(PageKey id)
                         throws StandardException
Validate the check sum on the page.

Compare the check sum stored in the page on disk with the checksum calculated from the bytes on the page.

Parameters:
id - The key that describes the page.
Throws:
StandardException - Standard exception policy.

updateChecksum

protected void updateChecksum()
                       throws java.io.IOException
Recalculate checksum and write it to the page array.

Recalculate the checksum of the page, and write the result back into the last bytes of the page.

Throws:
java.io.IOException - if writing to end of array fails.

writePage

protected void writePage(PageKey identity)
                  throws StandardException
Write information about page from variables into page byte array.

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.

Specified by:
writePage in class CachedPage
Parameters:
identity - The key of this page.
Throws:
StandardException - Standard exception policy.

writeFormatId

protected void writeFormatId(PageKey identity)
                      throws StandardException
Write out the format id of this page

Specified by:
writeFormatId in class CachedPage
Parameters:
identity - The key of this page.
Throws:
StandardException - Standard exception policy.

releaseExclusive

protected void releaseExclusive()
Ensure that the page is released from the cache when it is unlatched.

Overrides:
releaseExclusive in class CachedPage
See Also:
BasePage.releaseExclusive()

getTotalSpace

public int getTotalSpace(int slot)
                  throws StandardException
Return the total number of bytes used, reserved, or wasted by the record at this slot.

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

Specified by:
getTotalSpace in class BasePage
Parameters:
slot - look at row at this slot.
Returns:
The number of bytes used by the row at slot "slot".
Throws:
StandardException - Standard exception policy.

spaceForInsert

public boolean spaceForInsert()
                       throws StandardException
Is there minimal space for insert?

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.

Returns:
true if we think the page will allow an insert, false otherwise.
Throws:
StandardException - Standard exception policy.

spaceForInsert

public boolean spaceForInsert(java.lang.Object[] row,
                              FormatableBitSet validColumns,
                              int overflowThreshold)
                       throws StandardException
Is row guaranteed to be inserted successfully on this page?

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.

Parameters:
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).
Returns:
bolean indicating if row can be inserted on this page.
Throws:
StandardException - Standard exception policy.

spaceForInsert

private boolean spaceForInsert(java.lang.Object[] row,
                               FormatableBitSet validColumns,
                               int spaceNeeded,
                               int startColumn,
                               int overflowThreshold)
                        throws StandardException
Is row guaranteed to be inserted successfully on this page?

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.

Parameters:
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).
Returns:
bolean indicating if row can be inserted on this page.
Throws:
StandardException - Standard exception policy.

unfilled

public boolean unfilled()
Is this page 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.

Specified by:
unfilled in class BasePage
Returns:
true if page is relatively unfilled.

allowInsert

public boolean allowInsert()
Is there enough space on the page to insert a minimum size row?

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.

Specified by:
allowInsert in class BasePage
Returns:
boolean indicating if a minimum sized row can be inserted.

spaceForCopy

public boolean spaceForCopy(int num_rows,
                            int[] spaceNeeded)
Does this page have enough space to insert the input rows?

Can the rows with lengths spaceNeeded[0..num_rows-1] be copied onto this page?

Specified by:
spaceForCopy in class BasePage
Parameters:
num_rows - number of rows to check for.
spaceNeeded - array of lengths of the rows to insert.
Returns:
true if the sum of the lengths will fit on the page.

spaceForCopy

protected boolean spaceForCopy(int spaceNeeded,
                               int source_id)
Does this page have enough space to move the row to it.

Calculate if a row of length "spaceNeeded" with current record id "source_id" will fit on this page.

Parameters:
spaceNeeded - length of the row encoded with source_id record id.
source_id - record id of the row being moved.
Returns:
true if the record will fit on this page, after being given a new record id as the next id on this page.
Throws:
StandardException - Standard exception policy.

restoreRecordFromSlot

protected boolean restoreRecordFromSlot(int slot,
                                        java.lang.Object[] row,
                                        FetchDescriptor fetchDesc,
                                        RecordHandle recordToLock,
                                        StoredRecordHeader recordHeader,
                                        boolean isHeadRow)
                                 throws StandardException
Read the record at the given slot into the given row.

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.

Specified by:
restoreRecordFromSlot in class BasePage
Parameters:
slot - the slot number
row - (out) filled in sparse row
fetchDesc - 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.
Returns:
false if a qualifier_list is provided and the row does not qualifier (no row read in that case), else true.
Throws:
StandardException - Standard Derby error policy

restoreLongRecordFromSlot

private StoredRecordHeader restoreLongRecordFromSlot(java.lang.Object[] row,
                                                     FetchDescriptor fetchDesc,
                                                     RecordHandle recordToLock,
                                                     StoredRecordHeader parent_recordHeader)
                                              throws StandardException
Throws:
StandardException

newRecordId

public int newRecordId()
Create a new record handle.

Return the next record id for allocation. Callers of this interface expect the next id to get bumped some where else - probably by storeRecordForInsert().

Specified by:
newRecordId in class BasePage
Returns:
The next id to assing to a row.

newRecordIdAndBump

public int newRecordIdAndBump()
Create a new record handle, and bump the id.

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.

Specified by:
newRecordIdAndBump in class BasePage
Returns:
The next id to assing to a row.

newRecordId

protected int newRecordId(int recordId)
Create a new record id based on current one passed in.

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.

Specified by:
newRecordId in class BasePage
Parameters:
recordId - The id caller just used, return the next one.
Returns:
the next id based on the input id.

isOverflowPage

public boolean isOverflowPage()
Description copied from class: BasePage
Return true if the page is an overflow page, false if not. For implementation that don't have overflow pages, return false.

Specified by:
isOverflowPage in class BasePage

getPageSize

public final int getPageSize()
Get the full size of the page.


clearSection

protected final void clearSection(int offset,
                                  int length)
Zero out a portion of the page.

Parameters:
offset - position of first byte to clear
length - how many bytes to clear

getMaxFreeSpace

protected int getMaxFreeSpace()
The maximum free space on this page possible.

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

Returns:
the maximum free space on this page possible.

getCurrentFreeSpace

protected int getCurrentFreeSpace()
The current free space on the page.


readPageHeader

private void readPageHeader()
                     throws java.io.IOException
Read the page header from the page array.

Read the page header from byte form in the page array into in memory variables.

Throws:
java.io.IOException

updatePageHeader

private void updatePageHeader()
                       throws java.io.IOException
Update the page header in the page array.

Write the bytes of the page header, taking the values from those in the in memory variables.

Throws:
java.io.IOException

updatePageVersion

private void updatePageVersion()
                        throws java.io.IOException
Update the page version number in the byte array

Throws:
java.io.IOException

getSlotOffset

private int getSlotOffset(int slot)
Get the page offset of a given slot entry.

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.

Parameters:
slot - The array entry of the slot to find.
Returns:
The page offset of a given slot entry.

getRecordOffset

private int getRecordOffset(int slot)
Get the page offset of the record associated with the input slot.

This is the actual offset on the page of the beginning of the record.

Parameters:
slot - The array entry of the slot to find.
Returns:
The page offset of the record associated with the input slot.

setRecordOffset

private void setRecordOffset(int slot,
                             int recordOffset)
                      throws java.io.IOException
Set the page offset of the record associated with the input slot.

This is the actual offset on the page of the beginning of the record.

Parameters:
slot - The array entry of the slot to set.
recordOffset - the new offset to set.
Throws:
java.io.IOException

getRecordPortionLength

protected int getRecordPortionLength(int slot)
                              throws java.io.IOException
Return length of row on this page.

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.

Parameters:
slot - the slot of the row to look up the length of.
Returns:
The length of the row on this page.
Throws:
java.io.IOException

getReservedCount

public int getReservedCount(int slot)
                     throws java.io.IOException
Return reserved length of row on this page.

Return the reserved length of this record. This length is stored as the third "field" of the slot table entry.

Specified by:
getReservedCount in class BasePage
Parameters:
slot - the slot of the row to look up the length of.
Returns:
The reserved length of the row on this page.
Throws:
java.io.IOException - Thrown by InputStream methods potential I/O errors

updateRecordPortionLength

private void updateRecordPortionLength(int slot,
                                       int delta,
                                       int reservedDelta)
                                throws java.io.IOException
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". 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."

Parameters:
slot - the slot of the record to set.
delta - The amount the record length changed.
reservedDelta - The amount the reserved length changed.
Throws:
StandardException - Standard exception policy.
java.io.IOException

initSlotTable

private void initSlotTable(PageKey newIdentity)
                    throws StandardException
Initialize the in-memory slot table.

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.

Parameters:
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()).
Throws:
StandardException - Standard exception policy.

setSlotEntry

private void setSlotEntry(int slot,
                          int recordOffset,
                          int recordPortionLength,
                          int reservedSpace)
                   throws java.io.IOException
Set up a new slot entry.

Parameters:
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.
Throws:
StandardException - Standard exception policy.
java.io.IOException

addSlotEntry

private void addSlotEntry(int slot,
                          int recordOffset,
                          int recordPortionLength,
                          int reservedSpace)
                   throws java.io.IOException
Insert a new slot entry into the current slot array.

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.

Parameters:
slot - Position the new slot will take
recordOffset - Offset of the record for the new slot
recordPortionLength - Length of the record stored in the new slot
reservedSpace - Length of reserved space of record in slot
Throws:
java.io.IOException

removeSlotEntry

private void removeSlotEntry(int slot)
                      throws java.io.IOException
Remove slot entry from slot array.

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)

Parameters:
slot - The slot to delete.
Throws:
java.io.IOException

recordHeaderOnDemand

public StoredRecordHeader recordHeaderOnDemand(int slot)
create the record header for the specific 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.

Specified by:
recordHeaderOnDemand in class BasePage
Parameters:
slot - return record header of this slot.
Returns:
The record header for the specific slot.
Throws:
StandardException - Standard exception policy.

entireRecordOnPage

public boolean entireRecordOnPage(int slot)
                           throws StandardException
Is entire record on the page?

Specified by:
entireRecordOnPage in class BasePage
Parameters:
slot - Check record at this slot.
Returns:
true if the entire record at slot is on this page, i.e, no overflow row or long columns.
Throws:
StandardException - Standard exception policy.

purgeOverflowAtSlot

protected void purgeOverflowAtSlot(int slot,
                                   RecordHandle headRowHandle,
                                   boolean needDataLogged)
                            throws StandardException
Purge one row on an overflow page.

HeadRowHandle is the recordHandle pointing to the head row piece.

Parameters:
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.
Throws:
StandardException - Standard exception policy.

purgeOneColumnChain

private void purgeOneColumnChain(long overflowPageId,
                                 int overflowRecordId)
                          throws StandardException
Purge the column chain that starts at overflowPageId, overflowRecordId

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.

Parameters:
overflowPageId - The page where the long column chain starts.
overflowRecordId - The record id where long column chain starts.
Throws:
StandardException - Standard exception policy.

purgeColumnChains

private void purgeColumnChains(RawTransaction t,
                               int slot,
                               RecordHandle headRowHandle)
                        throws StandardException
purge long columns chains which eminate from this page.

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.

Parameters:
t - The raw transaction doing the purging.
slot - The slot of the row to purge.
headRowHandle - The RecordHandle of the head row.
Throws:
StandardException - Standard exception policy.

purgeRowPieces

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.

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.

Specified by:
purgeRowPieces in class BasePage
Parameters:
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.
Throws:
StandardException - Standard exception policy.

removeOrphanedColumnChain

void removeOrphanedColumnChain(ReclaimSpace work,
                               ContainerHandle containerHdl)
                         throws StandardException
Remove a column chain that may have been orphaned by an update.

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.

Parameters:
work - object describing the chain to remove.
containerHdl - open container handle to use to remove chain.
Throws:
StandardException - Standard exception policy.

isColumnOrphaned

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.

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.

Parameters:
recordHeader - record header which used to point at the long column
columnId - 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.
Returns:
true if page no longer points to the long column chain.
Throws:
StandardException - Standard exception policy.
java.io.IOException

getNextColumnPiece

private RecordHandle getNextColumnPiece(int slot)
                                 throws StandardException
Return the next recordHandle in a long column chain.

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.

Parameters:
slot - The slot of the current long column piece.
Returns:
The next record handle in a long column chain.
Throws:
StandardException - Standard exception policy.

initSpace

private void initSpace()
initialize the in memory variables associated with space maintenance.

Get the total available space on an empty page. initSlotTable() must be called after the page has been read in.


clearAllSpace

private void clearAllSpace()
Initialize the freeSpace count and set the firstFreeByte on page


compressPage

private void compressPage(int startByte,
                          int endByte)
                   throws java.io.IOException
Compress out the space specified by startByte and endByte.

As part of moving rows, updating rows, purging rows compact the space left between rows.

Parameters:
startByte - compress out space starting at startByte offset
endByte - compress out space ending at endByte offset
Throws:
java.io.IOException

expandPage

protected void expandPage(int startOffset,
                          int requiredBytes)
                   throws java.io.IOException
Free up required bytes by shifting rows "down" the page.

Expand page, move all the data from start Offset down the page by the amount required to free up the required bytes.

Parameters:
startOffset - offset on page to begin the shift
requiredBytes - the number of bytes that must be freed.
Throws:
java.io.IOException - If IOException is raised during the page mod.

shrinkPage

private void shrinkPage(int startOffset,
                        int shrinkBytes)
                 throws java.io.IOException
Shrink page.

move all the data from start Offset up the page by the amount shrunk.

Parameters:
startOffset - offset on page to begin the shift
shrinkBytes - the number of bytes that must be moved.
Throws:
java.io.IOException - some IOException is raised during the page mod, (unlikely as this is just writing to array).

getRecordLength

public int getRecordLength(int slot)
                    throws java.io.IOException
Description copied from class: BasePage
Get the stored length of a record. This must match the amount of data written by logColumn and logField.
MT - latched - page latch must be held

Specified by:
getRecordLength in class BasePage
Throws:
java.io.IOException

getIsOverflow

protected boolean getIsOverflow(int slot)
                         throws java.io.IOException
Throws:
java.io.IOException

logRow

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
Log a row into the StoreOuput stream.

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.

Specified by:
logRow in class BasePage
Parameters:
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.
Returns:
the "realStartColumn" value, -1 if not a long row.
Throws:
java.io.IOException - RESOLVE
StandardException - Standard exception policy.
See Also:
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)

handleIncompleteLogRow

private void handleIncompleteLogRow(int slot,
                                    int startColumn,
                                    FormatableBitSet columnList,
                                    DynamicByteArrayOutputStream out)
                             throws StandardException
Handle an update of a record portion that is incomplete.

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.

Parameters:
slot - slot of the current update.
startColumn - column to start at, handles start in middle of row
columnList - bit map indicating which columns are being updated.
out - place to lot to.
Throws:
StandardException - Standard exception policy.

restoreRecordFromStream

public void restoreRecordFromStream(LimitObjectInput in,
                                    java.lang.Object[] row)
                             throws StandardException,
                                    java.io.IOException
Restore a storable row from a LimitInputStream.

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.

Specified by:
restoreRecordFromStream in class BasePage
Parameters:
in - the limit input stream
row - (IN/OUT) row that is to be restored (sparse representation)
Throws:
StandardException - Standard exception policy.
java.io.IOException - object exceeds the available data in the stream.

qualifyRecordFromRow

private boolean qualifyRecordFromRow(java.lang.Object[] row,
                                     Qualifier[][] qual_list)
                              throws StandardException
Process the qualifier list on the row, return true if it qualifies.

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])

Parameters:
row - The row being qualified.
qual_list - 2 dimensional array representing conjunctive normal form of simple qualifiers.
Returns:
true if the row qualifies.
Throws:
StandardException - Standard exception policy.

readOneColumnFromPage

private final void readOneColumnFromPage(java.lang.Object[] row,
                                         int colid,
                                         int offset_to_field_data,
                                         StoredRecordHeader recordHeader,
                                         RecordHandle recordToLock)
                                  throws StandardException,
                                         java.io.IOException
Read just one column from stream into row.

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].

Parameters:
row - col is read into object in row[qual_colid].
offset_to_field_data - offset in bytes from top of page to field
colid - 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.
Throws:
StandardException - Standard exception policy.
java.io.IOException

qualifyRecordFromSlot

private final boolean qualifyRecordFromSlot(java.lang.Object[] row,
                                            int offset_to_row_data,
                                            FetchDescriptor fetchDesc,
                                            StoredRecordHeader recordHeader,
                                            RecordHandle recordToLock)
                                     throws StandardException,
                                            java.io.IOException
Process the list of qualifiers on the row in the stream.

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])

Parameters:
row - restore row into this object array.
offset_to_row_data - offset in bytes from top of page to row
fetchDesc - 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.
Returns:
Whether or not the row input qualifies.
Throws:
StandardException - Standard exception policy.
java.io.IOException

readRecordFromStream

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
restore a record from a stream.

The rawDataIn stream is expected to be positioned after the record header.

Parameters:
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.
Returns:
The identifier to be used to open the conglomerate later.
Throws:
StandardException - Standard exception policy.
java.io.IOException

readRecordFromArray

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
Throws:
StandardException
java.io.IOException

restorePortionLongColumn

public void restorePortionLongColumn(OverflowInputStream fetchStream)
                              throws StandardException,
                                     java.io.IOException
Restore a portion of a long column.

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.

Specified by:
restorePortionLongColumn in class BasePage
Parameters:
fetchStream - the stream to read the next portion of long col from
Throws:
StandardException - Standard exception policy.
java.io.IOException

logColumn

public void logColumn(int slot,
                      int fieldId,
                      java.lang.Object column,
                      DynamicByteArrayOutputStream out,
                      int overflowThreshold)
               throws StandardException,
                      java.io.IOException
Log a Storable to a stream.

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.

Specified by:
logColumn in class BasePage
Parameters:
slot - slot of the current record
fieldId - field number of the column being updated
column - column version of the field.
out - Where to write the logged form.
Throws:
StandardException - Standard Derby error policy
java.io.IOException - RESOLVE

logLongColumn

public int logLongColumn(int slot,
                         int recordId,
                         java.lang.Object column,
                         DynamicByteArrayOutputStream out)
                  throws StandardException,
                         java.io.IOException
Log a long column into a DataOuput.

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.

Specified by:
logLongColumn in class BasePage
Parameters:
slot - slot of the row with the column
recordId - record id of the
column - the object form of the column to log
out - where to log to the column to.
Throws:
StandardException - Standard Derby error policy
java.io.IOException - I/O exception from writing to an array.
See Also:
BasePage.logColumn(int, int, java.lang.Object, org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream, int)

logColumn

private int logColumn(java.lang.Object[] row,
                      int arrayPosition,
                      DynamicByteArrayOutputStream out,
                      int spaceAvailable,
                      int columnFlag,
                      int overflowThreshold)
               throws StandardException,
                      java.io.IOException
Log column from input row to the given output stream.

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.

Parameters:
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.
Returns:
The spaceAvailable after accounting for space for this column.
Throws:
StandardException - Standard exception policy.
LongColumnException - Thrown if column will not fit on a single page. See notes above
java.io.IOException

logOverflowRecord

private int logOverflowRecord(int slot,
                              int spaceAvailable,
                              DynamicByteArrayOutputStream out)
                       throws StandardException,
                              java.io.IOException
Create and write a long row header to the log stream.

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.

Parameters:
slot - slot of record to log.
spaceAvailable - spaceAvaliable on page.
out - stream to log the record to.
Returns:
-1
Throws:
StandardException - Standard exception policy.
java.io.IOException

logOverflowField

private int logOverflowField(DynamicByteArrayOutputStream out,
                             int spaceAvailable,
                             long overflowPage,
                             int overflowId)
                      throws StandardException,
                             java.io.IOException
Throws:
StandardException
java.io.IOException

logRecord

public void logRecord(int slot,
                      int flag,
                      int recordId,
                      FormatableBitSet validColumns,
                      java.io.OutputStream out,
                      RecordHandle headRowHandle)
               throws StandardException,
                      java.io.IOException
Log a record to the ObjectOutput stream.

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.

Specified by:
logRecord in class BasePage
Parameters:
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 logged
out - Where to write the logged form.
headRowHandle - the recordHandle of the head row piece, used for post commit cleanup for update.
Throws:
StandardException - Standard Derby error policy
java.io.IOException - on error writing to log stream.
See Also:
BasePage.logRecord(int, int, int, org.apache.derby.iapi.services.io.FormatableBitSet, java.io.OutputStream, org.apache.derby.iapi.store.raw.RecordHandle)

logRecordDataPortion

private void logRecordDataPortion(int slot,
                                  int flag,
                                  StoredRecordHeader recordHeader,
                                  FormatableBitSet validColumns,
                                  java.io.OutputStream out,
                                  RecordHandle headRowHandle)
                           throws StandardException,
                                  java.io.IOException
Throws:
StandardException
java.io.IOException

logField

public void logField(int slot,
                     int fieldNumber,
                     java.io.OutputStream out)
              throws StandardException,
                     java.io.IOException
Log a field to the ObjectOutput stream.

Find the field in the record and then write out the complete field, i.e. header and data.

Specified by:
logField in class BasePage
Parameters:
slot - Slot number the record is stored in.
fieldNumber - Number of the field (starts at 0).
out - Where to write the logged form.
Throws:
StandardException - Standard Derby error policy
java.io.IOException - RESOLVE
See Also:
BasePage.logField(int, int, java.io.OutputStream)

insertAtSlot

public RecordHandle insertAtSlot(int slot,
                                 java.lang.Object[] row,
                                 FormatableBitSet validColumns,
                                 LogicalUndo undo,
                                 byte insertFlag,
                                 int overflowThreshold)
                          throws StandardException
Override insertAtSlot to provide long row support.

Specified by:
insertAtSlot in interface Page
Overrides:
insertAtSlot in class BasePage
Parameters:
slot - The specified slot
row - The row version of the data
validColumns - 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.
Returns:
A RecordHandle representing the new record, or null if the row will not fit on a non-empty page.
Throws:
StandardException - Standard Derby error policy
See Also:
Page.insertAtSlot(int, java.lang.Object[], org.apache.derby.iapi.services.io.FormatableBitSet, org.apache.derby.iapi.store.access.conglomerate.LogicalUndo, byte, int)

updateFieldAtSlot

public RecordHandle updateFieldAtSlot(int slot,
                                      int fieldId,
                                      java.lang.Object newValue,
                                      LogicalUndo undo)
                               throws StandardException
Update field at specified slot

Specified by:
updateFieldAtSlot in interface Page
Overrides:
updateFieldAtSlot in class BasePage
Parameters:
slot - is the slot number
fieldId - is the column id
newValue - has the new colum value to be stored in the record
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.
Returns:
a Handle to the updated record.
Throws:
StandardException - Standard Derby error policy
See Also:
Page.updateFieldAtSlot(int, int, java.lang.Object, org.apache.derby.iapi.store.access.conglomerate.LogicalUndo)

fetchNumFieldsAtSlot

public int fetchNumFieldsAtSlot(int slot)
                         throws StandardException
Get the number of fields on the row at slot

Specified by:
fetchNumFieldsAtSlot in interface Page
Overrides:
fetchNumFieldsAtSlot in class BasePage
Parameters:
slot - is the slot number
Returns:
the number of fields in the record
Throws:
StandardException - Standard Derby error policy
See Also:
Page.fetchNumFieldsAtSlot(int)

moveRecordForCompressAtSlot

public int moveRecordForCompressAtSlot(int slot,
                                       java.lang.Object[] row,
                                       RecordHandle[] old_handle,
                                       RecordHandle[] new_handle)
                                throws StandardException
Move record to a page toward the beginning of the file.

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.

Parameters:
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.
Returns:
the number of rows processed.
Throws:
StandardException - Standard Derby error policy
See Also:
LockingPolicy

logAction

public void logAction(LogInstant instant)
               throws StandardException
Throws:
StandardException

cleanPage

private void cleanPage()

initPage

public void initPage(LogInstant instant,
                     byte status,
                     int recordId,
                     boolean overflow,
                     boolean reuse)
              throws StandardException
Initialize the page. If reuse, then Clean up any in memory or on disk structure to ready the page for reuse. This is not only reusing the page buffer, but reusing a free page which may or may not be cleaned up the the client of raw store when it was deallocated.

Specified by:
initPage in class BasePage
Throws:
StandardException - Derby Standard Error Policy

setPageStatus

public void setPageStatus(LogInstant instant,
                          byte status)
                   throws StandardException
Set page status

Specified by:
setPageStatus in class BasePage
Parameters:
instant - the log instant of the log record
status - the page status
Throws:
StandardException - Derby Standard Error Policy

setReservedSpace

public void setReservedSpace(LogInstant instant,
                             int slot,
                             int value)
                      throws StandardException,
                             java.io.IOException
Set the row reserved space.

Specified by:
setReservedSpace in class BasePage
Throws:
StandardException - Derby Standard Error Policy
java.io.IOException

storeRecord

public void storeRecord(LogInstant instant,
                        int slot,
                        boolean insert,
                        java.io.ObjectInput in)
                 throws StandardException,
                        java.io.IOException
Store a record at the given slot.

Specified by:
storeRecord in class BasePage
Throws:
StandardException - Standard Derby error policy
java.io.IOException - RESOLVE

storeRecordForInsert

private void storeRecordForInsert(int slot,
                                  java.io.ObjectInput in)
                           throws StandardException,
                                  java.io.IOException
Throws:
StandardException
java.io.IOException

storeRecordForUpdate

private void storeRecordForUpdate(int slot,
                                  java.io.ObjectInput in)
                           throws StandardException,
                                  java.io.IOException
Throws:
StandardException
java.io.IOException

moveSavedDataToPage

private int moveSavedDataToPage(DynamicByteArrayOutputStream savedData,
                                int unusedSpace,
                                int pageOffset)

createSpaceForUpdate

private void createSpaceForUpdate(int slot,
                                  int offset,
                                  int oldLength,
                                  int newLength)
                           throws StandardException,
                                  java.io.IOException
Create the space to update a portion of a record. This method ensures there is enough room to replace the old data of length oldLength at the given offset, with the new data of length newLength. This method does put any new data on the page, it moves old data around and zeros out any old data when newLength < oldLength. This method does update the information in the slot table. The passed in offset is the correct place to put the data when this method returns, ie. it only moves data that has an offset greater then this.

Throws:
StandardException - Standard Derby error policy
java.io.IOException - RESOLVE

storeField

public void storeField(LogInstant instant,
                       int slot,
                       int fieldNumber,
                       java.io.ObjectInput in)
                throws StandardException,
                       java.io.IOException
storeField

Specified by:
storeField in class BasePage
Throws:
StandardException - Standard Derby error policy
java.io.IOException - RESOLVE

reserveSpaceForSlot

public void reserveSpaceForSlot(LogInstant instant,
                                int slot,
                                int spaceToReserve)
                         throws StandardException,
                                java.io.IOException
reserveSpaceForSlot This method will reserve at least specified "spaceToReserve" bytes for the record in the slot.

Specified by:
reserveSpaceForSlot in class BasePage
Throws:
StandardException - Standard Derby error policy
java.io.IOException - RESOLVE

skipField

public void skipField(java.io.ObjectInput in)
               throws java.io.IOException
Skip a field header and its data on the given stream.

Specified by:
skipField in class BasePage
Throws:
java.io.IOException - corrupt stream

skipRecord

public void skipRecord(java.io.ObjectInput in)
                throws java.io.IOException
Specified by:
skipRecord in class BasePage
Throws:
java.io.IOException

shiftRemainingData

private int shiftRemainingData(int slot,
                               int offset,
                               int oldLength,
                               int newLength)
                        throws java.io.IOException
Shift data within a record to account for an update.

Parameters:
offset - Offset where the update starts, need not be on a field boundry.
oldLength - length of the data being replaced
newLength - length of the data replacing the old data
Returns:
the length of the data in the record after the replaced data.
Throws:
java.io.IOException

setDeleteStatus

public void setDeleteStatus(LogInstant instant,
                            int slot,
                            boolean delete)
                     throws StandardException,
                            java.io.IOException
Set the deleted status

Specified by:
setDeleteStatus in class BasePage
slot - the slot to delete or undelete
delete - set delete status to this value
Throws:
StandardException - Standard Derby error policy
java.io.IOException - RESOLVE
See Also:
BasePage.setDeleteStatus(int, boolean)

internalDeletedRecordCount

protected int internalDeletedRecordCount()
get record count without checking for latch

Specified by:
internalDeletedRecordCount in class BasePage

purgeRecord

public void purgeRecord(LogInstant instant,
                        int slot,
                        int recordId)
                 throws StandardException,
                        java.io.IOException
purgeRecord from page. Move following slots up by one.

Specified by:
purgeRecord in class BasePage
slot - the slot to purge
recordId - the id of the record that is to be purged
Throws:
StandardException - Standard Derby error policy
java.io.IOException - RESOLVE

getFieldOffset

private int getFieldOffset(int slot,
                           int fieldNumber)
                    throws java.io.IOException
Get the offset of the field header of the given field for the record in the given slot. Field number is the absolute number for the complete record, not just this portion. E.g. if this is a record portion that starts at field 3 and has 6 fields then the second field on this *page* has field number 4.

Throws:
java.io.IOException

currentTimeStamp

public PageTimeStamp currentTimeStamp()
Get a time stamp for this page

Returns:
page time stamp

setTimeStamp

public void setTimeStamp(PageTimeStamp ts)
                  throws StandardException
Set given pageVersion to be the as what is on this page

Throws:
StandardException - given time stamp is null or is not a time stamp implementation this page knows how to deal with

equalTimeStamp

public boolean equalTimeStamp(PageTimeStamp ts)
                       throws StandardException
compare given PageVersion with pageVersion on page

Parameters:
ts - the page version gotton from this page via a currentTimeStamp or setTimeStamp call earlier
Returns:
true if the same
Throws:
StandardException - given time stamp not gotton from this page
See Also:
PageTimeStamp

toString

public java.lang.String toString()
debugging, print this page

Overrides:
toString in class java.lang.Object

pagedataToHexDump

private static java.lang.String pagedataToHexDump(byte[] data)
Provide a hex dump of the data in the in memory version of the page.

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 ................

Parameters:
data - array of bytes to dump.
Returns:
The string with the hex dump in it.

pageHeaderToString

private java.lang.String pageHeaderToString()

recordToString

private java.lang.String recordToString(int slot)

getOverflowPage

protected StoredPage getOverflowPage(long pageNumber)
                              throws StandardException
Get the overflow page for a record that has already overflowed.

Throws:
StandardException - Standard Derby error policy

getNewOverflowPage

protected BasePage getNewOverflowPage()
                               throws StandardException
Get an empty overflow page.

Specified by:
getNewOverflowPage in class BasePage
Throws:
StandardException - Standard Derby error policy

getOverflowSlot

protected static int getOverflowSlot(BasePage overflowPage,
                                     StoredRecordHeader recordHeader)
                              throws StandardException
Get the overflow slot for a record that has already overflowed.

Throws:
StandardException - Standard Derby error policy

getOverflowPageForInsert

public BasePage getOverflowPageForInsert(int currentSlot,
                                         java.lang.Object[] row,
                                         FormatableBitSet validColumns)
                                  throws StandardException
Get a overflow page that potentially can handle a new overflowed record.

Throws:
StandardException - Standard Derby error policy

getOverflowPageForInsert

public BasePage getOverflowPageForInsert(int currentSlot,
                                         java.lang.Object[] row,
                                         FormatableBitSet validColumns,
                                         int startColumn)
                                  throws StandardException
Specified by:
getOverflowPageForInsert in class BasePage
Throws:
StandardException - Standard Derby error policy

updateOverflowed

protected void updateOverflowed(RawTransaction t,
                                int slot,
                                java.lang.Object[] row,
                                FormatableBitSet validColumns,
                                StoredRecordHeader recordHeader)
                         throws StandardException
Update an already overflowed record.

Parameters:
slot - Slot of the original record on its original page
row - new version of the data
Throws:
StandardException - Standard Derby error policy

updateOverflowDetails

public void updateOverflowDetails(RecordHandle handle,
                                  RecordHandle overflowHandle)
                           throws StandardException
Update a record handle to point to an overflowed record portion. Note that the record handle need not be the current page.

Specified by:
updateOverflowDetails in class BasePage
Parameters:
handle - handle of the record for long row
overflowHandle - the overflow (continuation) pointer for the long row
Throws:
StandardException - Standard Derby error policy

updateOverflowDetails

private void updateOverflowDetails(StoredPage handlePage,
                                   RecordHandle handle,
                                   RecordHandle overflowHandle)
                            throws StandardException
Throws:
StandardException

updateFieldOverflowDetails

public void updateFieldOverflowDetails(RecordHandle handle,
                                       RecordHandle overflowHandle)
                                throws StandardException
Description copied from class: BasePage
Update the overflow pointer for a long column
MT - latched - page latch must be held

Specified by:
updateFieldOverflowDetails in class BasePage
Parameters:
handle - handle of the record for long row
overflowHandle - the overflow (continuation) pointer for the long row
Throws:
StandardException - Standard Derby error policy

appendOverflowFieldHeader

public int appendOverflowFieldHeader(DynamicByteArrayOutputStream logBuffer,
                                     RecordHandle overflowHandle)
                              throws StandardException,
                                     java.io.IOException
Description copied from class: BasePage
Append an overflow pointer to a partly logged row, to point to a long column that just been logged.
MT - latched - page latch must be held

Specified by:
appendOverflowFieldHeader in class BasePage
Parameters:
logBuffer - The buffer that contains the partially logged row.
overflowHandle - the overflow (continuation) pointer to the beginning of the long column
Throws:
StandardException - Standard Derby error policy
java.io.IOException

getSlotsInUse

protected int getSlotsInUse()

getMaxDataLength

private int getMaxDataLength(int spaceAvailable,
                             int overflowThreshold)
return the max datalength allowed with the space available


isLong

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


doUpdateAtSlot

public void doUpdateAtSlot(RawTransaction t,
                           int slot,
                           int id,
                           java.lang.Object[] row,
                           FormatableBitSet validColumns)
                    throws StandardException
Perform an update.

Specified by:
doUpdateAtSlot in class BasePage
Throws:
StandardException - Standard Derby policy

checkRowReservedSpace

private boolean checkRowReservedSpace(int slot)
                               throws StandardException
See if the row on this page has reserved space that can be shrunk once the update commits.

Throws:
StandardException

compactRecord

protected void compactRecord(RawTransaction t,
                             int slot,
                             int id)
                      throws StandardException
Description copied from class: BasePage
Subclass implementation of compactRecord.

Specified by:
compactRecord in class BasePage
Throws:
StandardException - Standard Derby error policy
See Also:
BasePage.compactRecord(org.apache.derby.iapi.store.raw.RecordHandle)

Built on Thu 2011-03-10 11:54:14+0000, from revision ???

Apache Derby V10.6 Internals - Copyright © 2004,2007 The Apache Software Foundation. All Rights Reserved.