📄 storedpage.java
字号:
{ if (fetchDesc.getQualifierList() != null) { fetchDesc.reset(); } readRecordFromArray( row, (fetchDesc.getValidColumns() == null) ? row.length - 1 : fetchDesc.getMaxFetchColumnId(), fetchDesc.getValidColumnsArray(), fetchDesc.getMaterializedColumns(), lrdi, recordHeader, (ErrorObjectInput) null /* always null */, recordToLock); } else { readRecordFromArray( row, row.length - 1, (int[]) null, (int[]) null, lrdi, recordHeader, (ErrorObjectInput) null /* always null */, recordToLock); } // call routine to loop through all the overflow portions of // the row, reading it into "row". while (recordHeader != null) { // The record is a long row, loop callng code to read the // pieces of the row located in a linked list of rows on // overflow pages. StoredPage overflowPage = getOverflowPage(recordHeader.getOverflowPage()); if (SanityManager.DEBUG) { if (overflowPage == null) SanityManager.THROWASSERT( "cannot get overflow page"); } // This call reads in the columns of the row that reside // on "overflowPage", and if there is another piece it // returns the recordHeader of the row on overFlowPage, // from which we can find the next piece of the row. A // null return means that we have read in the entire row, // and are done. recordHeader = overflowPage.restoreLongRecordFromSlot( row, fetchDesc, recordToLock, recordHeader); overflowPage.unlatch(); overflowPage = null; } // for overflow rows just apply qualifiers at end for now. if ((fetchDesc != null) && (fetchDesc.getQualifierList() != null)) { if (!qualifyRecordFromRow( row, fetchDesc.getQualifierList())) { return(false); } } return(true); } } catch (IOException ioe) { if (SanityManager.DEBUG) { if (pageData == null) { SanityManager.DEBUG_PRINT("DEBUG_TRACE", "caught an IOException in restoreRecordFromSlot " + (PageKey)getIdentity() + " slot " + slot + ", pageData is null"); } else { SanityManager.DEBUG_PRINT("DEBUG_TRACE", "caught an IOException in reestoreRecordFromSlot, " + (PageKey)getIdentity() + " slot " + slot + ", pageData.length = " + pageData.length + " pageSize = " + getPageSize()); SanityManager.DEBUG_PRINT("DEBUG_TRACE", "Hex dump of pageData \n " + "--------------------------------------------------\n" + pagedataToHexDump(pageData) + "--------------------------------------------------\n"); SanityManager.DEBUG_PRINT("DEBUG_TRACE", "Attempt to dump page " + this.toString()); } } // i/o methods on the byte array have thrown an IOException throw dataFactory.markCorrupt( StandardException.newException( SQLState.DATA_CORRUPT_PAGE, ioe, getPageId())); } } private StoredRecordHeader restoreLongRecordFromSlot( Object[] row, FetchDescriptor fetchDesc, RecordHandle recordToLock, StoredRecordHeader parent_recordHeader) throws StandardException { int slot = findRecordById( parent_recordHeader.getOverflowId(), Page.FIRST_SLOT_NUMBER); StoredRecordHeader recordHeader = getHeaderAtSlot(slot); try { int offset_to_row_data = getRecordOffset(slot) + recordHeader.size(); if (SanityManager.DEBUG) { if (getRecordOffset(slot) < (PAGE_HEADER_OFFSET + PAGE_HEADER_SIZE)) { SanityManager.THROWASSERT( "Incorrect offset. offset = " + getRecordOffset(slot) + ", offset should be < " + "(PAGE_HEADER_OFFSET + PAGE_HEADER_SIZE) = " + (PAGE_HEADER_OFFSET + PAGE_HEADER_SIZE) + ", current slot = " + slot + ", total slotsInUse = " + slotsInUse); } } // position the array reading stream at beginning of row data // just past the record header. ArrayInputStream lrdi = rawDataIn; lrdi.setPosition(offset_to_row_data); if (fetchDesc != null) { if (fetchDesc.getQualifierList() != null) { fetchDesc.reset(); } readRecordFromArray( row, (fetchDesc.getValidColumns() == null) ? row.length - 1 : fetchDesc.getMaxFetchColumnId(), fetchDesc.getValidColumnsArray(), fetchDesc.getMaterializedColumns(), lrdi, recordHeader, (ErrorObjectInput) null /* always null */, recordToLock); } else { readRecordFromArray( row, row.length - 1, (int[]) null, (int[]) null, lrdi, recordHeader, (ErrorObjectInput) null /* always null */, recordToLock); } return(recordHeader.hasOverflow() ? recordHeader : null); } catch (IOException ioe) { if (SanityManager.DEBUG) { if (pageData == null) { SanityManager.DEBUG_PRINT("DEBUG_TRACE", "caught an IOException in restoreRecordFromSlot " + (PageKey)getIdentity() + " slot " + slot + ", pageData is null"); } else { SanityManager.DEBUG_PRINT("DEBUG_TRACE", "caught an IOException in reestoreRecordFromSlot, " + (PageKey)getIdentity() + " slot " + slot + ", pageData.length = " + pageData.length + " pageSize = " + getPageSize()); SanityManager.DEBUG_PRINT("DEBUG_TRACE", "Hex dump of pageData \n " + "--------------------------------------------------\n" + pagedataToHexDump(pageData) + "--------------------------------------------------\n"); SanityManager.DEBUG_PRINT("DEBUG_TRACE", "Attempt to dump page " + this.toString()); } } // i/o methods on the byte array have thrown an IOException throw dataFactory.markCorrupt( StandardException.newException( SQLState.DATA_CORRUPT_PAGE, ioe, getPageId())); } } /** * Create a new record handle. * <p> * Return the next record id for allocation. Callers of this interface * expect the next id to get bumped some where else - probably by * storeRecordForInsert(). * <p> * * @return The next id to assing to a row. **/ public int newRecordId() { return nextId; } /** * Create a new record handle, and bump the id. * <p> * 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. * <p> * * @return The next id to assing to a row. **/ public int newRecordIdAndBump() { // headerOutOfDate must be bumped as nextId is changing, and must // eventually be updated in the page array. headerOutOfDate = true; return nextId++; } /** * Create a new record id based on current one passed in. * <p> * 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. * <p> * * @return the next id based on the input id. * * @param recordId The id caller just used, return the next one. * **/ protected int newRecordId(int recordId) { if (SanityManager.DEBUG) { SanityManager.ASSERT( recordId >= nextId, "should not create a record Id that is already given out"); } return recordId + 1; } public boolean isOverflowPage() { return isOverflowPage; } /************************************************************************** * Public Methods specific to StoredPage: ************************************************************************** */ /** * Get the full size of the page. **/ public final int getPageSize() { return pageData.length; } /** * Zero out a portion of the page. * <p> **/ protected final void clearSection(int offset, int length) { int endOffset = offset + length; while (offset < endOffset) pageData[offset++] = 0; } /** * The maximum free space on this page possible. * <p> * 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 * * @return the maximum free space on this page possible. * **/ protected int getMaxFreeSpace() { return getPageSize() - RECORD_SPACE_OFFSET - CHECKSUM_SIZE; } /** * The current free space on the page. **/ protected int getCurrentFreeSpace() { return freeSpace; } /************************************************************************** * Page header routines ************************************************************************** */ /** * Read the page header from the page array. * <p> * Read the page header from byte form in the page array into in memory * variables. **/ private void readPageHeader() throws IOException { // these reads are always against the page array ArrayInputStream lrdi = rawDataIn; lrdi.setPosition(PAGE_HEADER_OFFSET); long spare; isOverflowPage = lrdi.readBoolean(); setPageStatus (lrdi.readByte()); setPageVersion (lrdi.readLong()); slotsInUse = lrdi.readUnsignedShort(); nextId = lrdi.readInt(); generation = lrdi.readInt(); // page generation (Future Use) prevGeneration = lrdi.readInt(); // previous generation (Future Use) bipLocation = lrdi.readLong(); // BIPage location (Future Use) // number of deleted rows on page, we start to store this release 2.0. // for upgrade reasons, a 0 on disk means -1, so, we subtract one here. deletedRowCount = lrdi.readUnsignedShort() - 1; // the next 4 (total 22 bytes) are reserved for future spare = lrdi.readUnsignedShort(); spare = lrdi.readInt(); // used by encryption spare = lrdi.readLong(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -