--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.impl.store.access.btree.index.B2IFactory\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.access.btree.index;\r
+\r
+import java.util.Properties;\r
+\r
+import org.apache.derby.iapi.reference.SQLState;\r
+\r
+import org.apache.derby.iapi.services.monitor.ModuleControl;\r
+import org.apache.derby.iapi.services.monitor.Monitor;\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import org.apache.derby.catalog.UUID;\r
+import org.apache.derby.iapi.services.uuid.UUIDFactory;\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.store.access.conglomerate.Conglomerate;\r
+import org.apache.derby.iapi.store.access.conglomerate.ConglomerateFactory;\r
+import org.apache.derby.iapi.store.access.conglomerate.TransactionManager;\r
+import org.apache.derby.iapi.store.access.ColumnOrdering;\r
+\r
+import org.apache.derby.iapi.store.raw.ContainerKey;\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.RawStoreFactory;\r
+\r
+import org.apache.derby.iapi.types.DataValueDescriptor;\r
+\r
+import org.apache.derby.impl.store.access.btree.BTree;\r
+import org.apache.derby.impl.store.access.btree.ControlRow;\r
+\r
+/**\r
+\r
+ The "B2I" (acronym for b-tree secondary index) factory manages b-tree\r
+ conglomerates implemented on the raw store which are used as secondary\r
+ indexes.\r
+ <p>\r
+ Most of this code is generic to all conglomerates. This class might be\r
+ more easily maintained as an abstract class in Raw/Conglomerate/Generic.\r
+ The concrete ConglomerateFactories would simply have to supply the \r
+ IMPLEMENTATIONID, FORMATUUIDSTRING, and implement createConglomerate\r
+ and defaultProperties. Conglomerates which support more than one format\r
+ would have to override supportsFormat, and conglomerates which support\r
+ more than one implementation would have to override supportsImplementation.\r
+\r
+**/\r
+\r
+public class B2IFactory implements ConglomerateFactory, ModuleControl\r
+{\r
+\r
+ private static final String IMPLEMENTATIONID = "BTREE";\r
+ private static final String FORMATUUIDSTRING = "C6CEEEF0-DAD3-11d0-BB01-0060973F0942";\r
+ private UUID formatUUID;\r
+\r
+\r
+ /*\r
+ ** Methods of MethodFactory (via ConglomerateFactory)\r
+ */\r
+\r
+ /**\r
+ Return the default properties for this kind of conglomerate.\r
+ @see org.apache.derby.iapi.store.access.conglomerate.MethodFactory#defaultProperties\r
+ **/\r
+ public Properties defaultProperties()\r
+ {\r
+ // XXX (nat) Need to return the default b-tree secondary index properties.\r
+ return new Properties();\r
+ }\r
+\r
+ /**\r
+ Return whether this access method implements the implementation\r
+ type given in the argument string.\r
+ The btree only has one implementation type, "BTREE".\r
+\r
+ @see org.apache.derby.iapi.store.access.conglomerate.MethodFactory#supportsImplementation\r
+ **/\r
+ public boolean supportsImplementation(String implementationId)\r
+ {\r
+ return implementationId.equals(IMPLEMENTATIONID);\r
+ }\r
+\r
+ /**\r
+ Return the primary implementation type for this access method.\r
+ The btree only has one implementation type, "BTREE".\r
+\r
+ @see org.apache.derby.iapi.store.access.conglomerate.MethodFactory#primaryImplementationType\r
+ **/\r
+ public String primaryImplementationType()\r
+ {\r
+ return IMPLEMENTATIONID;\r
+ }\r
+\r
+ /**\r
+ Return whether this access method supports the format supplied in\r
+ the argument.\r
+ The btree currently only supports one format.\r
+\r
+ @see org.apache.derby.iapi.store.access.conglomerate.MethodFactory#supportsFormat\r
+ **/\r
+ public boolean supportsFormat(UUID formatid)\r
+ {\r
+ return formatid.equals(formatUUID);\r
+ }\r
+\r
+ /**\r
+ Return the primary format that this access method supports.\r
+ The btree currently only supports one format.\r
+\r
+ @see org.apache.derby.iapi.store.access.conglomerate.MethodFactory#primaryFormat\r
+ **/\r
+ public UUID primaryFormat()\r
+ {\r
+ return formatUUID;\r
+ }\r
+\r
+ /*\r
+ ** Methods of ConglomerateFactory\r
+ */\r
+\r
+ /**\r
+ * Return the conglomerate factory id.\r
+ * <p>\r
+ * Return a number in the range of 0-15 which identifies this factory.\r
+ * Code which names conglomerates depends on this range currently, but\r
+ * could be easily changed to handle larger ranges. One hex digit seemed\r
+ * reasonable for the number of conglomerate types being currently \r
+ * considered (heap, btree, gist, gist btree, gist rtree, hash, others? ).\r
+ * <p>\r
+ * @see ConglomerateFactory#getConglomerateFactoryId\r
+ *\r
+ * @return an unique identifier used to the factory into the conglomid.\r
+ **/\r
+ public int getConglomerateFactoryId()\r
+ {\r
+ return(ConglomerateFactory.BTREE_FACTORY_ID);\r
+ }\r
+\r
+ /**\r
+ Create the conglomerate and return a conglomerate object for it.\r
+\r
+ @see ConglomerateFactory#createConglomerate\r
+\r
+ @exception StandardException Standard exception policy.\r
+ **/\r
+ public Conglomerate createConglomerate( \r
+ TransactionManager xact_mgr,\r
+ int segment,\r
+ long input_containerid,\r
+ DataValueDescriptor[] template,\r
+ ColumnOrdering[] columnOrder,\r
+ int[] collationIds,\r
+ Properties properties,\r
+ int temporaryFlag)\r
+ throws StandardException\r
+ {\r
+ B2I btree = null;\r
+\r
+ if (xact_mgr.checkVersion(\r
+ RawStoreFactory.DERBY_STORE_MAJOR_VERSION_10,\r
+ RawStoreFactory.DERBY_STORE_MINOR_VERSION_3,\r
+ null))\r
+ {\r
+ // on disk databases with version higher than 10.2 should use\r
+ // current disk format B2I. This includes new databases or\r
+ // hard upgraded databases.\r
+ btree = new B2I();\r
+ }\r
+ else\r
+ {\r
+ // Old databases that are running in new versions of the software,\r
+ // but are running in soft upgrade mode at release level 10.2\r
+ // and before should use the old B2I version. This version will\r
+ // continue to write metadata that can be read by 10.2 and previous\r
+ // versions.\r
+ btree = new B2I_v10_2();\r
+ }\r
+\r
+ btree.create(\r
+ xact_mgr, segment, input_containerid, template, columnOrder, \r
+ collationIds, properties, temporaryFlag);\r
+\r
+ return(btree);\r
+ }\r
+\r
+ /**\r
+ * Return Conglomerate object for conglomerate with conglomid.\r
+ * <p>\r
+ * Return the Conglomerate Object. This is implementation specific.\r
+ * Examples of what will be done is using the id to find the file where\r
+ * the conglomerate is located, and then executing implementation specific\r
+ * code to instantiate an object from reading a "special" row from a\r
+ * known location in the file. In the btree case the btree conglomerate\r
+ * is stored as a column in the control row on the root page.\r
+ * <p>\r
+ * This operation is costly so it is likely an implementation using this\r
+ * will cache the conglomerate row in memory so that subsequent accesses\r
+ * need not perform this operation.\r
+ * <p>\r
+ * The btree object returned by this routine may be installed in a cache\r
+ * so the object must not change.\r
+ *\r
+ * @return An instance of the conglomerate.\r
+ *\r
+ * @exception StandardException Standard exception policy.\r
+ **/\r
+ public Conglomerate readConglomerate(\r
+ TransactionManager xact_manager,\r
+ ContainerKey container_key)\r
+ throws StandardException\r
+ {\r
+ Conglomerate btree = null;\r
+ ContainerHandle container = null;\r
+ ControlRow root = null;\r
+\r
+ try\r
+ {\r
+ // open readonly, with no locks. Dirty read is ok as it is the\r
+ // responsibility of client code to make sure this data is not\r
+ // changing while being read. The only changes that currently\r
+ // happen to this data is creation and deletion - no updates\r
+ // ever happen to btree conglomerates.\r
+ container = \r
+ (xact_manager.getRawStoreXact()).openContainer(\r
+ container_key,\r
+ (LockingPolicy) null,\r
+ ContainerHandle.MODE_READONLY);\r
+\r
+ if (container == null)\r
+ {\r
+ // thrown a "known" error if the conglomerate does not exist \r
+ // which is checked for explicitly by callers of the store \r
+ // interface.\r
+\r
+ throw StandardException.newException(\r
+ SQLState.STORE_CONGLOMERATE_DOES_NOT_EXIST, \r
+ new Long(container_key.getContainerId()));\r
+ }\r
+\r
+ // The conglomerate is located in the control row on the root page.\r
+ root = ControlRow.get(container, BTree.ROOTPAGEID);\r
+\r
+ if (SanityManager.DEBUG)\r
+ SanityManager.ASSERT(root.getPage().isLatched());\r
+\r
+ // read the Conglomerate from it's entry in the control row.\r
+ btree = (B2I) root.getConglom(B2I.FORMAT_NUMBER);\r
+\r
+ if (SanityManager.DEBUG)\r
+ SanityManager.ASSERT(btree instanceof B2I);\r
+ }\r
+ finally\r
+ {\r
+\r
+ if (root != null)\r
+ root.release();\r
+\r
+ if (container != null)\r
+ container.close();\r
+ }\r
+\r
+ // if any error, just return null - meaning can't access the container.\r
+\r
+ return(btree);\r
+ }\r
+\r
+ /*\r
+ ** Methods of ModuleControl.\r
+ */\r
+\r
+ public boolean canSupport(Properties startParams) {\r
+\r
+ String impl = startParams.getProperty("derby.access.Conglomerate.type");\r
+ if (impl == null)\r
+ return false;\r
+\r
+ return supportsImplementation(impl);\r
+ }\r
+\r
+ public void boot(boolean create, Properties startParams)\r
+ throws StandardException\r
+ {\r
+ // Find the UUID factory.\r
+ UUIDFactory uuidFactory = \r
+ Monitor.getMonitor().getUUIDFactory();\r
+\r
+ // Make a UUID that identifies this conglomerate's format.\r
+ formatUUID = uuidFactory.recreateUUID(FORMATUUIDSTRING);\r
+ }\r
+\r
+ public void stop()\r
+ {\r
+ }\r
+}\r