1 | /* |
2 | |
3 | Derby - Class org.apache.derby.iapi.sql.dictionary.IndexLister |
4 | |
5 | Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable. |
6 | |
7 | Licensed under the Apache License, Version 2.0 (the "License"); |
8 | you may not use this file except in compliance with the License. |
9 | You may obtain a copy of the License at |
10 | |
11 | http://www.apache.org/licenses/LICENSE-2.0 |
12 | |
13 | Unless required by applicable law or agreed to in writing, software |
14 | distributed under the License is distributed on an "AS IS" BASIS, |
15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
16 | See the License for the specific language governing permissions and |
17 | limitations under the License. |
18 | |
19 | */ |
20 | |
21 | package org.apache.derby.iapi.sql.dictionary; |
22 | |
23 | import org.apache.derby.iapi.services.context.ContextManager; |
24 | |
25 | import org.apache.derby.iapi.error.StandardException; |
26 | |
27 | import org.apache.derby.iapi.sql.depend.Dependent; |
28 | |
29 | import org.apache.derby.iapi.services.context.ContextManager; |
30 | |
31 | import org.apache.derby.iapi.sql.dictionary.DataDictionary; |
32 | import org.apache.derby.iapi.sql.dictionary.TableDescriptor; |
33 | import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor; |
34 | import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator; |
35 | |
36 | import org.apache.derby.iapi.sql.depend.Dependent; |
37 | import org.apache.derby.iapi.sql.depend.DependencyManager; |
38 | import org.apache.derby.iapi.sql.dictionary.DataDictionaryContext; |
39 | import org.apache.derby.iapi.services.sanity.SanityManager; |
40 | |
41 | import org.apache.derby.iapi.error.StandardException; |
42 | |
43 | import java.util.Enumeration; |
44 | import java.util.Vector; |
45 | |
46 | /** |
47 | * This interface gathers up some tasty information about the indices on a |
48 | * table from the DataDictionary. |
49 | * |
50 | */ |
51 | public class IndexLister |
52 | { |
53 | //////////////////////////////////////////////////////////////////////// |
54 | // |
55 | // STATE |
56 | // |
57 | //////////////////////////////////////////////////////////////////////// |
58 | |
59 | private TableDescriptor tableDescriptor; |
60 | private IndexRowGenerator[] indexRowGenerators; |
61 | private long[] indexConglomerateNumbers; |
62 | private String[] indexNames; |
63 | // the following 3 are the compact arrays, without duplicate indexes |
64 | private IndexRowGenerator[] distinctIndexRowGenerators; |
65 | private long[] distinctIndexConglomerateNumbers; |
66 | private String[] distinctIndexNames; |
67 | |
68 | //////////////////////////////////////////////////////////////////////// |
69 | // |
70 | // CONSTRUCTORS |
71 | // |
72 | //////////////////////////////////////////////////////////////////////// |
73 | |
74 | /** |
75 | * Make an IndexLister |
76 | * |
77 | * @param tableDescriptor Describes the table in question. |
78 | * |
79 | */ |
80 | public IndexLister( TableDescriptor tableDescriptor ) |
81 | { |
82 | this.tableDescriptor = tableDescriptor; |
83 | } |
84 | |
85 | |
86 | //////////////////////////////////////////////////////////////////////// |
87 | // |
88 | // INDEXLISTER METHODS |
89 | // |
90 | //////////////////////////////////////////////////////////////////////// |
91 | |
92 | /** |
93 | * Returns an array of all the index row generators on a table. |
94 | * |
95 | * @return an array of index row generators |
96 | * |
97 | * @exception StandardException Thrown on error |
98 | */ |
99 | public IndexRowGenerator[] getIndexRowGenerators() |
100 | throws StandardException |
101 | { |
102 | if ( indexRowGenerators == null ) { getAllIndexes(); } |
103 | return indexRowGenerators; |
104 | } |
105 | |
106 | /** |
107 | * Returns an array of all the index conglomerate ids on a table. |
108 | * |
109 | * @return an array of index conglomerate ids |
110 | * |
111 | * @exception StandardException Thrown on error |
112 | */ |
113 | public long[] getIndexConglomerateNumbers() |
114 | throws StandardException |
115 | { |
116 | if ( indexConglomerateNumbers == null ) { getAllIndexes(); } |
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 | { |
129 | if ( indexNames == null ) { getAllIndexes(); } |
130 | return indexNames; |
131 | } |
132 | |
133 | /** |
134 | * Returns an array of distinct index row generators on a table, |
135 | * erasing entries for duplicate indexes (which share same conglomerate). |
136 | * |
137 | * @return an array of index row generators |
138 | * |
139 | * @exception StandardException Thrown on error |
140 | */ |
141 | public IndexRowGenerator[] getDistinctIndexRowGenerators() |
142 | throws StandardException |
143 | { |
144 | if ( distinctIndexRowGenerators == null ) { getAllIndexes(); } |
145 | return distinctIndexRowGenerators; |
146 | } |
147 | |
148 | /** |
149 | * Returns an array of distinct index conglomerate ids on a table. |
150 | * erasing entries for duplicate indexes (which share same conglomerate). |
151 | * |
152 | * @return an array of index conglomerate ids |
153 | * |
154 | * @exception StandardException Thrown on error |
155 | */ |
156 | public long[] getDistinctIndexConglomerateNumbers() |
157 | throws StandardException |
158 | { |
159 | if ( distinctIndexConglomerateNumbers == null ) { getAllIndexes(); } |
160 | return distinctIndexConglomerateNumbers; |
161 | } |
162 | |
163 | /** |
164 | * Returns an array of index names for all distinct indexes on a table. |
165 | * erasing entries for duplicate indexes (which share same conglomerate). |
166 | * |
167 | * @return an array of index names |
168 | * |
169 | * @exception StandardException Thrown on error |
170 | */ |
171 | public String[] getDistinctIndexNames() throws StandardException |
172 | { |
173 | if ( indexNames == null ) { getAllIndexes(); } |
174 | return indexNames; |
175 | } |
176 | |
177 | //////////////////////////////////////////////////////////////////////// |
178 | // |
179 | // MINIONS |
180 | // |
181 | //////////////////////////////////////////////////////////////////////// |
182 | |
183 | /** |
184 | * Reads all the indices on the table and populates arrays with the |
185 | * corresponding index row generators and index conglomerate ids. |
186 | * |
187 | * |
188 | * @exception StandardException Thrown on error |
189 | */ |
190 | private void getAllIndexes() |
191 | throws StandardException |
192 | { |
193 | int indexCount = 0; |
194 | |
195 | ConglomerateDescriptor[] cds = |
196 | tableDescriptor.getConglomerateDescriptors(); |
197 | |
198 | /* from one end of work space, we record distinct conglomerate |
199 | * numbers for comparison while we iterate; from the other end of |
200 | * work space, we record duplicate indexes' indexes in "cds" array, |
201 | * so that we can skip them in later round. |
202 | */ |
203 | long[] workSpace = new long[cds.length - 1]; // 1 heap |
204 | int distinctIndexCount = 0, duplicateIndex = workSpace.length - 1; |
205 | |
206 | for (int i = 0; i < cds.length; i++) |
207 | { |
208 | // first count the number of indices. |
209 | ConglomerateDescriptor cd = cds[i]; |
210 | |
211 | if ( ! cd.isIndex()) |
212 | continue; |
213 | |
214 | int k; |
215 | long thisCongNum = cd.getConglomerateNumber(); |
216 | |
217 | for (k = 0; k < distinctIndexCount; k++) |
218 | { |
219 | if (workSpace[k] == thisCongNum) |
220 | { |
221 | workSpace[duplicateIndex--] = i; |
222 | break; |
223 | } |
224 | } |
225 | if (k == distinctIndexCount) // first appearence |
226 | workSpace[distinctIndexCount++] = thisCongNum; |
227 | |
228 | indexCount++; |
229 | } |
230 | |
231 | indexRowGenerators = new IndexRowGenerator[ indexCount ]; |
232 | indexConglomerateNumbers = new long[ indexCount ]; |
233 | indexNames = new String[ indexCount ]; |
234 | distinctIndexRowGenerators = new IndexRowGenerator[ distinctIndexCount ]; |
235 | distinctIndexConglomerateNumbers = new long[ distinctIndexCount ]; |
236 | distinctIndexNames = new String[ distinctIndexCount ]; |
237 | |
238 | int duplicatePtr = workSpace.length - 1; |
239 | for ( int i = 0, j = -1, k = -1; i < cds.length; i++ ) |
240 | { |
241 | ConglomerateDescriptor cd = cds[i]; |
242 | |
243 | if ( ! cd.isIndex()) |
244 | continue; |
245 | |
246 | indexRowGenerators[++j] = |
247 | (IndexRowGenerator)cd.getIndexDescriptor(); |
248 | indexConglomerateNumbers[j] = cd.getConglomerateNumber(); |
249 | if (!(cd.isConstraint())) |
250 | { |
251 | // only fill index name if it is not a constraint. |
252 | indexNames[j] = cd.getConglomerateName(); |
253 | } |
254 | |
255 | if (duplicatePtr > duplicateIndex && i == (int) workSpace[duplicatePtr]) |
256 | duplicatePtr--; |
257 | else |
258 | { |
259 | distinctIndexRowGenerators[++k] = indexRowGenerators[j]; |
260 | distinctIndexConglomerateNumbers[k] = indexConglomerateNumbers[j]; |
261 | distinctIndexNames[k] = indexNames[j]; |
262 | } |
263 | } |
264 | } |
265 | } |