001: /*
002:
003: Derby - Class org.apache.derby.iapi.sql.dictionary.IndexLister
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.iapi.sql.dictionary;
023:
024: import org.apache.derby.iapi.services.context.ContextManager;
025:
026: import org.apache.derby.iapi.error.StandardException;
027:
028: import org.apache.derby.iapi.sql.depend.Dependent;
029:
030: import org.apache.derby.iapi.services.context.ContextManager;
031:
032: import org.apache.derby.iapi.sql.dictionary.DataDictionary;
033: import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
034: import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;
035: import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator;
036:
037: import org.apache.derby.iapi.sql.depend.Dependent;
038: import org.apache.derby.iapi.sql.depend.DependencyManager;
039: import org.apache.derby.iapi.sql.dictionary.DataDictionaryContext;
040: import org.apache.derby.iapi.services.sanity.SanityManager;
041:
042: import org.apache.derby.iapi.error.StandardException;
043:
044: import java.util.Enumeration;
045: import java.util.Vector;
046:
047: /**
048: * This interface gathers up some tasty information about the indices on a
049: * table from the DataDictionary.
050: *
051: */
052: public class IndexLister {
053: ////////////////////////////////////////////////////////////////////////
054: //
055: // STATE
056: //
057: ////////////////////////////////////////////////////////////////////////
058:
059: private TableDescriptor tableDescriptor;
060: private IndexRowGenerator[] indexRowGenerators;
061: private long[] indexConglomerateNumbers;
062: private String[] indexNames;
063: // the following 3 are the compact arrays, without duplicate indexes
064: private IndexRowGenerator[] distinctIndexRowGenerators;
065: private long[] distinctIndexConglomerateNumbers;
066: private String[] distinctIndexNames;
067:
068: ////////////////////////////////////////////////////////////////////////
069: //
070: // CONSTRUCTORS
071: //
072: ////////////////////////////////////////////////////////////////////////
073:
074: /**
075: * Make an IndexLister
076: *
077: * @param tableDescriptor Describes the table in question.
078: *
079: */
080: public IndexLister(TableDescriptor tableDescriptor) {
081: this .tableDescriptor = tableDescriptor;
082: }
083:
084: ////////////////////////////////////////////////////////////////////////
085: //
086: // INDEXLISTER METHODS
087: //
088: ////////////////////////////////////////////////////////////////////////
089:
090: /**
091: * Returns an array of all the index row generators on a table.
092: *
093: * @return an array of index row generators
094: *
095: * @exception StandardException Thrown on error
096: */
097: public IndexRowGenerator[] getIndexRowGenerators()
098: throws StandardException {
099: if (indexRowGenerators == null) {
100: getAllIndexes();
101: }
102: return indexRowGenerators;
103: }
104:
105: /**
106: * Returns an array of all the index conglomerate ids on a table.
107: *
108: * @return an array of index conglomerate ids
109: *
110: * @exception StandardException Thrown on error
111: */
112: public long[] getIndexConglomerateNumbers()
113: throws StandardException {
114: if (indexConglomerateNumbers == null) {
115: getAllIndexes();
116: }
117: return indexConglomerateNumbers;
118: }
119:
120: /**
121: * Returns an array of all the index names on a table.
122: *
123: * @return an array of index names
124: *
125: * @exception StandardException Thrown on error
126: */
127: public String[] getIndexNames() throws StandardException {
128: if (indexNames == null) {
129: getAllIndexes();
130: }
131: return indexNames;
132: }
133:
134: /**
135: * Returns an array of distinct index row generators on a table,
136: * erasing entries for duplicate indexes (which share same conglomerate).
137: *
138: * @return an array of index row generators
139: *
140: * @exception StandardException Thrown on error
141: */
142: public IndexRowGenerator[] getDistinctIndexRowGenerators()
143: throws StandardException {
144: if (distinctIndexRowGenerators == null) {
145: getAllIndexes();
146: }
147: return distinctIndexRowGenerators;
148: }
149:
150: /**
151: * Returns an array of distinct index conglomerate ids on a table.
152: * erasing entries for duplicate indexes (which share same conglomerate).
153: *
154: * @return an array of index conglomerate ids
155: *
156: * @exception StandardException Thrown on error
157: */
158: public long[] getDistinctIndexConglomerateNumbers()
159: throws StandardException {
160: if (distinctIndexConglomerateNumbers == null) {
161: getAllIndexes();
162: }
163: return distinctIndexConglomerateNumbers;
164: }
165:
166: /**
167: * Returns an array of index names for all distinct indexes on a table.
168: * erasing entries for duplicate indexes (which share same conglomerate).
169: *
170: * @return an array of index names
171: *
172: * @exception StandardException Thrown on error
173: */
174: public String[] getDistinctIndexNames() throws StandardException {
175: if (indexNames == null) {
176: getAllIndexes();
177: }
178: return indexNames;
179: }
180:
181: ////////////////////////////////////////////////////////////////////////
182: //
183: // MINIONS
184: //
185: ////////////////////////////////////////////////////////////////////////
186:
187: /**
188: * Reads all the indices on the table and populates arrays with the
189: * corresponding index row generators and index conglomerate ids.
190: *
191: *
192: * @exception StandardException Thrown on error
193: */
194: private void getAllIndexes() throws StandardException {
195: int indexCount = 0;
196:
197: ConglomerateDescriptor[] cds = tableDescriptor
198: .getConglomerateDescriptors();
199:
200: /* from one end of work space, we record distinct conglomerate
201: * numbers for comparison while we iterate; from the other end of
202: * work space, we record duplicate indexes' indexes in "cds" array,
203: * so that we can skip them in later round.
204: */
205: long[] workSpace = new long[cds.length - 1]; // 1 heap
206: int distinctIndexCount = 0, duplicateIndex = workSpace.length - 1;
207:
208: for (int i = 0; i < cds.length; i++) {
209: // first count the number of indices.
210: ConglomerateDescriptor cd = cds[i];
211:
212: if (!cd.isIndex())
213: continue;
214:
215: int k;
216: long this CongNum = cd.getConglomerateNumber();
217:
218: for (k = 0; k < distinctIndexCount; k++) {
219: if (workSpace[k] == this CongNum) {
220: workSpace[duplicateIndex--] = i;
221: break;
222: }
223: }
224: if (k == distinctIndexCount) // first appearence
225: workSpace[distinctIndexCount++] = this CongNum;
226:
227: indexCount++;
228: }
229:
230: indexRowGenerators = new IndexRowGenerator[indexCount];
231: indexConglomerateNumbers = new long[indexCount];
232: indexNames = new String[indexCount];
233: distinctIndexRowGenerators = new IndexRowGenerator[distinctIndexCount];
234: distinctIndexConglomerateNumbers = new long[distinctIndexCount];
235: distinctIndexNames = new String[distinctIndexCount];
236:
237: int duplicatePtr = workSpace.length - 1;
238: for (int i = 0, j = -1, k = -1; i < cds.length; i++) {
239: ConglomerateDescriptor cd = cds[i];
240:
241: if (!cd.isIndex())
242: continue;
243:
244: indexRowGenerators[++j] = (IndexRowGenerator) cd
245: .getIndexDescriptor();
246: indexConglomerateNumbers[j] = cd.getConglomerateNumber();
247: if (!(cd.isConstraint())) {
248: // only fill index name if it is not a constraint.
249: indexNames[j] = cd.getConglomerateName();
250: }
251:
252: if (duplicatePtr > duplicateIndex
253: && i == (int) workSpace[duplicatePtr])
254: duplicatePtr--;
255: else {
256: distinctIndexRowGenerators[++k] = indexRowGenerators[j];
257: distinctIndexConglomerateNumbers[k] = indexConglomerateNumbers[j];
258: distinctIndexNames[k] = indexNames[j];
259: }
260: }
261: }
262: }
|