Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / derby-10.3.2.1 / java / engine / org / apache / derby / impl / store / raw / data / BaseContainer.java
diff --git a/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/store/raw/data/BaseContainer.java b/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/store/raw/data/BaseContainer.java
new file mode 100644 (file)
index 0000000..43a1b88
--- /dev/null
@@ -0,0 +1,928 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.store.raw.data.BaseContainer\r
+\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to you under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+      http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.impl.store.raw.data;\r
+\r
+import org.apache.derby.iapi.reference.SQLState;\r
+import org.apache.derby.iapi.services.locks.CompatibilitySpace;\r
+import org.apache.derby.iapi.services.locks.Lockable;\r
+import org.apache.derby.iapi.services.locks.Latch;\r
+import org.apache.derby.iapi.services.locks.C_LockFactory;\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+import org.apache.derby.iapi.store.access.TransactionController;\r
+import org.apache.derby.iapi.store.access.SpaceInfo;\r
+\r
+import org.apache.derby.iapi.store.raw.ContainerHandle;\r
+import org.apache.derby.iapi.store.raw.LockingPolicy;\r
+import org.apache.derby.iapi.store.raw.Page;\r
+import org.apache.derby.iapi.store.raw.PageKey;\r
+import org.apache.derby.iapi.store.raw.PageTimeStamp;\r
+import org.apache.derby.iapi.store.raw.RecordHandle;\r
+import org.apache.derby.iapi.store.raw.Transaction;\r
+import org.apache.derby.iapi.store.raw.ContainerKey;\r
+import org.apache.derby.iapi.store.raw.data.RawContainerHandle;\r
+import org.apache.derby.iapi.store.raw.log.LogInstant;\r
+import org.apache.derby.iapi.store.raw.xact.RawTransaction;\r
+\r
+import org.apache.derby.iapi.util.ByteArray;\r
+\r
+import java.util.Properties;\r
+import java.util.Hashtable;\r
+\r
+/**\r
+       BaseContainer is an abstract class that provides the locking bahaviour\r
+       for an object representing an active container, that is the actual\r
+       storage container, not the ContainerHandle interface. This class is designed\r
+       so that it can change the container it represents to avoid creating\r
+       a new object for every container.\r
+       <P>\r
+       This object implements lockable to provide an object to lock while a page is being\r
+       allocated.\r
+       <BR> MT - Mutable - mutable identity : \r
+*/\r
+abstract class BaseContainer implements Lockable {\r
+\r
+       /**\r
+               Identity of the container.\r
+\r
+               <BR> MT - Mutable\r
+       */\r
+       protected ContainerKey identity;\r
+\r
+       \r
+       /**\r
+               Dropped state of the container.\r
+\r
+               <BR> MT - mutable : single thread required. Either the container must be exclusive\r
+               locked by this thread, or the container must have no identity (ie. it is being created\r
+               or opened).\r
+       */\r
+       protected boolean       isDropped;\r
+\r
+\r
+       /**\r
+               Committed Drop state of the container.  If a post comit action\r
+               determined that the drop container operation is committed, the whole\r
+               container may be removed and space reclaimed.\r
+\r
+               <BR> MT - mutable : single thread required. Either the container must be exclusive\r
+               locked by this thread, or the container must have no identity (ie. it is being created\r
+               or opened).\r
+       */\r
+       protected boolean isCommittedDrop;\r
+\r
+\r
+       /**\r
+               Is reusable recordId.  By default, record Ids are not reusable when a\r
+               page is reused.  However, under special circumstances, clients to raw\r
+               store may decide that record Ids may be reused after the page is\r
+               reused.   When this flag is set, pages that are reused will have its\r
+               next recordId set to RecordHandle.FIRST_RECORD_ID\r
+       */\r
+       protected boolean isReusableRecordId = false;\r
+\r
+       BaseContainer() {\r
+       }\r
+\r
+       /*\r
+       ** portions of Cacheable interface, interface is actually implemented by\r
+       ** sub-class. This section also contains methods related to this interface.\r
+       */\r
+\r
+       protected void fillInIdentity(ContainerKey key) {\r
+\r
+               if (SanityManager.DEBUG) {\r
+                       SanityManager.ASSERT(identity == null || (identity == key));\r
+               }\r
+\r
+               identity = key;\r
+       }\r
+\r
+       public void clearIdentity() {\r
+               if (SanityManager.DEBUG) {\r
+                       SanityManager.ASSERT(identity != null);\r
+               }\r
+\r
+               identity = null;\r
+       }\r
+\r
+       public Object getIdentity() {\r
+               return identity;\r
+       }\r
+\r
+       /*\r
+       ** Methods from Lockable, just require a single exclusive locker\r
+       */\r
+\r
+       public void lockEvent(Latch lockInfo) {\r
+               if (SanityManager.DEBUG) {\r
+                       SanityManager.ASSERT(identity != null);\r
+               }\r
+       }\r
+\r
+       public boolean requestCompatible(Object requestedQualifier, Object grantedQualifier) {\r
+               if (SanityManager.DEBUG) {\r
+                       SanityManager.ASSERT(identity != null);\r
+               }\r
+               return false;\r
+       }\r
+\r
+       public boolean lockerAlwaysCompatible() {\r
+               if (SanityManager.DEBUG) {\r
+                       SanityManager.ASSERT(identity != null);\r
+               }\r
+               return false;\r
+       }\r
+\r
+       public void unlockEvent(Latch lockInfo) {\r
+               if (SanityManager.DEBUG) {\r
+                       SanityManager.ASSERT(identity != null);\r
+               }\r
+       }\r
+\r
+       /*\r
+       ** Implementation specific methods\r
+       */\r
+\r
+\r
+       /**\r
+               Release free space to the OS.\r
+               <P>\r
+        As is possible release any free space to the operating system.  This\r
+        will usually mean releasing any free pages located at the end of the\r
+        file using the java truncate() interface.\r
+\r
+               @exception StandardException    Standard Derby error policy\r
+       */\r
+       public void compressContainer(BaseContainerHandle handle)\r
+        throws StandardException\r
+    {\r
+               RawTransaction ntt = handle.getTransaction().startNestedTopTransaction();\r
+\r
+               int mode = handle.getMode(); \r
+\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       SanityManager.ASSERT((mode & ContainerHandle.MODE_FORUPDATE) ==\r
+                                                                ContainerHandle.MODE_FORUPDATE, \r
+                                                                "addPage handle not for update");\r
+               }\r
+\r
+               // if we are not in the same transaction as the one which created the\r
+               // container and the container may have logged some operation already, \r
+               // then we need to log allocation regardless of whether user changes\r
+               // are logged.  Otherwise, the database will be corrupted if it\r
+               // crashed. \r
+               if ((mode & ContainerHandle.MODE_CREATE_UNLOGGED) == 0 &&\r
+                       (mode & ContainerHandle.MODE_UNLOGGED) ==\r
+                                               ContainerHandle.MODE_UNLOGGED) \r
+                       mode &= ~ContainerHandle.MODE_UNLOGGED;\r
+\r
+               // make a handle which is tied to the ntt, not to the user transaction \r
+        // this handle is tied to.  The container is already locked by the \r
+        // user transaction, open it nolock\r
+               BaseContainerHandle allocHandle = (BaseContainerHandle)\r
+            ntt.openContainer(identity, (LockingPolicy)null, mode);\r
+\r
+               if (allocHandle == null)\r
+        {\r
+                       throw StandardException.newException(\r
+                    SQLState.DATA_ALLOC_NTT_CANT_OPEN, \r
+                    new Long(getSegmentId()), \r
+                    new Long(getContainerId()));\r
+        }\r
+\r
+               CompatibilitySpace cs = ntt.getCompatibilitySpace();\r
+               // Latch this container, the commit will release the latch\r
+               ntt.getLockFactory().lockObject(\r
+                cs, ntt, this, null, C_LockFactory.WAIT_FOREVER);\r
+\r
+               try\r
+               {\r
+            incrementReusableRecordIdSequenceNumber();                                         \r
+            compressContainer(ntt, allocHandle);\r
+               }\r
+               finally\r
+               {\r
+            ntt.commit();\r
+\r
+                       ntt.close();\r
+               }\r
+    }\r
+\r
+       /**\r
+        * Get the reusable RecordId sequence number for the\r
+        * container. This sequence number should be incremented every time\r
+        * there is an operation which may cause RecorIds to be reused.\r
+        * This method can be used by clients to check if a RecordId they \r
+        * obtained is still guaranteed to be valid.\r
+        * If the sequence number has changed, the RecordId may have been\r
+        * reused for another row.\r
+        * @return sequence number for reusable RecordId\r
+        */\r
+       public abstract long getReusableRecordIdSequenceNumber();\r
+\r
+       /**\r
+        * Increment the reusable RecordId sequence number.\r
+        */\r
+       protected abstract void incrementReusableRecordIdSequenceNumber();\r
+       \r
+\r
+       /**\r
+               Add a page to this container.\r
+\r
+               <BR> MT - thread aware - \r
+\r
+               The add page operation involves 2 transactions, one is the user\r
+               transaction (the transaction which owns the passed in handle), the\r
+               other one is a NestedTopTransaction created by this BaseContainer.\r
+\r
+               The nestedTopTransaction is used by the underlying container to change\r
+               high contention structures, such as link list anchor or bit map pages.\r
+               The nestedTopTransaction commits or aborts before this routine returns.\r
+\r
+               The user transaction is used to latch the newly created page.\r
+\r
+               @exception StandardException Standard Derby error policy\r
+       */\r
+       public Page addPage(BaseContainerHandle handle, boolean isOverflow) throws StandardException {\r
+               \r
+               RawTransaction ntt = handle.getTransaction().startNestedTopTransaction();\r
+\r
+               int mode = handle.getMode(); \r
+\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       SanityManager.ASSERT((mode & ContainerHandle.MODE_FORUPDATE) ==\r
+                                                                ContainerHandle.MODE_FORUPDATE, \r
+                                                                "addPage handle not for update");\r
+               }\r
+\r
+               // if we are not in the same transaction as the one which created the\r
+               // container and the container may have logged some operation already, \r
+               // then we need to log allocation regardless of whether user changes\r
+               // are logged.  Otherwise, the database will be corrupted if it\r
+               // crashed. \r
+               if ((mode & ContainerHandle.MODE_CREATE_UNLOGGED) == 0 &&\r
+                       (mode & ContainerHandle.MODE_UNLOGGED) ==\r
+                                               ContainerHandle.MODE_UNLOGGED) \r
+                       mode &= ~ContainerHandle.MODE_UNLOGGED;\r
+\r
+               // make a handle which is tied to the ntt, not to the user transaction this\r
+               // handle is tied to.  The container is already locked by the user transaction,\r
+               // open it nolock\r
+               BaseContainerHandle allocHandle = (BaseContainerHandle)ntt.openContainer\r
+                       (identity, (LockingPolicy)null, mode);\r
+\r
+               if (allocHandle == null)\r
+        {\r
+                       throw StandardException.newException(\r
+                    SQLState.DATA_ALLOC_NTT_CANT_OPEN, \r
+                    new Long(getSegmentId()), \r
+                    new Long(getContainerId()));\r
+        }\r
+\r
+               // Latch this container, the commit will release the latch\r
+               CompatibilitySpace cs = ntt.getCompatibilitySpace();\r
+               ntt.getLockFactory().lockObject(\r
+                cs, ntt, this, null, C_LockFactory.WAIT_FOREVER);\r
+\r
+               BasePage newPage = null;\r
+               try\r
+               {\r
+                       newPage = newPage(handle, ntt, allocHandle, isOverflow);\r
+               }\r
+               finally\r
+               {\r
+                       if (newPage != null)\r
+            {\r
+                // it is ok to commit without syncing, as it is ok if this\r
+                // transaction never makes it to the db, if no subsequent\r
+                // log record makes it to the log.  If any subsequent log\r
+                // record is sync'd then this transaction will be sync'd\r
+                // as well.\r
+                               ntt.commitNoSync(Transaction.RELEASE_LOCKS);\r
+            }\r
+                       else\r
+            {      \r
+                               ntt.abort();\r
+            }\r
+                       ntt.close();\r
+               }\r
+\r
+               if (SanityManager.DEBUG) {\r
+                       SanityManager.ASSERT(newPage.isLatched());\r
+               }\r
+\r
+               if (!this.identity.equals(newPage.getPageId().getContainerId())) {\r
+\r
+                       if (SanityManager.DEBUG) {\r
+                               SanityManager.THROWASSERT("BaseContainer.addPage(), just got a new page from a different container"\r
+                                       + "\n this.identity = " + this.identity\r
+                                       + "\n newPage.getPageId().getContainerId() = " + newPage.getPageId().getContainerId()\r
+                                       + "\n handle is: " + handle\r
+                                       + "\n allocHandle is: " + allocHandle\r
+                                       + "\n this container is: " + this);\r
+                       }\r
+\r
+                       throw StandardException.newException(\r
+                    SQLState.DATA_DIFFERENT_CONTAINER,\r
+                    this.identity, newPage.getPageId().getContainerId());\r
+               }\r
+\r
+               return newPage;\r
+       }\r
+\r
+    /**\r
+     * Request the system properties associated with a container.\r
+     * <p>\r
+     * Request the value of properties that are associated with a container.  \r
+     * The following properties can be requested:\r
+     *     derby.storage.pageSize \r
+     *     derby.storage.pageReservedSpace\r
+     *     derby.storage.minimumRecordSize\r
+     * <p>\r
+     * To get the value of a particular property add it to the property list,\r
+     * and on return the value of the property will be set to it's current \r
+     * value.  For example:\r
+     *\r
+     * get_prop(BaseContainer base)\r
+     * {\r
+     *     Properties prop = new Properties();\r
+     *     prop.put("derby.storage.pageSize", "");\r
+     *     base.getContainerProperties(prop);\r
+     *\r
+     *     System.out.println(\r
+     *         "container's page size = " + \r
+     *         prop.getProperty("derby.storage.pageSize");\r
+     * }\r
+     *\r
+     * @param prop   Property list to fill in.\r
+     *\r
+        * @exception  StandardException  Standard exception policy.\r
+     **/\r
+    public abstract void getContainerProperties(Properties prop)\r
+               throws StandardException;\r
+\r
+       /**\r
+               Remove a page from this container.  The page will be unlatched by this\r
+               routine before it returns.\r
+\r
+               Unlike addPage, this method done as part of the user transaction.  \r
+               The removed page is not usable by anyone until the user transaction \r
+        comits.\r
+               If the user transaction rolls back, the removed page is un-removed.\r
+\r
+               <BR> MT - thread aware -\r
+\r
+               @param handle the container handle that has opened the container and latched the page\r
+               @param page the latched page that is to be deallocated\r
+\r
+               @exception StandardException Standard Derby error policy\r
+       */\r
+       protected void removePage(BaseContainerHandle handle, BasePage page) \r
+                throws StandardException\r
+       {\r
+               try\r
+               {\r
+                       if (SanityManager.DEBUG)\r
+                       {\r
+                               SanityManager.ASSERT(page.isLatched(), "page is not latched");\r
+                       }\r
+\r
+                       // get dealloc lock nowait on the page to be deallocated\r
+                       // this lock is held until this transaction commits.\r
+                       // then gc can free this page\r
+                       RecordHandle deallocLock = \r
+                               page.makeRecordHandle(RecordHandle.DEALLOCATE_PROTECTION_HANDLE);\r
+\r
+                       // don't get deallocLock wait because caller have a page latched\r
+                       if (!getDeallocLock(handle, deallocLock, \r
+                                                               false /* no wait */,\r
+                                                               false /* not zeroDuration */))\r
+            {\r
+                               throw StandardException.newException(\r
+                        SQLState.DATA_CANNOT_GET_DEALLOC_LOCK, \r
+                        page.getIdentity());\r
+            }\r
+\r
+                       deallocatePage(handle, page);\r
+               }\r
+               finally\r
+               {\r
+                       if (page != null)\r
+                               page.unlatch();\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+               Get the special dealloc lock on the page - the lock is gotten by the\r
+               transaction that owns the container handle\r
+\r
+               @exception StandardException Standard Derby error policy\r
+       */\r
+       protected boolean getDeallocLock(BaseContainerHandle handle, \r
+                                                                        RecordHandle deallocLock, \r
+                                                                        boolean wait,\r
+                                                                        boolean zeroDuration)\r
+                throws StandardException\r
+       {\r
+               // get deallocate lock on page so that the GC won't attempt to \r
+               // free and re-allocate it until the transaction commits\r
+               RawTransaction tran = handle.getTransaction();\r
+\r
+               LockingPolicy lp = \r
+            tran.newLockingPolicy(\r
+                LockingPolicy.MODE_RECORD,\r
+                TransactionController.ISOLATION_REPEATABLE_READ, \r
+                true); // striterOK\r
+               \r
+               PageKey pkey = new PageKey(identity, deallocLock.getPageNumber());\r
+               if (lp != null)\r
+        {\r
+                       if (zeroDuration)\r
+                               return lp.zeroDurationLockRecordForWrite(\r
+                        tran, deallocLock, false, wait); \r
+                       else\r
+                               return lp.lockRecordForWrite(tran, deallocLock, false, wait);\r
+        }\r
+               else\r
+               {\r
+                       throw StandardException.newException(\r
+                    SQLState.DATA_CANNOT_GET_DEALLOC_LOCK, pkey);\r
+               }\r
+       }\r
+\r
+\r
+       /**\r
+               Get an allocation page and latch it.\r
+               @exception StandardException Standard Derby error policy\r
+       */\r
+       protected Page getAllocPage(BaseContainerHandle handle, long pageNumber, boolean wait)\r
+                throws StandardException\r
+       {\r
+               return latchPage(handle, getAllocPage(pageNumber), wait);\r
+       }\r
+\r
+       /**\r
+               Get any page and latch it .\r
+               @exception StandardException Standard Derby error policy\r
+       */\r
+       protected Page getAnyPage(BaseContainerHandle handle, long pageNumber, boolean wait)\r
+                throws StandardException\r
+       {\r
+               return latchPage(handle, getAnyPage(handle, pageNumber), wait);\r
+       }\r
+\r
+\r
+       /**\r
+               Get the first valid page. Result is latched.\r
+               @exception StandardException Standard Derby error policy\r
+       */\r
+       protected Page getFirstPage(BaseContainerHandle handle) throws StandardException\r
+       {\r
+               return getFirstHeadPage(handle, true /* wait */);\r
+       }\r
+\r
+       /**\r
+               Get the next valid page and latch it\r
+               @exception StandardException Standard Derby error policy\r
+       */\r
+       protected Page getNextPage(BaseContainerHandle handle, long pageNumber)\r
+        throws StandardException\r
+       {\r
+               return getNextHeadPage(handle, pageNumber, true /* wait */);\r
+       }\r
+\r
+       /*\r
+               utility to latch a page\r
+       */\r
+       protected BasePage latchPage(BaseContainerHandle handle, BasePage foundPage, boolean wait)\r
+                throws StandardException\r
+       {\r
+               if (foundPage != null) {\r
+                        if (wait) {\r
+                               foundPage.setExclusive(handle);\r
+                        } else {\r
+                                if (!foundPage.setExclusiveNoWait(handle))\r
+                                {\r
+                                        // sub-class will release page from the cache if required.\r
+                                        return null;\r
+                                }\r
+                        }\r
+               }\r
+\r
+               if (SanityManager.DEBUG) {\r
+                       SanityManager.ASSERT((foundPage == null) || foundPage.isLatched());\r
+               }\r
+\r
+               return foundPage;\r
+\r
+       }\r
+\r
+\r
+       /**\r
+               Lock the container and mark the container as in-use by this container handle.\r
+\r
+               @param droppedOK if true, use this container even if it is dropped.,\r
+               @return true if the container can be used, false if it has been dropped\r
+               since the lock was requested and droppedOK is not true.\r
+\r
+               @exception StandardException I cannot be opened for update.\r
+       */\r
+       protected boolean use(BaseContainerHandle handle, boolean forUpdate,\r
+                                                 boolean droppedOK) \r
+               throws StandardException {\r
+\r
+               // see if the container can be updated\r
+               if (forUpdate && !canUpdate())\r
+        {\r
+                       throw StandardException.newException(\r
+                    SQLState.DATA_CONTAINER_READ_ONLY);\r
+        }\r
+\r
+               // if the container is dropped, cannot see if unless droppedOK is set\r
+               if (!droppedOK && (getDroppedState() || getCommittedDropState())) {\r
+                       return false;\r
+               }\r
+\r
+               return true;\r
+       }\r
+\r
+       /**\r
+               Discontinue use of this container. Note that the unlockContainer\r
+               call made from this method may not release any locks. The container\r
+               lock may be held until the end of the transaction.\r
+\r
+       */\r
+       protected void letGo(BaseContainerHandle handle) {\r
+\r
+               RawTransaction t = handle.getTransaction();\r
+\r
+               handle.getLockingPolicy().unlockContainer(t, handle);\r
+       }\r
+\r
+       protected boolean getDroppedState() {\r
+               return isDropped;\r
+       }\r
+\r
+       protected boolean getCommittedDropState()\r
+       {\r
+               return isCommittedDrop;\r
+       }\r
+\r
+\r
+       protected boolean isReusableRecordId()\r
+       {\r
+               return isReusableRecordId;\r
+       }\r
+\r
+       public int getContainerStatus()\r
+       {\r
+               if (getCommittedDropState())\r
+                       return RawContainerHandle.COMMITTED_DROP;\r
+\r
+               if (getDroppedState())\r
+                       return RawContainerHandle.DROPPED;\r
+\r
+               return RawContainerHandle.NORMAL;\r
+       }\r
+\r
+       public long getContainerId() {\r
+               return identity.getContainerId();\r
+       }\r
+\r
+       public long getSegmentId() {\r
+               return identity.getSegmentId();\r
+       }\r
+\r
+\r
+       //public int getPageSize() {\r
+       //      return pageSize();\r
+       //}\r
+\r
+       /*\r
+       **      Methods that need to be provided by a sub-class.\r
+       */\r
+\r
+    /**\r
+    Get information about space used by the container.\r
+    **/\r
+    protected abstract SpaceInfo getSpaceInfo(BaseContainerHandle handle)\r
+        throws StandardException;\r
+\r
+       /**\r
+               Can the container be updated.\r
+\r
+               @return true if the container can be updated, false otherwise.\r
+       */\r
+       protected abstract boolean canUpdate();\r
+\r
+       /**\r
+               The container is about to be modified.\r
+               Loggable actions use this to make sure the container gets cleaned if a\r
+               checkpoint is taken after any log record is sent to the log stream but\r
+               before the container is actually dirtied.\r
+        */\r
+       protected abstract void preDirty(boolean preDirtyOn);\r
+\r
+\r
+       /**\r
+               Return a BasePage that represents the given page number in this container.\r
+        The resulting page is latched.\r
+\r
+               @exception StandardException Standard Derby error policy\r
+       */\r
+       protected abstract BasePage getPage(BaseContainerHandle handle, long pageNumber,\r
+        boolean wait) throws StandardException;\r
+\r
+       /**\r
+               Return a BasePage that represents the given alloc page number in this container.\r
+\r
+               @exception StandardException Standard Derby error policy\r
+       */\r
+       protected abstract BasePage getAllocPage(long pageNumber) throws StandardException;\r
+\r
+       /**\r
+               Return a BasePage that represents any page - alloc page, valid page, free page,\r
+               dealloced page etc.  The only requirement is that the page is initialized...\r
+\r
+               @exception StandardException Derby Standard error policy\r
+       */\r
+       protected abstract BasePage getAnyPage(BaseContainerHandle handle, long pageNumber)\r
+                throws StandardException;\r
+\r
+    /**\r
+     * ReCreate a page for rollforward recovery.  \r
+     * <p>\r
+     * During redo recovery it is possible for the system to try to redo\r
+     * the creation of a page (ie. going from non-existence to version 0).\r
+     * It first trys to read the page from disk, but a few different types\r
+     * of errors can occur:\r
+     *     o the page does not exist at all on disk, this can happen during\r
+     *       rollforward recovery applied to a backup where the file was\r
+     *       copied and the page was added to the file during the time frame\r
+     *       of the backup but after the physical file was copied.\r
+     *     o space in the file exists, but it was never initalized.  This\r
+     *       can happen if you happen to crash at just the right moment during\r
+     *       the allocation process.  Also\r
+     *       on some OS's it is possible to read from a part of the file that\r
+     *       was not ever written - resulting in garbage from the store's \r
+     *       point of view (often the result is all 0's).  \r
+     *\r
+     * All these errors are easy to recover from as the system can easily \r
+     * create a version 0 from scratch and write it to disk.\r
+     *\r
+     * Because the system does not sync allocation of data pages, it is also\r
+     * possible at this point that whlie writing the version 0 to disk to \r
+     * create it we may encounter an out of disk space error (caught in this\r
+     * routine as a StandardException from the create() call.  We can't \r
+     * recovery from this without help from outside, so the caught exception\r
+     * is nested and a new exception thrown which the recovery system will\r
+     * output to the user asking them to check their disk for space/errors.\r
+     *\r
+     * The arguments passed in need to be sufficient for the page cache to \r
+     * materialize a brand new page and write it to disk.  \r
+     *\r
+        * @exception  StandardException  Standard exception policy.\r
+     **/\r
+       protected abstract BasePage\r
+       reCreatePageForRedoRecovery(\r
+    BaseContainerHandle handle,\r
+    int pageFormat,\r
+    long pageNumber,\r
+    long pageOffset)\r
+                throws StandardException;\r
+\r
+       /**\r
+               Log all information on the container creation necessary to recreate teh\r
+               container during a load tran.\r
+\r
+               @exception StandardException Derby Standard error policy\r
+        */\r
+        protected abstract ByteArray logCreateContainerInfo()\r
+                throws StandardException;\r
+\r
+\r
+       /**\r
+               Get only a valid, non-overflow page.  If page number is either invalid\r
+               or overflow, returns null\r
+\r
+               @exception StandardException Derby Standard error policy\r
+        */\r
+       protected abstract BasePage getHeadPage(BaseContainerHandle handle,\r
+        long pagenumber, boolean wait) throws StandardException;\r
+\r
+       /**\r
+               Get the first page in the container.\r
+               @exception StandardException Standard Derby error policy\r
+       */\r
+       protected abstract BasePage getFirstHeadPage(BaseContainerHandle handle,\r
+        boolean wait) throws StandardException;\r
+\r
+       /**\r
+               Get the next page in the container.\r
+               @exception StandardException Standard Derby error policy\r
+       */\r
+       protected abstract BasePage getNextHeadPage(BaseContainerHandle handle,\r
+        long pageNumber, boolean wait) throws StandardException;\r
+\r
+       /**\r
+               Get a potentially suitable page for insert and latch it.\r
+               @exception StandardException Standard Derby error policy\r
+        */\r
+       protected abstract BasePage getPageForInsert(BaseContainerHandle handle,\r
+                                                                                                int flag)\r
+                throws StandardException;\r
+\r
+       protected abstract BasePage getPageForCompress(\r
+    BaseContainerHandle handle,\r
+    int                 flag,\r
+    long                pageno)\r
+                throws StandardException;\r
+\r
+       protected abstract void truncatePages(long lastValidPagenum)\r
+        throws StandardException;\r
+\r
+\r
+       /**\r
+               Create a new page in the container.\r
+\r
+               @exception StandardException Standard Derby error policy\r
+       */\r
+       protected abstract BasePage newPage(BaseContainerHandle userhandle,\r
+                                                                               RawTransaction t,\r
+                                                                               BaseContainerHandle allocHandle,\r
+                                                                               boolean isOverflow) throws StandardException;\r
+\r
+       protected abstract void compressContainer(\r
+    RawTransaction      t,\r
+    BaseContainerHandle allocHandle)\r
+        throws StandardException;\r
+\r
+\r
+       /**\r
+               Deallocate a page from the container.\r
+\r
+               @exception StandardException Standard Derby error policy\r
+       */\r
+       protected abstract void deallocatePage(BaseContainerHandle userhandle,\r
+                                                                                  BasePage page) throws StandardException;\r
+\r
+\r
+       protected void truncate(BaseContainerHandle handle) throws StandardException {\r
+               if (SanityManager.DEBUG) {\r
+                       SanityManager.THROWASSERT("truncate not supported");\r
+               }\r
+       }\r
+\r
+       /**\r
+               Mark the container as drop or not drop depending on the input value.\r
+\r
+       */\r
+       protected abstract void dropContainer(LogInstant instant, boolean drop);\r
+\r
+\r
+       /**\r
+               Remove the container and reclaim its space.  Once executed, this\r
+               operation cannot be undone - as opposed to dropContainer which only\r
+               marks the container as dropped and can be rolled back.\r
+               <BR><B> This operation should only be called by post commit clean up </B>\r
+\r
+               @param leaveStub if true, leave a stub.  If false, remove everything\r
+               @see org.apache.derby.iapi.store.raw.data.RawContainerHandle#removeContainer\r
+\r
+               @exception StandardException Standard Derby error policy\r
+       */\r
+       protected abstract void removeContainer(LogInstant instant, boolean leaveStub) throws StandardException;\r
+\r
+       /**\r
+               Get the logged container version.\r
+\r
+               @exception StandardException Standard Derby error policy\r
+       */\r
+       protected abstract long getContainerVersion() throws StandardException;\r
+\r
+       /**\r
+               Flush all outstanding changes in this container to persistent storage.\r
+\r
+               @exception StandardException Standard Derby error policy\r
+       */\r
+       protected abstract void flushAll() throws StandardException;\r
+\r
+       /**\r
+               The container will be grown vastly, prepare for it.\r
+       */\r
+       protected abstract void prepareForBulkLoad(BaseContainerHandle handle,\r
+                                                                                          int numPage);\r
+\r
+       /**\r
+               The container will have no pre-allocate threshold, i.e., if the\r
+               implementation supports it, page preallocation will happen\r
+               the next time a new page is allocated.\r
+       */\r
+       protected abstract void clearPreallocThreshold();\r
+\r
+       /*\r
+               Cost estimates\r
+       */\r
+       /**\r
+               @see ContainerHandle#getEstimatedRowCount\r
+               @exception StandardException Standard Derby error policy\r
+        */\r
+       public abstract long getEstimatedRowCount(int flag) throws StandardException;\r
+\r
+       /**\r
+               @see ContainerHandle#setEstimatedRowCount\r
+               @exception StandardException Standard Derby error policy\r
+        */\r
+       public abstract void setEstimatedRowCount(long count, int flag) throws StandardException;\r
+\r
+       /**\r
+               @see ContainerHandle#getEstimatedPageCount\r
+               @exception StandardException Standard Derby error policy\r
+        */\r
+       public abstract long getEstimatedPageCount(BaseContainerHandle handle, int flag) throws StandardException;\r
+\r
+       /**\r
+     * Backup the container to the specified path.\r
+     * \r
+     * @param handle the container handle.\r
+     * @param backupContainerPath  location of the backup container. \r
+     * @exception StandardException Standard Derby error policy \r
+     */\r
+       protected abstract void  backupContainer(BaseContainerHandle handle, \r
+                                                                                        String backupContainerPath) throws StandardException ;\r
+\r
+\r
+    /**\r
+     * Create encrypted version of the  container with the \r
+     * user specified encryption properties. \r
+     *\r
+     * @param handle the container handle.\r
+     * @param newFilePath file to store the new encrypted version of the container\r
+     * @exception StandardException Standard Derby error policy \r
+     */\r
+       protected abstract void  encryptContainer(BaseContainerHandle handle, \r
+                                              String newFilePath) \r
+        throws StandardException ;\r
+\r
+\r
+       /*\r
+       ** Methods to be used by sub-classes.\r
+       */\r
+\r
+       /**\r
+               Set the container's dropped state\r
+       */\r
+       protected void setDroppedState(boolean isDropped) {\r
+               this.isDropped = isDropped;\r
+       }\r
+\r
+       protected void setCommittedDropState(boolean isCommittedDrop)\r
+       {\r
+               this.isCommittedDrop = isCommittedDrop;\r
+       }\r
+\r
+\r
+       protected void setReusableRecordIdState(boolean isReusableRecordId)\r
+       {\r
+               this.isReusableRecordId = isReusableRecordId;\r
+       }\r
+\r
+       //protected void setPageSize(int pageSize) {\r
+       //      identity.setPageSize(pageSize);\r
+       //}\r
+\r
+       // Not interested in participating in the diagnostic virtual lock table.\r
+       public boolean lockAttributes(int flag, Hashtable attributes)\r
+       {\r
+               return false;\r
+       }\r
+\r
+       \r
+\r
+}\r
+\r