📄 streamfilecontainer.java
字号:
/* Derby - Class org.apache.derby.impl.store.raw.data.StreamFileContainer Copyright 1999, 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.raw.data;import org.apache.derby.iapi.reference.SQLState;import org.apache.derby.iapi.services.context.ContextService;import org.apache.derby.iapi.services.sanity.SanityManager;import org.apache.derby.iapi.services.io.Storable;import org.apache.derby.iapi.services.io.StreamStorable;import org.apache.derby.iapi.services.io.FormatIdInputStream;import org.apache.derby.iapi.services.io.FormatIdOutputStream;import org.apache.derby.iapi.services.io.FormatIdUtil;import org.apache.derby.iapi.services.io.StoredFormatIds;import org.apache.derby.iapi.services.io.TypedFormat;import org.apache.derby.iapi.services.monitor.Monitor;import org.apache.derby.iapi.error.StandardException;import org.apache.derby.iapi.store.access.AccessFactory;import org.apache.derby.iapi.store.access.RowSource;import org.apache.derby.iapi.store.access.RowUtil;import org.apache.derby.iapi.store.access.TransactionController;import org.apache.derby.iapi.store.raw.ContainerKey;import org.apache.derby.iapi.store.raw.RawStoreFactory;import org.apache.derby.iapi.store.raw.StreamContainerHandle;import org.apache.derby.io.StorageFactory;import org.apache.derby.io.WritableStorageFactory;import org.apache.derby.io.StorageFile;import org.apache.derby.impl.store.raw.data.DecryptInputStream;import org.apache.derby.impl.store.raw.data.StoredFieldHeader;import org.apache.derby.impl.store.raw.data.StoredRecordHeader;import org.apache.derby.iapi.services.io.ArrayInputStream;import org.apache.derby.iapi.services.io.FormatableBitSet;import org.apache.derby.iapi.services.io.CompressedNumber;import org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream;import org.apache.derby.iapi.services.io.LimitInputStream;import org.apache.derby.iapi.services.property.PropertyUtil;import org.apache.derby.iapi.util.ReuseFactory;import java.util.Properties;import java.io.InputStream;import java.io.BufferedInputStream;import java.io.OutputStream;import java.io.IOException;import java.io.EOFException;import java.io.InvalidClassException;import java.io.Externalizable;import java.security.AccessController;import java.security.PrivilegedExceptionAction;import java.security.PrivilegedActionException;import java.io.FileNotFoundException;/** The format of this stream file is: (RH) (FH) (field data) (FH) (field data) ........ (FH) (field data) Record header is stored once at the beginning of the file for all the rows stored in this file. Record Header indicates how many fields are in each row. Then we just stored all the column from each row. Field header stored on this file is fixed size with fieldDataLength size set to LARGE_SLOT_SIZE (4) bytes. NOTE: No locks are used in this container. All transaction are not logged.**/public class StreamFileContainer implements TypedFormat, PrivilegedExceptionAction{ /************************************************************************** * Constant Fields of the class ************************************************************************** */ /* * typed format * format Id must fit in 4 bytes */ protected static int formatIdInteger = StoredFormatIds.RAW_STORE_SINGLE_CONTAINER_STREAM_FILE; // 4 bytes for field data length protected static final int LARGE_SLOT_SIZE = 4; protected static final int MIN_BUFFER_SIZE = RawStoreFactory.STREAM_FILE_BUFFER_SIZE_MINIMUM; protected static final int FIELD_STATUS = StoredFieldHeader.setFixed(StoredFieldHeader.setInitial(), true); protected static final int FIELD_HEADER_SIZE = StoredFieldHeader.size(FIELD_STATUS, 0, LARGE_SLOT_SIZE); /************************************************************************** * Fields of the class ************************************************************************** */ protected ContainerKey identity; private BaseDataFileFactory dataFactory; // the factory that made me private int bufferSize; private StorageFile file; private OutputStream fileOut; private DynamicByteArrayOutputStream out; private FormatIdOutputStream logicalDataOut; private InputStream fileIn; private BufferedInputStream bufferedIn; private DecryptInputStream decryptIn; private LimitInputStream limitIn; private FormatIdInputStream logicalDataIn; private StoredRecordHeader recordHeader; private byte[] ciphertext; private byte[] zeroBytes; // in case encryption // stream needs pad. /* privileged actions */ private static final int STORAGE_FILE_EXISTS_ACTION = 1; private static final int STORAGE_FILE_DELETE_ACTION = 2; private static final int STORAGE_FILE_MKDIRS_ACTION = 3; private static final int STORAGE_FILE_GET_OUTPUT_STREAM_ACTION = 4; private static final int STORAGE_FILE_GET_INPUT_STREAM_ACTION = 5; private int actionCode; private StorageFile actionStorageFile; /************************************************************************** * Constructors for This class: ************************************************************************** */ /** * Constructor. * * @exception StandardException Standard exception policy. **/ StreamFileContainer( ContainerKey identity, BaseDataFileFactory dataFactory) throws StandardException { this.identity = identity; this.dataFactory = dataFactory; } /** * Constructor * <p> * when rowSource is passed to the constructor, it will be loaded into the * container after the container has been created. * <p> * * @exception StandardException Standard exception policy. **/ StreamFileContainer( ContainerKey identity, BaseDataFileFactory dataFactory, Properties prop) throws StandardException { this.identity = identity; this.dataFactory = dataFactory; try { file = getFileName(identity, true, false); if (privExists(file)) { // note I'm left in the no-identity state as fillInIdentity() // hasn't been called. throw StandardException.newException( SQLState.FILE_EXISTS, file); } // get the properties to set buffer size // derby.storage.streamFileBufferSize getContainerProperties(prop); } catch (SecurityException se) { throw StandardException.newException( SQLState.FILE_CREATE, se, file); } } /************************************************************************** * Private/Protected methods of This class: ************************************************************************** */ /** * Open a stream file container. * <p> * Open a container. Open the file that maps to this container, if the * file does not exist then we assume the container was never created * and return. * If the file exists but we have trouble opening it then we throw some * exception. * <p> * * @return The opened StreamFileContainer. * * @param forUpdate Currently only accepts false, updating and existing * stream file container is not currently supported. * * @exception StandardException Standard exception policy. **/ protected StreamFileContainer open(boolean forUpdate) throws StandardException { file = getFileName(this.identity, false, true); if (!privExists(file)) return null; try { if (!forUpdate) { fileIn = privGetInputStream(file); if (dataFactory.databaseEncrypted()) { // if the database is encrypted, when reading the data back // from the file stream, we need to used the decrypt stream // to buffer up the bytes for reading. DecryptInputStream // also decrypts the data. MemByteHolder byteHolder = new MemByteHolder( RawStoreFactory.STREAM_FILE_BUFFER_SIZE_DEFAULT); decryptIn = new DecryptInputStream(fileIn, byteHolder, dataFactory); limitIn = new LimitInputStream(decryptIn); } else { bufferedIn = new BufferedInputStream( fileIn, RawStoreFactory.STREAM_FILE_BUFFER_SIZE_DEFAULT); limitIn = new LimitInputStream(bufferedIn); } // the logicalDataIn input stream is on top of a limit Input // stream, use a limit stream to make sure we don't read off // more then what each column says it contains logicalDataIn = new FormatIdInputStream(limitIn); // get the record header recordHeader = new StoredRecordHeader(); recordHeader.read(logicalDataIn); } else { if (SanityManager.DEBUG) SanityManager.THROWASSERT( "updating existing stream container not supported yet"); return null; } } catch (IOException ioe) { throw StandardException.newException( SQLState.FILE_CREATE, ioe, file); } return this; } /** * Close the stream file. * <p> * Close this stream file, and all streams associated with it. * <p> * * @exception StandardException Standard exception policy. **/ protected void close() { try { if (fileIn != null) { fileIn.close(); fileIn = null; if (dataFactory.databaseEncrypted()) { decryptIn.close(); decryptIn = null; } else { bufferedIn.close(); bufferedIn = null; } logicalDataIn.close(); logicalDataIn = null; } if (fileOut != null) { fileOut.close(); logicalDataOut.close(); fileOut = null; logicalDataOut = null; out = null; } } catch (IOException ioe) { // ignore close errors from fileOut.close() and fileIn.close() - // there isn't much we can do about them anyway - and some of the // interfaces don't want to deal with exceptions from close(). /* throw StandardException.newException( SQLState.FILE_CREATE, ioe, file); */ } } /************************************************************************** * Public Methods of This class: ************************************************************************** */ /** * Return my format identifier. **/ public int getTypeFormatId() { return StoredFormatIds.RAW_STORE_SINGLE_CONTAINER_STREAM_FILE; } /** * Request the system properties associated with a stream container. * <p> * Request the value of properties associated with a stream container. * The following properties can be requested: * derby.storage.streamFileBufferSize * * <p> * To get the value of a particular property add it to the property list, * and on return the value of the property will be set to it's current * value. For example: * * get_prop(ConglomerateController cc) * { * Properties prop = new Properties(); * prop.put("derby.storage.streamFileBufferSize", ""); * cc.getContainerProperties(prop); * * System.out.println( * "stream table's buffer size = " +
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -