--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.iapi.store.raw.ContainerHandle\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.iapi.store.raw;\r
+\r
+import org.apache.derby.iapi.store.access.SpaceInfo;\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+import java.util.Properties;\r
+\r
+/**\r
+ A Container contains a contigious address space of pages, the pages\r
+ start at page number Container.FIRST_PAGE_NUMBER and are numbered sequentially.\r
+ \r
+ The page size is set at addContainer() time.\r
+\r
+\r
+ RESOLVE: this style of coding is not currently enforced\r
+ If the caller calls getPage (or one of its variants) more than once on the \r
+ same page, the caller must call unlatch a corresponding number of times in \r
+ order to ensure that the page is latched. For example:\r
+ <p>\r
+ <blockquote><pre>\r
+ Container c;\r
+ Page p1 = c.getPage(Container.FIRST_PAGE_NUMBER);\r
+ Page p2 = c.getPage(Container.FIRST_PAGE_NUMBER);\r
+ p1.unlatch(); -- Page is still latched.\r
+ p2.unlatch(); -- Page is now unlatched.\r
+ </pre></blockquote>\r
+\r
+ <p>\r
+ There is no restriction on the order in which latching and unlatching is \r
+ done. In the example, p1 could have been unlatched after p2 with no ill \r
+ effects.\r
+\r
+ <P> <B>Open container modes</B>\r
+ ContainerHandle.MODE are used to open or create the container.\r
+ Unlike TableProperties, MODEs are not permanantely associated with the\r
+ container, it is effective only for the lifetime of the containerHandle\r
+ itself.\r
+ <BR>A container may use any of these mode flags when it is opened.\r
+ <UL>\r
+ <LI>MODE_READONLY - Open the container in read only mode.\r
+ <LI>MODE_FORUPDATE - Open the container in update mode, if the underlying \r
+ storage does not allow updates\r
+ then the container will be opned in read only mode.\r
+ <LI>MODE_UNLOGGED - If Unset, any changes to the container are logged.\r
+ If set, any user changes to the container are unlogged. It is guaranteed\r
+ at commit time that all changes made during the transaction will have been \r
+ flushed to disk. Using this mode automatically opens the container in \r
+ container locking, isolation 3 level. The state of the container following\r
+ an abort or any type of rollback is unspecified.\r
+ <LI>MODE_CREATE_UNLOGGED - If set, not only are user changes to the\r
+ container are unlogged, page allocations are also unlogged. This MODE is\r
+ only useful for container is created in the same statement and no change on\r
+ the container (other than the create) is ever logged. The difference\r
+ between MODE_UNLOGGED and MODE_CREATE_UNLOGGED is that page allocation is\r
+ also unlogged and commit of nested transaction will not cause the container\r
+ to be forced from the cache. Unlike MODE_UNLOGGED, MODE_CREATE_UNLOGGED\r
+ does not force the cache. It is up to the client of raw store to force the\r
+ cache at the appropriate time - this allows a statement to create and open\r
+ the container serveral times for bulk loading without logging or doing any\r
+ synchronous I/O. \r
+ <LI>MODE_LOCK_NOWAIT - if set, then don't wait for the container lock, else\r
+ wait for the container lock. This flag only dictates whether the lock\r
+ should be waited for or not. After the container is successfully opened,\r
+ whether this bit is set or not has no effect on the container handle.\r
+ </UL>\r
+ If neither or both of the {MODE_READONLY, MODE_FORUPDATE} modes are \r
+ specified then the behaviour of the container is unspecified.\r
+ <BR>\r
+ MODE_UNLOGGED must be set for MODE_CREATE_UNLOGGED to be set.\r
+ <P>\r
+ <B>Temporary Containers</B><BR>\r
+ If when creating a container the segment used is \r
+ ContainerHandle.TEMPORARY_SEGMENT then the container is a temporary \r
+ container. Temporary containers are not logged or locked and do not live \r
+ across re-boots of the system. In addition any abort or rollback including\r
+ rollbacks to savepoints truncate the container if it has been opened for \r
+ update since the last commit or abort. Temporary containers are private \r
+ to a transaction and must only be used a single thread within the \r
+ transaction at any time, these restrictions are not currently enforced.\r
+ <BR>\r
+ When opening a temporary container for update access these additional mode\r
+ flags may be used\r
+ <UL>\r
+ <LI> MODE_TRUNCATE_ON_COMMIT - At commit/abort time container is truncated.\r
+ <LI> MODE_DROP_ON_COMMIT - At commit/abort time the container is dropped.\r
+ <LI> MODE_TEMP_IS_KEPT - At commit/abort time the container is kept around.\r
+ </UL>\r
+ If a temporary container is opened multiple times in the same transaction \r
+ with different modes then the most severe mode is used, ie. none < \r
+ truncate on commit < drop on commit.\r
+ The MODE_UNLOGGED, MODE_CREAT_UNLOGGED flags are ignored when opening a \r
+ temporary container, not logged is always assumed. */\r
+\r
+public interface ContainerHandle \r
+{\r
+\r
+ /**\r
+ Used in add container.\r
+ */\r
+ public static final int DEFAULT_PAGESIZE = -1;\r
+\r
+ public static final int DEFAULT_SPARESPACE = -1;\r
+\r
+ public static final int DEFAULT_ASSIGN_ID = 0;\r
+\r
+ /**\r
+ See comments above for these modes.\r
+ */\r
+ public static final int MODE_DEFAULT = 0x00000000;\r
+ public static final int MODE_UNLOGGED = 0x00000001;\r
+ public static final int MODE_CREATE_UNLOGGED = 0x00000002;\r
+ public static final int MODE_FORUPDATE = 0x00000004;\r
+ public static final int MODE_READONLY = 0x00000008;\r
+ public static final int MODE_TRUNCATE_ON_COMMIT = 0x00000010;\r
+ public static final int MODE_DROP_ON_COMMIT = 0x00000020;\r
+ public static final int MODE_OPEN_FOR_LOCK_ONLY = 0x00000040;\r
+ public static final int MODE_LOCK_NOWAIT = 0x00000080;\r
+ public static final int MODE_TRUNCATE_ON_ROLLBACK = 0x00000100; // internal raw store\r
+ public static final int MODE_FLUSH_ON_COMMIT = 0x00000200; // internal raw store\r
+ public static final int MODE_NO_ACTIONS_ON_COMMIT = 0x00000400; // internal raw store\r
+ public static final int MODE_TEMP_IS_KEPT = 0x00000800; // internal raw store\r
+\r
+ public static final int MODE_USE_UPDATE_LOCKS = 0x00001000; // external access\r
+ public static final int MODE_SECONDARY_LOCKED = 0x00002000; // external access\r
+ public static final int MODE_BASEROW_INSERT_LOCKED = 0x00004000; // external access\r
+\r
+ public static final int TEMPORARY_SEGMENT = -1;\r
+\r
+\r
+ /**\r
+ The first valid page number\r
+ */\r
+ public static final long FIRST_PAGE_NUMBER = 1;\r
+ \r
+ /**\r
+ A page number that is guaranteed to be invalid.\r
+ */\r
+ public static final long INVALID_PAGE_NUMBER = -1;\r
+\r
+ /**\r
+ Return my identifier.\r
+ */\r
+ public ContainerKey getId();\r
+\r
+ /**\r
+ Return my unique identifier, this identifier will be unique to each\r
+ instance of an open container handle. This id is used by the locking\r
+ system to group locks to an open container handle.\r
+ */\r
+ public Object getUniqueId();\r
+\r
+ /**\r
+ * Is the container opened for read only or update?\r
+ *\r
+ * @return true if container is opened for read only, else false.\r
+ **/\r
+ boolean isReadOnly();\r
+\r
+ /**\r
+ Add an empty page to the container and obtain exclusive access to it.\r
+ <P>\r
+ Note that the added page may not be the last page in the Container.\r
+\r
+ Once the Page is no longer required the Page's unlatch() method must \r
+ be called.\r
+\r
+ @return a reference to the page that was added.\r
+\r
+ @see Page#unlatch\r
+\r
+ @exception StandardException Standard Derby error policy\r
+ @exception StandardException If a page could not be allocated.\r
+ */\r
+ public Page addPage() throws StandardException;\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() throws StandardException;\r
+\r
+ /**\r
+ * Get the reusable recordId sequence number.\r
+ * @return version sequence number\r
+ * @exception StandardException Standard Derby error policy\r
+ */\r
+ public long getReusableRecordIdSequenceNumber() throws StandardException;\r
+\r
+ /** \r
+ Add an empty page to the container and obtain exclusive access to it.\r
+ <P>\r
+ If flag == ADD_PAGE_DEFAULT, this call is identical to addPage().\r
+ <BR>\r
+ If flag == ADD_PAGE_BULK, then this call signifies to the container that\r
+ this addPage is part of a large number of additional pages and it is\r
+ desirable to do whatever possible to facilitate adding many subsequent pages.\r
+ The actual container implementation will decide whether or not to heed\r
+ this hint and what to do about it.\r
+\r
+ @return a reference to the page that was added.\r
+\r
+ @see Page#unlatch\r
+\r
+ @exception StandardException Standard Derby error policy\r
+ @exception StandardException If a page could not be allocated.\r
+\r
+ */\r
+ public Page addPage(int flag) throws StandardException;\r
+ public static final int ADD_PAGE_DEFAULT = 0x1;\r
+ public static final int ADD_PAGE_BULK = 0x2;\r
+\r
+\r
+ /**\r
+ Try to preallocate numPage new pages if possible.\r
+ */\r
+ public void preAllocate(int numPage);\r
+\r
+\r
+ /**\r
+ Remove this page from the container and unlatch the page. <B>Caller\r
+ should commit or abort this transaction ASAP because failure to do so\r
+ will slow down page allocation of this container. </B>\r
+\r
+ <BR>The page to be removed must be latched and gotten (or added) by\r
+ this ContainerHandle. The page should not be used again after this\r
+ call as if it has been unlatched. If the call to removePage is\r
+ successful, this page is invalid should not be gotten again with\r
+ getPage. \r
+\r
+ <BR>RemovePage will guarantee to unlatch the page even if a\r
+ StandardException is thrown. \r
+\r
+ <P>\r
+ <B>Locking Policy</B>\r
+ <BR>\r
+ The page will not be freed until the transaction that removed the page \r
+ commits. A special RecordHandle.DEALLOC_PROTECTION_HANDLE lock will be \r
+ gotten for the transaction and which is used to prevent the page from \r
+ being freed. This lock will be held regardless of the default locking \r
+ policy of the transaction that called removedPage.\r
+\r
+ @see LockingPolicy\r
+ @see RecordHandle\r
+\r
+ @exception StandardException Standard Derby error policy \r
+ */\r
+ public void removePage(Page page) throws StandardException;\r
+\r
+\r
+ /**\r
+ Obtain exclusive access to the page with the given page number.\r
+ \r
+ Once the Page is no longer required the Page's unlatch() method must \r
+ be called.\r
+\r
+ <P>\r
+ The Page object is guaranteed to remain in-memory and exclusive to the \r
+ caller until its unlatch() method is called.\r
+\r
+ @return the required Page or null if the page does not exist or is not \r
+ valid (i.e, it has been deallocated or freed or never initialized)\r
+ Note that an overflow page will be returned since it is a valid page.\r
+\r
+ @exception StandardException Standard Derby error policy\r
+ */\r
+ public Page getPage(long pageNumber)\r
+ throws StandardException;\r
+\r
+ /**\r
+ Identical to getPage but returns null immediately if the desired page\r
+ is already latched by another Container.\r
+\r
+ @return the required Page or null if the page does not exist or the page\r
+ is already latched.\r
+\r
+ @exception StandardException Standard Derby error policy\r
+\r
+ */\r
+ public Page getPageNoWait(long pageNumber) throws StandardException;\r
+\r
+ /**\r
+ Obtain exclusive access to the page with the given page number.\r
+\r
+ Will only return a valid, non-overflow user page - so can be used by\r
+ routines in post commit to get pages to attempt deleted row space\r
+ reclamation. If for some reason a request is made for an overflow\r
+ page a null will be returned.\r
+\r
+ Once the Page is no longer required the Page's unlatch() method must \r
+ be called.\r
+\r
+ <P>\r
+ The Page object is guaranteed to remain in-memory and exclusive to the \r
+ caller until its unlatch() method is called.\r
+\r
+ @return the required Page or null if the page does not exist or is not \r
+ valid (i.e, it has been deallocated, freed, never initialized, or is\r
+ an allocation page or overflow page)\r
+\r
+ @exception StandardException Standard Derby error policy\r
+ */\r
+ public Page getUserPageNoWait(long pageNumber) throws StandardException;\r
+ /**\r
+ Obtain exclusive access to the page with the given page number.\r
+\r
+ Will only return a valid, non-overflow user page - so can be used by\r
+ routines in post commit to get pages to attempt deleted row space\r
+ reclamation. If for some reason a request is made for an overflow\r
+ page a null will be returned.\r
+\r
+ Once the Page is no longer required the Page's unlatch() method must \r
+ be called.\r
+\r
+ <P>\r
+ The Page object is guaranteed to remain in-memory and exclusive to the \r
+ caller until its unlatch() method is called.\r
+\r
+ @return the required Page or null if the page does not exist or is not \r
+ valid (i.e, it has been deallocated, freed, never initialized, or is\r
+ an allocation page or overflow page)\r
+\r
+ @exception StandardException Standard Derby error policy\r
+ */\r
+ public Page getUserPageWait(long pageNumber) throws StandardException;\r
+\r
+ /**\r
+ Obtain exclusive access to the current first page of the container.\r
+ Only a valid, non overflow page will be returned.\r
+ Pages in the container are ordered in an internally defined ordering.\r
+ <P>\r
+ Note that once this method returns this page may no longer be the \r
+ first page of the container. I.e, other threads may allocate pages \r
+ prior to this page number while this page is latched. It is up to\r
+ the caller of this routine to synchronize this call with addPage to \r
+ assure that this is the first page. \r
+ <BR>\r
+ As long as the client provide the necessary lock to ensure \r
+ that no addPage is called, then this page is guaranteed to be the\r
+ first page of the container in some internally defined ordering of\r
+ the pages.\r
+\r
+ @return latched page or null if there is no page in the container\r
+ @exception StandardException Standard Derby error policy\r
+\r
+ @see ContainerHandle#getPage\r
+ */\r
+ public Page getFirstPage() throws StandardException;\r
+\r
+ /**\r
+ Obtain exclusive access to the next valid page of the given page number \r
+ in the container. Only a valid, non overflow page will be returned.\r
+ Pages in the container are ordered in an internally defined ordering.\r
+ <P>\r
+ Note that once this method returns this page may no longer be the \r
+ next page of the container. I.e, other threads may allocate pages \r
+ prior to this page number while this page is latched. It is up to\r
+ the caller of this routine to synchronize this call with addPage to \r
+ assure that this is the first page. \r
+ <BR>\r
+ As long as the client provide the necessary lock to ensure \r
+ that no addPage is called, then this page is guaranteed to be the\r
+ next page of the container in some internally defined ordering of\r
+ the pages.\r
+ <BR>\r
+ If no pages are added or removed, then an iteration such as:\r
+ <PRE>\r
+ for (Page p = containerHandle.getFirstPage();\r
+ p != null;\r
+ p = containerHandle.getNextPage(p.getPageNumber()))\r
+ <PRE>\r
+ will guarentee to iterate thru and latched all the valid pages \r
+ in the container\r
+\r
+ @param prevNum the pagenumber of the page previous to the page\r
+ that is to be gotten. The page which correspond to prevNum\r
+ may or may not be latched by the caller, but it must be gotten \r
+ via a page which was (or currently still is) latched, and the page\r
+ number must be gotten while the container must not have been closed \r
+ or dropped or removed in the interim.\r
+\r
+ In other words, if the user manufactures a page number, or remembers \r
+ the page number from a previous session or a previous openContainer, \r
+ then the behavior of this routine is undefined.\r
+\r
+ @return latched page or null if there is no next page in the container\r
+ @exception StandardException Standard Derby error policy\r
+\r
+ @see ContainerHandle#getPage\r
+ */\r
+ public Page getNextPage(long prevNum) throws StandardException;\r
+\r
+\r
+ /**\r
+ Get a page for insert. If RawStore thinks it knows where a potentially\r
+ suitable page is for insert, it will return it. If RawStore doesn't\r
+ know where a suitable page for insert is, or if there are no allocated\r
+ page, then null is returned. If a page is returned, it will be a\r
+ valid, non-overflow page. A potentially suitable page is one which\r
+ has enough space for a minium sized record.\r
+\r
+ @return a valid, non-overflow page. Or null if RawStore doesn't know\r
+ where to find a good valid, non-overflow page.\r
+\r
+ @param flag a GET_PAGE_* flag.\r
+\r
+ @exception StandardException Standard Derby error policy \r
+ */\r
+ public Page getPageForInsert(int flag) \r
+ throws StandardException;\r
+\r
+ public Page getPageForCompress(\r
+ int flag,\r
+ long pageno) \r
+ throws StandardException;\r
+\r
+ // Try to get a page that is unfilled, 'unfill-ness' is defined by the\r
+ // page. Since unfill-ness is defined by the page, the only thing RawStore\r
+ // guarentees about the page is that it has space for a a minimum sized\r
+ // record.\r
+ //\r
+ // If this bit is not set, then getPageForInsert will get the page that was\r
+ // last gotten, provided it has space for a minimum sized record.\r
+ //\r
+ // If for whatever reasons RawStore is unable to come up with such a page,\r
+ // null will be returned.\r
+ public static final int GET_PAGE_UNFILLED = 0x1;\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 table. The\r
+ * 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(ConglomerateController cc)\r
+ * {\r
+ * Properties prop = new Properties();\r
+ * prop.put("derby.storage.pageSize", "");\r
+ * cc.getTableProperties(prop);\r
+ *\r
+ * System.out.println(\r
+ * "table'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
+ void getContainerProperties(Properties prop)\r
+ throws StandardException;\r
+\r
+ /**\r
+ Close me. After using this method the caller must throw away the\r
+ reference to the Container object, e.g.\r
+ <PRE>\r
+ ref.close();\r
+ ref = null;\r
+ </PRE>\r
+ <BR>\r
+ The container will be closed automatically at the commit or abort\r
+ of the transaction if this method is not called explictly.\r
+ <BR>\r
+ Any pages that were obtained using me and have not been released\r
+ using Page's unlatch method are released, and references to them must be\r
+ thrown away.\r
+\r
+\r
+ @see Page#unlatch\r
+ */\r
+ public void close();\r
+\r
+ /**\r
+ Cost estimation\r
+ */\r
+\r
+ /**\r
+ Get the total estimated number of rows in the container, not including\r
+ overflow rows. This number is a rough estimate and may be grossly off.\r
+\r
+ @param flag different flavors of row count (reserved for future use)\r
+ @exception StandardException Standard Derby error policy\r
+ */\r
+ public long getEstimatedRowCount(int flag) throws StandardException;\r
+\r
+ /**\r
+ Set the total estimated number of rows in the container. Often, after\r
+ a scan, the client of RawStore has a much better estimate of the number\r
+ of rows in the container then what RawStore has. Use this better\r
+ number for future reference.\r
+ <BR>\r
+ It is OK for a ReadOnly ContainerHandle to set the estimated row count.\r
+\r
+ @param count the estimated number of rows in the container.\r
+ @param flag different flavors of row count (reserved for future use)\r
+\r
+ @exception StandardException Standard Derby error policy\r
+ */\r
+ public void setEstimatedRowCount(long count, int flag) throws StandardException;\r
+\r
+ /**\r
+ Get the total estimated number of allocated (not freed, not\r
+ deallocated) user pages in the container, including overflow pages.\r
+ this number is a rough estimate and may be grossly off.\r
+\r
+ @param flag different flavors of page count (reserved for future use)\r
+\r
+ @exception StandardException Standard Derby error policy\r
+ */\r
+ public long getEstimatedPageCount(int flag) throws StandardException;\r
+\r
+\r
+ /**\r
+ Flush all dirty pages of the container to disk. Used mainly for\r
+ UNLOGGED or CREATE_UNLOGGED operation.\r
+\r
+ @exception StandardException Standard Derby error policy\r
+ */\r
+ public void flushContainer() throws StandardException;\r
+\r
+ /**\r
+ Return the locking policy for this open container.\r
+ */\r
+ public LockingPolicy getLockingPolicy();\r
+\r
+ /**\r
+ Set the locking policy for this open container\r
+ */\r
+ public void setLockingPolicy(LockingPolicy newLockingPolicy);\r
+\r
+ /**\r
+ Return a record handle that is initialized to the given segment id,\r
+ container id, page number and record id.\r
+\r
+ @exception StandardException Standard Derby exception policy.\r
+\r
+ @param pageNumber the page number of the RecordHandle.\r
+ @param recordId the record id of the RecordHandle.\r
+\r
+ @see RecordHandle\r
+ */\r
+ public RecordHandle makeRecordHandle(long pageNumber, int recordId)\r
+ throws StandardException;\r
+\r
+\r
+ /**\r
+ This record probably has shrunk considerably. Free its reserved space\r
+ or compact it.\r
+\r
+ @param record The record handle, the record must have been locked execlusively already.\r
+ @exception StandardException Standard Derby exception policy.\r
+ */\r
+ public void compactRecord(RecordHandle record) throws StandardException;\r
+\r
+ /**\r
+ Return true if this containerHandle refers to a temporary container.\r
+ @exception StandardException Standard Derby exception policy.\r
+ */\r
+ public boolean isTemporaryContainer() throws StandardException;\r
+\r
+ /**\r
+ Get information about space used by the container.\r
+ **/\r
+ public SpaceInfo getSpaceInfo() throws StandardException;\r
+\r
+ /**\r
+ Backup the container to the specified path.\r
+ @exception StandardException Standard Derby error policy\r
+ */\r
+ public void backupContainer(String backupContainerPath) throws StandardException;\r
+}\r