📄 filecontainer.java
字号:
/** Read containerInfo from a byte array The container Header array must be written by or of the same format as put together by writeHeaderFromArray. @exception StandardException Cloudscape Standard error policy @exception IOException error in reading the header from file */ private void readHeaderFromArray(byte[] a) throws StandardException, IOException { ArrayInputStream inStream = new ArrayInputStream(a); inStream.setLimit(0, CONTAINER_INFO_SIZE); int fid = inStream.readInt(); if (fid != formatIdInteger) { throw StandardException.newException( SQLState.DATA_UNKNOWN_CONTAINER_FORMAT, getIdentity(), new Long(fid)); } int status = inStream.readInt(); pageSize = inStream.readInt(); spareSpace = inStream.readInt(); minimumRecordSize = inStream.readInt(); initialPages = inStream.readShort(); PreAllocSize = inStream.readShort(); firstAllocPageNumber = inStream.readLong(); firstAllocPageOffset = inStream.readLong(); containerVersion = inStream.readLong(); estimatedRowCount = inStream.readLong(); lastLogInstant = null; if (PreAllocSize == 0) // pre 2.0, we don't store this. PreAllocSize = DEFAULT_PRE_ALLOC_SIZE; long spare2 = inStream.readLong(); // read spare long long spare3 = inStream.readLong(); // read spare long // upgrade - if this is a container that was created before // initialPages was stored, it will have a zero value. Set it to the // default of 1. if (initialPages == 0) initialPages = 1; // container read in from disk, reset preAllocation values PreAllocThreshold = PRE_ALLOC_THRESHOLD; // validate checksum long onDiskChecksum = inStream.readLong(); checksum.reset(); checksum.update(a, 0, CONTAINER_INFO_SIZE - CHECKSUM_SIZE); if (onDiskChecksum != checksum.getValue()) { PageKey pk = new PageKey(identity, FIRST_ALLOC_PAGE_NUMBER); throw dataFactory.markCorrupt (StandardException.newException( SQLState.FILE_BAD_CHECKSUM, pk, new Long(checksum.getValue()), new Long(onDiskChecksum), org.apache.derby.iapi.util.StringUtil.hexDump(a))); } allocCache.reset(); // set the in memory state setDroppedState((status & FILE_DROPPED) != 0); setCommittedDropState((status & FILE_COMMITTED_DROP) != 0); setReusableRecordIdState((status & FILE_REUSABLE_RECORDID) != 0); } /** Write the container header to a page array (the first allocation page) @exception StandardException Cloudscape Standard error policy @exception IOException error in writing the header to file */ protected void writeHeader(byte[] pageData) throws StandardException, IOException { // write out the current containerInfo in the borrowed space to byte // array containerInfo writeHeaderToArray(containerInfo); AllocPage.WriteContainerInfo(containerInfo, pageData, false); } /** Write the container header directly to output stream (fileData). Assumes the output stream is positioned at the beginning of the file. Subclasses that can writes the container header is expected to manufacture a DataOutput stream which is used here. <BR> MT - single thread required - Enforced by caller @exception StandardException Cloudscape Standard error policy @exception IOException error in writing the header to file */ protected void writeHeader(DataOutput fileData, boolean create, byte[] epage) throws IOException, StandardException { // write out the current containerInfo in the borrowed space to byte // array containerInfo writeHeaderToArray(containerInfo); // RESOLVE: get no wait on the page cache to see if allocation page is // there, if so, use that instead of making a new array and a static // function. AllocPage.WriteContainerInfo(containerInfo, epage, create); // now epage has the containerInfo written inside it // force WAL - and check to see if database is corrupt or is frozen. dataFactory.flush(lastLogInstant); if (lastLogInstant != null) lastLogInstant = null; // write it out dataFactory.writeInProgress(); try { fileData.write(epage); } finally { dataFactory.writeFinished(); } } /** Get an embryonic page from the dataInput stream. If fileData is not null, then the embyronic page will be read in from the input stream (fileData), which is assumed to be positioned at the beginning of the first allocation page. if fileData is null, then just manufacture an array which is the size of an embryonic page. @exception IOException error in read the embryonic page from file */ protected byte[] getEmbryonicPage(DataInput fileData) throws IOException { byte[] epage = new byte[AllocPage.MAX_BORROWED_SPACE]; if (fileData != null) { fileData.readFully(epage); } return epage; } /** Write containerInfo into a byte array The container Header thus put together can be read by readHeaderFromArray. @exception IOException error in writing the header */ private void writeHeaderToArray(byte[] a) throws IOException { if (SanityManager.DEBUG) SanityManager.ASSERT(a.length >= CONTAINER_INFO_SIZE, "header won't fit in array"); ArrayOutputStream a_out = new ArrayOutputStream(a); FormatIdOutputStream outStream = new FormatIdOutputStream(a_out); int status = 0; if (getDroppedState()) status |= FILE_DROPPED; if (getCommittedDropState()) status |= FILE_COMMITTED_DROP; if (isReusableRecordId()) status |= FILE_REUSABLE_RECORDID; a_out.setPosition(0); a_out.setLimit(CONTAINER_INFO_SIZE); outStream.writeInt(formatIdInteger); outStream.writeInt(status); outStream.writeInt(pageSize); outStream.writeInt(spareSpace); outStream.writeInt(minimumRecordSize); outStream.writeShort(initialPages); outStream.writeShort(PreAllocSize); // write spare1 outStream.writeLong(firstAllocPageNumber); outStream.writeLong(firstAllocPageOffset); outStream.writeLong(containerVersion); outStream.writeLong(estimatedRowCount); outStream.writeLong(0); //Write spare2 outStream.writeLong(0); //Write spare3 checksum.reset(); checksum.update(a, 0, CONTAINER_INFO_SIZE - CHECKSUM_SIZE); // write the checksum to the array outStream.writeLong(checksum.getValue()); a_out.clearLimit(); } /** Log all information on the container creation necessary to recreate the container during a load tran. @exception StandardException Cloudscape Standard error policy */ protected ByteArray logCreateContainerInfo() throws StandardException { // just write out the whole container header byte[] array = new byte[CONTAINER_INFO_SIZE]; if (array == null || array.length != CONTAINER_INFO_SIZE) { throw StandardException.newException( SQLState.DATA_OBJECT_ALLOCATION_FAILED, "byte[]"); } try { writeHeaderToArray(array); } catch (IOException ioe) { throw StandardException.newException( SQLState.DATA_UNEXPECTED_EXCEPTION, ioe); } return new ByteArray(array); } /** Set container properties from the passed in ByteArray, which is created by logCreateContainerInfo. This information is used to recreate the container during recovery load tran. The following container properties are set: pageSize spareSpace minimumRecordSize isReusableRecordId initialPages */ private void createInfoFromLog(ByteArray byteArray) throws StandardException { if (SanityManager.DEBUG) { SanityManager.ASSERT(byteArray != null, "setCreateContainerInfoFromLog: ByteArray is null"); SanityManager.ASSERT(byteArray.getLength() == CONTAINER_INFO_SIZE, "setCreateContainerInfoFromLog: ByteArrays.length() != CONTAINER_INFO_SIZE"); } byte[] array = byteArray.getArray(); // now extract the relavent information from array - basically // duplicate the code in readHeaderFromArray ArrayInputStream inStream = new ArrayInputStream(array); int status = 0; try { inStream.setLimit(0, CONTAINER_INFO_SIZE); int fid = inStream.readInt(); if (fid != formatIdInteger) { // RESOLVE: do something about this when we have > 1 container format throw StandardException.newException( SQLState.DATA_UNKNOWN_CONTAINER_FORMAT, getIdentity(), new Long(fid)); } status = inStream.readInt(); pageSize = inStream.readInt(); spareSpace = inStream.readInt(); minimumRecordSize = inStream.readInt(); initialPages = inStream.readShort(); } catch (IOException ioe) { throw StandardException.newException( SQLState.DATA_UNEXPECTED_EXCEPTION, ioe); } // set reusable record id property setReusableRecordIdState((status & FILE_REUSABLE_RECORDID) != 0); // sanity check to make sure we are not encoutering any // dropped Container if (SanityManager.DEBUG) { SanityManager.ASSERT((status & FILE_DROPPED) == 0 && (status & FILE_COMMITTED_DROP) == 0, "cannot load a dropped container"); } } /** Set container properties from the passed in createArgs. The following container properties are set: pageSize spareSpace minimumRecordSize isReusableRecordId initialPages RESOLVE - in the future setting parameters should be overridable by sub-class, e.g. one implementation of Container may require a minimum page size of 4k. */ private void createInfoFromProp(Properties createArgs) throws StandardException { // Need a TransactionController to get database/service wide properties. AccessFactory af = (AccessFactory) Monitor.getServiceModule(dataFactory, AccessFactory.MODULE); // RESOLVE: sku defectid 2014 TransactionController tc = (af == null) ? null : af.getTransaction( ContextService.getFactory().getCurrentContextManager()); pageSize = PropertyUtil.getServiceInt(tc, createArgs, Property.PAGE_SIZE_PARAMETER, Limits.DB2_MIN_PAGE_SIZE, Limits.DB2_MAX_PAGE_SIZE, RawStoreFactory.PAGE_SIZE_DEFAULT); // rather than throw error, just automatically set page size to // default if bad value given. if ((pageSize != 4096) && (pageSize != 8192) && (pageSize != 16384) && (pageSize != 32768)) { pageSize= RawStoreFactory.PAGE_SIZE_DEFAULT; } spareSpace = PropertyUtil.getServiceInt(tc, createArgs, RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER, 0, 100, 20); PreAllocSize = PropertyUtil.getServiceInt(tc, createArgs, RawStoreFactory.PRE_ALLOCATE_PAGE, MIN_PRE_ALLOC_SIZE, MAX_PRE_ALLOC_SIZE, DEFAULT_PRE_ALLOC_SIZE /* default */); // RESOLVE - in the future, we will allow user to set minimumRecordSize // to be larger than pageSize, when long rows are supported. if (createArgs == null) { // if the createArgs is null, then the following method call // will get the system properties from the appropriete places. // we want to make sure minimumRecrodSize is set to at least // the default value MINIMUM_RECORD_SIZE_DEFAULT (12) // as set in rawStoreFactory. minimumRecordSize = PropertyUtil.getServiceInt(tc, RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER, RawStoreFactory.MINIMUM_RECORD_SIZE_DEFAULT, // this is different from the next call // reserving 100 bytes for record/field headers (pageSize * (1 - spareSpace/100) - 100), RawStoreFactory.MINIMUM_RECORD_SIZE_DEFAULT); } else { // if the createArgs is not null, then it has already been set // by upper layer or create statement, then, we allow the minimum // value of this to be MINIMUM_RECORD_SIZE_MINIMUM (1). minimumRecordSize = PropertyUtil.getServiceInt(tc, createArgs, RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER, RawStoreFactory.MINIMUM_RECORD_SIZE_MINIMUM, // this is different from the last call // reserving 100 bytes for record/field headers (pageSize * (1 - spareSpace/100) - 100),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -