📄 heap.java
字号:
/* Derby - Class org.apache.derby.impl.store.access.heap.Heap Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */package org.apache.derby.impl.store.access.heap;import java.io.ObjectOutput;import java.io.ObjectInput;import java.io.IOException;import java.util.Properties;import org.apache.derby.iapi.reference.SQLState;import org.apache.derby.iapi.services.io.ArrayInputStream;import org.apache.derby.iapi.services.io.FormatableBitSet;import org.apache.derby.iapi.services.sanity.SanityManager;import org.apache.derby.iapi.services.io.Formatable;import org.apache.derby.iapi.services.io.FormatIdUtil;import org.apache.derby.iapi.services.io.Storable;import org.apache.derby.iapi.services.io.StoredFormatIds;import org.apache.derby.iapi.error.StandardException;import org.apache.derby.iapi.store.access.conglomerate.Conglomerate;import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo;import org.apache.derby.iapi.store.access.conglomerate.TransactionManager;import org.apache.derby.iapi.store.access.conglomerate.ScanManager;import org.apache.derby.iapi.store.access.conglomerate.TransactionManager;import org.apache.derby.iapi.store.access.AccessFactoryGlobals;import org.apache.derby.iapi.store.access.ConglomerateController;import org.apache.derby.iapi.store.access.DynamicCompiledOpenConglomInfo;import org.apache.derby.iapi.store.access.Qualifier;import org.apache.derby.iapi.store.access.RowLocationRetRowSource;import org.apache.derby.iapi.store.access.RowUtil;import org.apache.derby.iapi.store.access.StaticCompiledOpenConglomInfo;import org.apache.derby.iapi.store.access.StoreCostController;import org.apache.derby.iapi.store.access.TransactionController;import org.apache.derby.iapi.store.raw.ContainerKey;import org.apache.derby.iapi.store.raw.ContainerHandle;import org.apache.derby.iapi.store.raw.LockingPolicy;import org.apache.derby.iapi.store.raw.Transaction;import org.apache.derby.iapi.store.raw.Page;import org.apache.derby.iapi.store.raw.RawStoreFactory;import org.apache.derby.iapi.store.raw.RecordHandle;import org.apache.derby.iapi.types.DataValueDescriptor;import org.apache.derby.iapi.services.cache.ClassSize;import org.apache.derby.iapi.types.DataType;import org.apache.derby.impl.store.access.conglomerate.ConglomerateUtil;import org.apache.derby.impl.store.access.conglomerate.GenericConglomerate;import org.apache.derby.impl.store.access.conglomerate.OpenConglomerate;import org.apache.derby.impl.store.access.conglomerate.OpenConglomerateScratchSpace;import java.sql.ResultSet;import java.sql.SQLException;/** * @format_id ACCESS_HEAP_V1_ID * * @purpose The tag that describes the on disk representation of the Heap * conglomerate object. The Heap conglomerate object is stored in * a field of a row in the Conglomerate directory. * * @upgrade This format was made obsolete in the kimono release. * * @disk_layout * containerid(long) * segmentid(int) **//** * @format_id ACCESS_HEAP_V2_ID * * @purpose The tag that describes the on disk representation of the Heap * conglomerate object. The Heap conglomerate object is stored in * a field of a row in the Conglomerate directory. * * @upgrade The format id of this object is currently always read from disk * as a separate column in the conglomerate directory. To read * A conglomerate object from disk and upgrade it to the current * version do the following: * * format_id = get format id from a separate column * Upgradable conglom_obj = instantiate empty obj(format_id) * read in conglom_obj from disk * conglom = conglom_obj.upgradeToCurrent(); * * @disk_layout * format_of_this_conlgomerate(byte[]) * containerid(long) * segmentid(int) * number_of_columns(int) * array_of_format_ids(byte[][]) **//** A heap object corresponds to an instance of a heap conglomerate. It caches information which makes it fast to open heap controllers from it.**/public final class Heap extends GenericConglomerate implements Conglomerate, StaticCompiledOpenConglomInfo{ /* ** Fields of Heap. */ protected ContainerKey id; /** * The format id's of each of the columns in the heap table. **/ int[] format_ids; private static final int BASE_MEMORY_USAGE = ClassSize.estimateBaseFromCatalog( Heap.class); private static final int CONTAINER_KEY_MEMORY_USAGE = ClassSize.estimateBaseFromCatalog( ContainerKey.class); public int estimateMemoryUsage() { int sz = BASE_MEMORY_USAGE; if( null != id) sz += CONTAINER_KEY_MEMORY_USAGE; if( null != format_ids) sz += format_ids.length*ClassSize.getIntSize(); return sz; } // end of estimateMemoryUsage /* ** Methods of Heap. */ /* Constructors for This class: */ /** * Zero arg constructor for Monitor to create empty object. **/ public Heap() { } /* Private/Protected methods of This class: */ /** * Create a heap conglomerate. * <p> * Create a heap conglomerate. This method is called from the heap factory * to create a new instance of a heap. * <p> * * @exception StandardException Standard exception policy. **/ protected void create( Transaction rawtran, int segmentId, long input_containerid, DataValueDescriptor[] template, Properties properties, int tmpFlag) throws StandardException { // Create a container for the heap table with // default minimumRecordSize to be at least // MINIMUM_RECORD_SIZE_DEFAULT (12), // to guarantee there is enough room for updates // of the row. // Here we only take care of the case that // that the properties are set with the create // statement. For the case when properties are // not set with the create statement, it is taken // care of in fileContainer.java: createInfoFromProp(). if (properties != null) { String value = properties.getProperty( RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER); int minimumRecordSize = (value == null) ? RawStoreFactory.MINIMUM_RECORD_SIZE_DEFAULT : Integer.parseInt(value); if (minimumRecordSize < RawStoreFactory.MINIMUM_RECORD_SIZE_DEFAULT) { properties.put( RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER, Integer.toString( RawStoreFactory.MINIMUM_RECORD_SIZE_DEFAULT)); } } // Create a container for the heap with default page size. long containerid = rawtran.addContainer( segmentId, input_containerid, ContainerHandle.MODE_DEFAULT, properties, tmpFlag); // Make sure the container was actually created. if (containerid < 0) { throw StandardException.newException( SQLState.HEAP_CANT_CREATE_CONTAINER); } // Keep track of what segment the container's in. id = new ContainerKey(segmentId, containerid); // Heap requires a template representing every column in the table. if ((template == null) || (template.length == 0)) { throw StandardException.newException( SQLState.HEAP_COULD_NOT_CREATE_CONGLOMERATE); } // get format id's from each column in template and store it in the // conglomerate state. this.format_ids = ConglomerateUtil.createFormatIds(template); // need to open the container and insert the row. Since we are // creating it no need to bother with locking since no one can get // to it until after we have created it and returned it's id. ContainerHandle container = null; Page page = null; try { container = rawtran.openContainer( id, (LockingPolicy) null, ContainerHandle.MODE_FORUPDATE | (isTemporary() ? ContainerHandle.MODE_TEMP_IS_KEPT : 0)); // row in slot 0 of heap page 1 which is just a single column with // the heap entry. DataValueDescriptor[] control_row = new DataValueDescriptor[1]; control_row[0] = this; page = container.getPage(ContainerHandle.FIRST_PAGE_NUMBER); page.insertAtSlot( Page.FIRST_SLOT_NUMBER, control_row, (FormatableBitSet) null, (LogicalUndo) null, Page.INSERT_OVERFLOW, AccessFactoryGlobals.HEAP_OVERFLOW_THRESHOLD); page.unlatch(); page = null; // Don't include the control row in the estimated row count. container.setEstimatedRowCount(0, /* unused flag */ 0); } finally { if (container != null) container.close(); if (page !=null) page.unlatch(); } } /** * Create a heap conglomerate during the boot process. * <p> * Manufacture a Heap Conglomerate out of "thin" air, to boot strap * the system. Create an in-memory Heap Conglomerate with the input * parameters, The caller will use this to open the conglomerate * conglomerate and read the "real" values from disk. Conglom-conglom * is always on segment 0. * * * @param containerid The container id of the conglomerate. * @param template Object array describing the columns of the heap. **/ public void boot_create( long containerid, DataValueDescriptor[] template) { id = new ContainerKey(0, containerid); this.format_ids = ConglomerateUtil.createFormatIds(template); } /* ** Methods of Conglomerate */ /** * Add a column to the heap conglomerate. * <p> * This routine update's the in-memory object version of the Heap * Conglomerate to have one more column of the type described by the * input template column. * * @param column_id The column number to add this column at. * @param template_column An instance of the column to be added to table. * * @exception StandardException Standard exception policy. **/ public void addColumn( TransactionManager xact_manager, int column_id, Storable template_column) throws StandardException { // need to open the container and update the row containing the // serialized format of the heap. ContainerHandle container = null; Page page = null; Transaction rawtran = xact_manager.getRawStoreXact(); try { container = rawtran.openContainer( id, rawtran.newLockingPolicy( LockingPolicy.MODE_CONTAINER, TransactionController.ISOLATION_SERIALIZABLE, true), ContainerHandle.MODE_FORUPDATE | (isTemporary() ? ContainerHandle.MODE_TEMP_IS_KEPT : 0)); if (column_id != format_ids.length) { if (SanityManager.DEBUG) SanityManager.THROWASSERT( "column_id = " + column_id + "format_ids.length = " + format_ids.length + "format_ids = " + format_ids); throw(StandardException.newException( SQLState.HEAP_TEMPLATE_MISMATCH, new Long(column_id), new Long(this.format_ids.length))); } // create a new array, and copy old values to it. int[] old_format_ids = format_ids; format_ids = new int[old_format_ids.length + 1]; System.arraycopy( old_format_ids, 0, format_ids, 0, old_format_ids.length);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -