--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.iapi.sql.dictionary.IndexLister\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.sql.dictionary;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator;\r
+\r
+\r
+/**\r
+ * This interface gathers up some tasty information about the indices on a\r
+ * table from the DataDictionary.\r
+ *\r
+ */\r
+public class IndexLister\r
+{\r
+ ////////////////////////////////////////////////////////////////////////\r
+ //\r
+ // STATE\r
+ //\r
+ ////////////////////////////////////////////////////////////////////////\r
+\r
+ private TableDescriptor tableDescriptor;\r
+ private IndexRowGenerator[] indexRowGenerators;\r
+ private long[] indexConglomerateNumbers;\r
+ private String[] indexNames;\r
+ // the following 3 are the compact arrays, without duplicate indexes\r
+ private IndexRowGenerator[] distinctIndexRowGenerators;\r
+ private long[] distinctIndexConglomerateNumbers;\r
+ private String[] distinctIndexNames;\r
+\r
+ ////////////////////////////////////////////////////////////////////////\r
+ //\r
+ // CONSTRUCTORS\r
+ //\r
+ ////////////////////////////////////////////////////////////////////////\r
+\r
+ /**\r
+ * Make an IndexLister\r
+ *\r
+ * @param tableDescriptor Describes the table in question.\r
+ *\r
+ */\r
+ public IndexLister( TableDescriptor tableDescriptor )\r
+ {\r
+ this.tableDescriptor = tableDescriptor;\r
+ }\r
+\r
+\r
+ ////////////////////////////////////////////////////////////////////////\r
+ //\r
+ // INDEXLISTER METHODS\r
+ //\r
+ ////////////////////////////////////////////////////////////////////////\r
+\r
+ /**\r
+ * Returns an array of all the index row generators on a table.\r
+ *\r
+ * @return an array of index row generators\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+ public IndexRowGenerator[] getIndexRowGenerators()\r
+ throws StandardException\r
+ {\r
+ if ( indexRowGenerators == null ) { getAllIndexes(); }\r
+ return indexRowGenerators;\r
+ }\r
+\r
+ /**\r
+ * Returns an array of all the index conglomerate ids on a table.\r
+ *\r
+ * @return an array of index conglomerate ids\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+ public long[] getIndexConglomerateNumbers()\r
+ throws StandardException\r
+ {\r
+ if ( indexConglomerateNumbers == null ) { getAllIndexes(); }\r
+ return indexConglomerateNumbers;\r
+ }\r
+\r
+ /**\r
+ * Returns an array of all the index names on a table.\r
+ *\r
+ * @return an array of index names\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+ public String[] getIndexNames() throws StandardException\r
+ {\r
+ if ( indexNames == null ) { getAllIndexes(); }\r
+ return indexNames;\r
+ }\r
+\r
+ /**\r
+ * Returns an array of distinct index row generators on a table,\r
+ * erasing entries for duplicate indexes (which share same conglomerate).\r
+ *\r
+ * @return an array of index row generators\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+ public IndexRowGenerator[] getDistinctIndexRowGenerators()\r
+ throws StandardException\r
+ {\r
+ if ( distinctIndexRowGenerators == null ) { getAllIndexes(); }\r
+ return distinctIndexRowGenerators;\r
+ }\r
+\r
+ /**\r
+ * Returns an array of distinct index conglomerate ids on a table.\r
+ * erasing entries for duplicate indexes (which share same conglomerate).\r
+ *\r
+ * @return an array of index conglomerate ids\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+ public long[] getDistinctIndexConglomerateNumbers()\r
+ throws StandardException\r
+ {\r
+ if ( distinctIndexConglomerateNumbers == null ) { getAllIndexes(); }\r
+ return distinctIndexConglomerateNumbers;\r
+ }\r
+\r
+ /**\r
+ * Returns an array of index names for all distinct indexes on a table.\r
+ * erasing entries for duplicate indexes (which share same conglomerate).\r
+ *\r
+ * @return an array of index names\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+ public String[] getDistinctIndexNames() throws StandardException\r
+ {\r
+ if ( indexNames == null ) { getAllIndexes(); }\r
+ return indexNames;\r
+ }\r
+\r
+ ////////////////////////////////////////////////////////////////////////\r
+ //\r
+ // MINIONS\r
+ //\r
+ ////////////////////////////////////////////////////////////////////////\r
+\r
+ /**\r
+ * Reads all the indices on the table and populates arrays with the\r
+ * corresponding index row generators and index conglomerate ids.\r
+ *\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+ private void getAllIndexes()\r
+ throws StandardException\r
+ {\r
+ int indexCount = 0;\r
+\r
+ ConglomerateDescriptor[] cds = \r
+ tableDescriptor.getConglomerateDescriptors();\r
+\r
+ /* from one end of work space, we record distinct conglomerate\r
+ * numbers for comparison while we iterate; from the other end of\r
+ * work space, we record duplicate indexes' indexes in "cds" array,\r
+ * so that we can skip them in later round.\r
+ */\r
+ long[] workSpace = new long[cds.length - 1]; // 1 heap\r
+ int distinctIndexCount = 0, duplicateIndex = workSpace.length - 1;\r
+\r
+ for (int i = 0; i < cds.length; i++)\r
+ {\r
+ // first count the number of indices.\r
+ ConglomerateDescriptor cd = cds[i];\r
+\r
+ if ( ! cd.isIndex())\r
+ continue;\r
+\r
+ int k;\r
+ long thisCongNum = cd.getConglomerateNumber();\r
+\r
+ for (k = 0; k < distinctIndexCount; k++)\r
+ {\r
+ if (workSpace[k] == thisCongNum)\r
+ {\r
+ workSpace[duplicateIndex--] = i;\r
+ break;\r
+ }\r
+ }\r
+ if (k == distinctIndexCount) // first appearence\r
+ workSpace[distinctIndexCount++] = thisCongNum;\r
+\r
+ indexCount++;\r
+ }\r
+\r
+ indexRowGenerators = new IndexRowGenerator[ indexCount ];\r
+ indexConglomerateNumbers = new long[ indexCount ];\r
+ indexNames = new String[ indexCount ];\r
+ distinctIndexRowGenerators = new IndexRowGenerator[ distinctIndexCount ];\r
+ distinctIndexConglomerateNumbers = new long[ distinctIndexCount ];\r
+ distinctIndexNames = new String[ distinctIndexCount ];\r
+\r
+ int duplicatePtr = workSpace.length - 1;\r
+ for ( int i = 0, j = -1, k = -1; i < cds.length; i++ )\r
+ {\r
+ ConglomerateDescriptor cd = cds[i];\r
+\r
+ if ( ! cd.isIndex())\r
+ continue;\r
+\r
+ indexRowGenerators[++j] = \r
+ (IndexRowGenerator)cd.getIndexDescriptor();\r
+ indexConglomerateNumbers[j] = cd.getConglomerateNumber();\r
+ if (!(cd.isConstraint()))\r
+ {\r
+ // only fill index name if it is not a constraint.\r
+ indexNames[j] = cd.getConglomerateName();\r
+ }\r
+\r
+ if (duplicatePtr > duplicateIndex && i == (int) workSpace[duplicatePtr])\r
+ duplicatePtr--;\r
+ else\r
+ {\r
+ distinctIndexRowGenerators[++k] = indexRowGenerators[j];\r
+ distinctIndexConglomerateNumbers[k] = indexConglomerateNumbers[j];\r
+ distinctIndexNames[k] = indexNames[j];\r
+ }\r
+ }\r
+ }\r
+}\r