⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 basepage.java

📁 derby database source code.good for you.
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/*   Derby - Class org.apache.derby.impl.store.raw.data.BasePage   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.raw.data;import org.apache.derby.iapi.reference.SQLState;import org.apache.derby.iapi.services.io.FormatableBitSet;import org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream;import org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream;import org.apache.derby.iapi.services.locks.C_LockFactory;import org.apache.derby.iapi.services.locks.Lockable;import org.apache.derby.iapi.services.locks.Latch;import org.apache.derby.iapi.services.locks.VirtualLockTable;import org.apache.derby.iapi.services.sanity.SanityManager;import org.apache.derby.iapi.services.io.LimitObjectInput;import org.apache.derby.iapi.services.io.TypedFormat;import org.apache.derby.iapi.error.StandardException;import org.apache.derby.iapi.store.raw.AuxObject;import org.apache.derby.iapi.store.raw.ContainerHandle;import org.apache.derby.iapi.store.raw.ContainerKey;import org.apache.derby.iapi.store.raw.FetchDescriptor;import org.apache.derby.iapi.store.raw.Page;import org.apache.derby.iapi.store.raw.PageKey;import org.apache.derby.iapi.store.raw.RecordHandle;import org.apache.derby.iapi.store.raw.RawStoreFactory;import org.apache.derby.iapi.store.raw.xact.RawTransaction;import org.apache.derby.iapi.store.raw.log.LogInstant;import org.apache.derby.iapi.store.access.Qualifier;import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo;import org.apache.derby.iapi.types.DataValueDescriptor;import java.io.IOException;import java.io.OutputStream;import java.io.ObjectInput;import java.util.Hashtable;import java.util.Observer;import java.util.Observable;/**  This class implements all the the generic locking behaviour for a Page.  It leaves method used to log and store the records up to sub-classes.  It is intended that the object can represent multiple pages from different  containers during its lifetime.  <P>  A page contains a set of records, which can be accessed by "slot",  which defines the order of the records on the page, or by "id" which  defines the identity of the records on the page.  Clients access  records by both slot and id, depending on their needs.  <P>  BasePage implements Observer to watch the ContainerHandle which notifies  its Observers when it is closing.  <BR>  MT - mutable **/public abstract class BasePage implements Page, Lockable, Observer, TypedFormat{	/**		auxiliary object		MT - mutable - content dynamic : single thread required. This reference is		set while the page is latched and returned to callers of page while the page is latched.		For correct MT behaviour it is assumed that the caller discards any reference to an		auxiliary object once the page is unlatched. The reference mya be cleared while		the page is latched, or while the page is being cleaned from the cache. In the latter		case the cache manager ensures that only a single thread can access this object.			*/	private AuxObject auxObj;	/**		this page's identity		<BR>		MT - immutable - content dynamic : single thread required	*/	protected PageKey identity;	/**		In-memory slot table, array of StoredRecordHeaders.		<BR>		MT - Immutable - Content Dynamic : Single thread required.	*/	private StoredRecordHeader[]	headers;		// in memory slot table	private int   recordCount;	/**		Page owner during exclusive access.		MT - mutable : single thread required, provided by Lockable single thread required. 	*/	protected BaseContainerHandle	owner;	/**		Count of times a latch is held nested during an abort	*/	private int nestedLatch;	/**		LockManager held latch during exclusive access.		When this is not null, latch.getQualifier() == owner	*/	private Latch	myLatch;		protected boolean		inClean;	// is the page being cleaned    /**     * Used to determine latch state of a page.     *     * MT - mutable     *     * There are 3 latch states for a page:     *     * UNLATCHED - (owner == null)      * PRELATCH  - (owner != null) && preLatch     * LATCHED   - (owner != null) && !preLatch     *     * A page may be "cleaned" while it is either UNLATCHED, or PRELATCH, but     * it must wait for it to be not LATCHED.     *     * A page may move from UNLATCHED to PRELATCH, while being cleaned.     * A page must wait for !inClean before it can move from PRELATCH to      * LATCHED.     **/	protected boolean		preLatch;	/**		Instant of last log record that updated this page.		<BR> MT - mutable : latched	*/	private LogInstant lastLog;	/**		Version of the page.		<BR> MT - mutable : single thread required - The page must be latched to access		this variable or the page muts be in the noidentiy state.	*/	private long	pageVersion = 0;	// version of the page	/**		Status of the page	 */	private byte	pageStatus;	/**		Values for pageStatus flag 		page goes thru the following transition:		VALID_PAGE <-> deallocated page -> free page <-> VALID_PAGE		deallocated and free page are both INVALID_PAGE as far as BasePage is concerned.		When a page is deallocated, it transitioned from VALID to INVALID.		When a page is allocated, it trnasitioned from INVALID to VALID.	*/	public static final byte VALID_PAGE = 1;	public static final byte INVALID_PAGE = 2;	/**		Init page flag.		INIT_PAGE_REUSE - set if page is being initialized for reuse		INIT_PAGE_OVERFLOW - set if page will be an overflow page		INIT_PAGE_REUSE_RECORDID - set if page is being reused and its record						id can be reset to RecordHandle.FIRST_RECORD_ID, rather						to 1+ next recordId on the page	*/	public static final int INIT_PAGE_REUSE = 0x1;	public static final int INIT_PAGE_OVERFLOW = 0x2;	public static final int INIT_PAGE_REUSE_RECORDID = 0x4;	/**		Log Record flag.  Why the before image of this record is being logged		LOG_RECORD_FOR_UPDATE - set if the record is being logged for update.		LOG_RECORD_DEFAULT - for non update.		LOG_RECORD_FOR_PURGE - set if the record is being logged for purges 		                       and no data required to ve logged.		The other cases (copy, purge, delete), we don't need to distinguish,		leave no bit set. 	 */	public static final int LOG_RECORD_DEFAULT = 0x0;	public static final int LOG_RECORD_FOR_UPDATE = 0x1;	public static final int LOG_RECORD_FOR_PURGE = 0x2;	/**	 ** Create a new, empty page.	 **/		protected BasePage()	{			}	/**        Initialized the BasePage.        <p>		Initialize the object, ie. perform work normally perfomed in         constructor.  Called by setIdentity() and createIdentity().	*/	protected void initialize()	{		setAuxObject(null);		identity = null;		recordCount = 0;		clearLastLogInstant();		if (SanityManager.DEBUG)		{			if (nestedLatch != 0)				SanityManager.THROWASSERT("nestedLatch is non-zero in initialize - value =  " + nestedLatch);			if (inClean)				SanityManager.THROWASSERT("inClean is true in initialize");			if (preLatch)				SanityManager.THROWASSERT("preLatch is true in initialize");		}	}	/**		Must be called by a sub-class before calling setHeaderAtSlot.	*/	protected void initializeHeaders(int numRecords)     {		if (SanityManager.DEBUG)		{			if (recordCount != 0)				SanityManager.THROWASSERT(						"record count = " + recordCount + 						" before initSlotTable is called"); 		}        headers = new StoredRecordHeader[numRecords];	}	/*	** Cacheable methods	*/	protected void fillInIdentity(PageKey key) {		if (SanityManager.DEBUG) {			SanityManager.ASSERT(identity == null);		}		identity = key;	}	public void clearIdentity() {		if (SanityManager.DEBUG) {			SanityManager.ASSERT(!isLatched());		}		identity = null;		cleanPageForReuse();	}	/**		Initialized this page for reuse or first use	*/	protected void cleanPageForReuse()	{		setAuxObject(null);		recordCount = 0;	}	/**			OK to hand object outside to cache.. 	*/	public Object getIdentity() {		return identity;	}	/*	** Methods of Page	*/	private static final RecordHandle InvalidRecordHandle = 		new RecordId(			new PageKey(				new ContainerKey(0,0), ContainerHandle.INVALID_PAGE_NUMBER),				RecordHandle.INVALID_RECORD_HANDLE);	public final RecordHandle getInvalidRecordHandle()	{		// a static invalid record handle		return InvalidRecordHandle;	}	public static final RecordHandle MakeRecordHandle(PageKey pkey, int recordHandleConstant)		 throws StandardException	{		if (recordHandleConstant >= RecordHandle.FIRST_RECORD_ID)        {			throw StandardException.newException(                SQLState.DATA_CANNOT_MAKE_RECORD_HANDLE,                 new Long(recordHandleConstant));        }		return new RecordId(pkey, recordHandleConstant);	}	public final RecordHandle makeRecordHandle(int recordHandleConstant)		 throws StandardException	{		return MakeRecordHandle(getPageId(), recordHandleConstant);	}	/** @see Page#getPageNumber */	public final long getPageNumber() {		if (SanityManager.DEBUG) {			SanityManager.ASSERT(isLatched(), "page is not latched.");			SanityManager.ASSERT(identity != null, "identity is null.");		}		return identity.getPageNumber();	}	public final RecordHandle getRecordHandle(int recordId) {		if (SanityManager.DEBUG) {			SanityManager.ASSERT(isLatched());		}		int slot = findRecordById(recordId, FIRST_SLOT_NUMBER);		if (slot < 0)			return null;		return getRecordHandleAtSlot(slot);	}	public final RecordHandle getRecordHandleAtSlot(int slot) {		return getHeaderAtSlot(slot).getHandle(getPageId(), slot);	}	/**	  @see Page#recordExists	  @exception StandardException recordHandle is not a valid record handle	*/	public final boolean recordExists(RecordHandle handle, boolean ignoreDelete)		 throws StandardException	{		if (SanityManager.DEBUG) {			SanityManager.ASSERT(isLatched());		}		if (handle.getId() < RecordHandle.FIRST_RECORD_ID)        {			throw StandardException.newException(                    SQLState.DATA_INVALID_RECORD_HANDLE, handle);        }		if (handle.getPageNumber() != getPageNumber())			return false;		int slot = findRecordById(handle.getId(), handle.getSlotNumberHint());		return (slot >= FIRST_SLOT_NUMBER &&				(ignoreDelete || !isDeletedAtSlot(slot)));	}	/**		<OL>		<LI>Lock the record (according to the locking policy)		<LI>If the record is deleted then return null. We must check after we hold the lock to		ensure that we don't look at the delete status of an uncommitted record.		<LI>Fetch the record		<LI>Unlock the record (according to the locking policy)		</OL>		@see Page#fetch		@exception StandardException messageId equals StandardException.newException(SQLState.RECORD_VANISHED		If the record identfied by handle does not exist on this page.		@exception StandardException	Standard Cloudscape error policy		@exception StandardException   record is not on page with message id equal to			StandardException.newException(SQLState.RECORD_VANISHED.	*/	public RecordHandle fetch(    RecordHandle        handle,     Object[]            row,     FormatableBitSet    validColumns,     boolean             forUpdate)	throws StandardException {		if (SanityManager.DEBUG) {			SanityManager.ASSERT(isLatched());		}		owner.getLockingPolicy().lockRecordForRead(myLatch, handle, forUpdate);		// See if the record is deleted or not.		int slot = getSlotNumber(handle);        StoredRecordHeader recordHeader = getHeaderAtSlot(slot);		if (recordHeader.isDeleted())			return null;        FetchDescriptor hack_fetch =             new FetchDescriptor(                    row.length, validColumns, (Qualifier[][]) null);		// magic to copy rows across ...		restoreRecordFromSlot(            slot, row, hack_fetch, handle, recordHeader, true);		owner.getLockingPolicy().unlockRecordAfterRead(                owner.getTransaction(), owner, handle, forUpdate, true);		return handle;	}	public RecordHandle fetchFromSlot(    RecordHandle            rh,     int                     slot,     Object[]                row,    FetchDescriptor         fetchDesc,    boolean                 ignoreDelete)		 throws StandardException	{		if (SanityManager.DEBUG) {			SanityManager.ASSERT(isLatched());

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -