KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > sql > execute > UpdateStatisticsConstantAction


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.execute.UpdateStatisticsConstantAction
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.sql.execute;
23
24 import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
25 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
26 import org.apache.derby.iapi.sql.dictionary.StatisticsDescriptor;
27 import org.apache.derby.iapi.sql.Activation;
28 import org.apache.derby.iapi.error.StandardException;
29
30 import org.apache.derby.iapi.sql.execute.ExecIndexRow;
31 import org.apache.derby.iapi.store.access.TransactionController;
32 import org.apache.derby.iapi.types.DataValueDescriptor;
33 import org.apache.derby.iapi.store.access.GroupFetchScanController;
34 import org.apache.derby.iapi.store.access.ConglomerateController;
35 import org.apache.derby.catalog.UUID;
36 import org.apache.derby.catalog.types.StatisticsImpl;
37 import org.apache.derby.iapi.sql.depend.DependencyManager;
38 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
39
40 /**
41  * This class describes actions that are performed for an
42  * UPDATE STATISTICS Statement at execution time.
43  */

44
45 class UpdateStatisticsConstantAction extends DDLConstantAction
46 {
47     private UUID tableUUID;
48     private UUID[] objectUUID;
49     private String JavaDoc objectName;
50     private boolean forTable;
51     private long[] conglomerateNumber;
52     private ExecIndexRow[] indexRow;
53
54     /* RUNTIME state of the system is maintained in these objects.
55      * rowBufferOne simply reuses the index row prepared by
56      * makeConstantAction. rowBufferTwo is a clone (an extra copy) of
57      * objects. rowBufferCurrent just switches between rowBufferOne and
58      * rowBufferTwo.
59      */

60     private DataValueDescriptor[][] rowBufferArray;
61     private DataValueDescriptor[] rowBuffer;
62     private DataValueDescriptor[] lastUniqueKey;
63
64     private static final int GROUP_FETCH_SIZE = 16;
65
66     public UpdateStatisticsConstantAction() {};
67
68     public UpdateStatisticsConstantAction(boolean forTable,
69                                           String JavaDoc objectName,
70                                           UUID tableUUID,
71                                           UUID[] objectUUID,
72                                           long[] conglomerateNumber,
73                                           ExecIndexRow[] indexRow)
74     {
75         
76         this.forTable = forTable;
77         this.objectName = objectName;
78         this.tableUUID = tableUUID;
79         this.objectUUID = objectUUID;
80         this.conglomerateNumber = conglomerateNumber;
81         this.indexRow = indexRow;
82     }
83
84     public String JavaDoc toString()
85     {
86         return "UPDATE STATISTICS FOR " + (forTable ? "TABLE" : "INDEX") + " " +
87             objectName;
88             
89     }
90
91     public void executeConstantAction(Activation activation)
92         throws StandardException
93     
94     {
95         GroupFetchScanController gsc = null;
96         TransactionController tc = activation.getTransactionController();
97         LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
98         DataDictionary dd = lcc.getDataDictionary();
99         DependencyManager dm = dd.getDependencyManager();
100
101         
102         dd.startWriting(lcc);
103
104         TableDescriptor td = dd.getTableDescriptor(tableUUID);
105         dm.invalidateFor(td, DependencyManager.UPDATE_STATISTICS, lcc);
106
107         for (int indexNumber = 0; indexNumber < conglomerateNumber.length;
108              indexNumber++)
109         {
110             if (conglomerateNumber[indexNumber] == -1)
111                 continue;
112
113             int numCols = indexRow[indexNumber].nColumns() - 1;;
114             long[] cardinality = new long[numCols];
115             long numRows = 0;
116             initializeRowBuffers(indexRow[indexNumber]);
117
118             try
119             {
120                 /* Read uncommited, with record locking. Actually CS store may
121                    not hold record locks */

122                 gsc =
123                     tc.openGroupFetchScan(
124                         conglomerateNumber[indexNumber],
125                         false, // hold
126
0, // openMode: for read
127
TransactionController.MODE_RECORD, // locking
128
TransactionController.ISOLATION_READ_UNCOMMITTED, //isolation level
129
null, // scancolumnlist-- want everything.
130
null, // startkeyvalue-- start from the beginning.
131
0,
132                         null, // qualifiers, none!
133
null, // stopkeyvalue,
134
0);
135         
136                 boolean firstRow = true;
137                 int rowsFetched = 0;
138                 while ((rowsFetched = gsc.fetchNextGroup(rowBufferArray, null)) > 0)
139                 {
140                     for (int i = 0; i < rowsFetched; i++)
141                     {
142                         int whichPositionChanged = compareWithPrevKey(i, firstRow);
143                         firstRow = false;
144                         if (whichPositionChanged >= 0)
145                         {
146                             for (int j = whichPositionChanged; j < cardinality.length; j++)
147                                 cardinality[j]++;
148                         }
149                         numRows++;
150                     }
151
152                     DataValueDescriptor[] tmp;
153                     tmp = rowBufferArray[GROUP_FETCH_SIZE - 1];
154                     rowBufferArray[GROUP_FETCH_SIZE - 1] = lastUniqueKey;
155                     lastUniqueKey = tmp;
156                 } // while
157
} // try
158
finally
159             {
160                 if (gsc != null)
161                 {
162                     gsc.close();
163                     gsc = null;
164                 }
165             }
166
167             if (numRows == 0)
168             {
169                 /* if there is no data in the table: no need to write anything
170                  * to sys.systatstics.
171                  */

172                 break;
173             }
174
175             StatisticsDescriptor statDesc;
176         
177             dd.dropStatisticsDescriptors(tableUUID, objectUUID[indexNumber],
178                                          tc);
179
180             for (int i = 0; i < indexRow[indexNumber].nColumns() - 1; i++)
181             {
182                 statDesc = new StatisticsDescriptor(dd, dd.getUUIDFactory().createUUID(),
183                                                        objectUUID[indexNumber],
184                                                        tableUUID,
185                                                        "I",
186                                                        new StatisticsImpl(numRows,
187                                                                           cardinality[i]),
188                                                        i + 1);
189                 dd.addDescriptor(statDesc, null,
190                                  DataDictionary.SYSSTATISTICS_CATALOG_NUM,
191                                  true, tc);
192             } // for each leading column (c1) (c1,c2)....
193

194         } // for each index.
195
}
196
197
198     private void initializeRowBuffers(ExecIndexRow ir)
199     {
200
201         rowBufferArray = new DataValueDescriptor[GROUP_FETCH_SIZE][];
202         lastUniqueKey = ir.getRowArrayClone();
203         rowBufferArray[0] = ir.getRowArray(); // 1 gets old objects.
204
}
205
206     private int compareWithPrevKey(int index, boolean firstRow)
207         throws StandardException
208     {
209         if (firstRow)
210             return 0;
211
212         DataValueDescriptor[] prev = (index == 0) ? lastUniqueKey : rowBufferArray[index - 1];
213         DataValueDescriptor[] curr = rowBufferArray[index];
214         // no point trying to do rowlocation; hence - 1
215
for (int i = 0; i < (prev.length - 1); i++)
216         {
217             DataValueDescriptor dvd = (DataValueDescriptor)prev[i];
218
219             if (dvd.isNull())
220                 return i; // nulls are counted as unique values.
221

222             if (prev[i].compare(curr[i]) != 0)
223             {
224                 return i;
225             }
226         }
227
228         return -1;
229     }
230
231     
232
233 }
234
Popular Tags