KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.execute.CardinalityCounter
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.services.io.FormatableBitSet;
25
26 import org.apache.derby.iapi.services.io.Storable;
27
28 import org.apache.derby.iapi.error.StandardException;
29
30 import org.apache.derby.iapi.store.access.RowLocationRetRowSource;
31
32 import org.apache.derby.iapi.types.DataValueDescriptor;
33
34 import org.apache.derby.iapi.types.RowLocation;
35
36 /**
37  * This is a decorator (in Design Patterns Terminology)
38  * class to enhance the functionality
39  * of a RowLocationRetRowSource. It assumes that the rows are coming
40  * in sorted order from the row source and it simply keeps track of
41  * the cardinality of all the leading columns.
42  */

43
44 public class CardinalityCounter implements RowLocationRetRowSource
45 {
46     private RowLocationRetRowSource rowSource;
47     private DataValueDescriptor[] prevKey;
48     private long[] cardinality;
49     private long numRows;
50
51     public CardinalityCounter(RowLocationRetRowSource rowSource)
52     {
53         this.rowSource = rowSource;
54     }
55
56     /** @see RowLocationRetRowSource#needsRowLocation */
57     public boolean needsRowLocation()
58     {
59         return rowSource.needsRowLocation();
60     }
61
62     /** @see RowLocationRetRowSource#rowLocation */
63     public void rowLocation(RowLocation rl) throws StandardException
64     {
65         rowSource.rowLocation(rl);
66     }
67
68     /**
69      * Gets next row from the row source and update the count of unique values
70      * that are returned.
71      * @see RowLocationRetRowSource#getNextRowFromRowSource
72      */

73     public DataValueDescriptor[] getNextRowFromRowSource() throws StandardException
74     {
75         DataValueDescriptor[] nextRow;
76         nextRow = rowSource.getNextRowFromRowSource();
77         if (nextRow != null)
78             keepCount(nextRow);
79         return nextRow;
80     }
81
82
83     /** @see RowLocationRetRowSource#needsToClone */
84     public boolean needsToClone()
85     {
86         return rowSource.needsToClone();
87     }
88
89     /** @see RowLocationRetRowSource#getValidColumns */
90     public FormatableBitSet getValidColumns()
91     {
92         return rowSource.getValidColumns();
93     }
94
95     /** @see RowLocationRetRowSource#closeRowSource */
96     public void closeRowSource()
97     {
98         rowSource.closeRowSource();
99     }
100     
101     private DataValueDescriptor[] clone(DataValueDescriptor[] clonee)
102     {
103         DataValueDescriptor[] cloned;
104
105         cloned = new DataValueDescriptor[clonee.length];
106         for (int i = 0; i < clonee.length - 1; i++)
107         {
108             cloned[i] = ((DataValueDescriptor)clonee[i]).getClone();
109         }
110         return cloned;
111     }
112
113     public void keepCount(DataValueDescriptor[] currentKey) throws StandardException
114     {
115         int numKeys = currentKey.length - 1; // always row location.
116
numRows++;
117         if (prevKey == null)
118         {
119             prevKey = clone(currentKey);
120             cardinality = new long[currentKey.length - 1];
121             for (int i = 0; i < numKeys; i++)
122                 cardinality[i] = 1;
123             return;
124         }
125         
126         int i;
127         for (i = 0; i < numKeys; i++)
128         {
129             if (((DataValueDescriptor)prevKey[i]).isNull())
130                 break;
131
132             if ((prevKey[i]).compare(currentKey[i]) != 0)
133             {
134                 // null out prevKey, so that the object gets
135
// garbage collected. is this too much object
136
// creation? can we do setColumn or some such
137
// in the object that already exists in prevKey?
138
// xxxstatRESOLVE--
139
prevKey = null;
140                 prevKey = clone(currentKey);
141                 break;
142             }
143         } // for
144

145         for (int j = i; j < numKeys; j++)
146             cardinality[j]++;
147     }
148     
149     /** return the array of cardinalities that are kept internally. One value
150      * for each leading key; i.e c1, (c1,c2), (c1,c2,c3) etc.
151      * @return an array of unique values.
152      */

153     public long[] getCardinality() { return cardinality; }
154
155     /**
156      * get the number of rows seen in the row source thus far.
157      * @return total rows seen from the row source.
158      */

159     public long getRowCount() { return numRows; }
160 }
161
Popular Tags