KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > daffodilwoods > daffodildb > server > sql99 > dql > iterator > table > MaxMinIterator


1 package com.daffodilwoods.daffodildb.server.sql99.dql.iterator.table;
2
3 import com.daffodilwoods.daffodildb.server.sql99.common.*;
4 import com.daffodilwoods.daffodildb.server.sql99.dql.iterator.*;
5 import com.daffodilwoods.daffodildb.server.sql99.utils.*;
6 import com.daffodilwoods.daffodildb.utils.*;
7 import com.daffodilwoods.daffodildb.utils.field.*;
8 import com.daffodilwoods.database.resource.*;
9
10 /**
11  * <p>Title: MaxMinIterator </p>
12  * <p>Description: This class is responsible for the MAX and MIN aggregate
13  * function computation. This class comes into picture when the passed argument
14  * column has index on it. In case of index on a column, first value will be
15  * MINIMUM value and the last value will be MAXIMUM value. If one of the boundary
16  * values is null, iterator is navigated accordingly to return the non-null
17  * result of given aggregate function. This class takes part in the optimisation,
18  * when the argument column passed has index on it. </p>
19  * <p>Copyright: Copyright (c) 2003</p>
20  * <p>Company: </p>
21  * @author unascribed
22  * @version 1.0
23  */

24
25 public class MaxMinIterator extends BaseSingleIterator implements _Iterator, SimpleConstants {
26
27    private _Reference childReference;
28    /**
29     * Variable representing whether the aggregate function is MIN OR MAX.
30     */

31    private int maxMin;
32    private ColumnDetails[] aggregateColumns;
33
34    /**
35     * Variable representing the status of the underlying iterator.
36     */

37    private int status;
38    /**
39     * Variable represents whether the underlying iterator has data.
40     * @usage if the underlying iterator has no data, null value is
41     * returned for both aggregate methods.
42     */

43    private boolean isHavingData = true;
44
45    public MaxMinIterator(_Iterator iterator0, ColumnDetails[] aggregateColumns0) throws DException {
46       super(iterator0);
47       String JavaDoc functionType = aggregateColumns0[0].getFunctionType();
48       if (functionType.equalsIgnoreCase("Max")) {
49          maxMin = MAX;
50       } else if (functionType.equalsIgnoreCase("Min")) {
51          maxMin = MIN;
52       } else {
53          throw new DException("DSE0", new Object JavaDoc[] {"Invalid Type Set For Aggregate"});
54       }
55       childReference = aggregateColumns0[0].getChildColumnDetails()[0];
56       aggregateColumns = aggregateColumns0;
57    }
58
59    /**
60     * The following methods are used for the navigation of the maxmin
61     * iterator. Since, Aggregate function causes in the retrival of one
62     * record, all navigation method performs in following way:
63     * Checks the given aggregate function.
64     * If the given aggregate function is MAX
65     * Get the last record from the underlying iterator,since the
66     * values are indexed and maximum value can be found from last
67     * record. Check the value of passed argument column.
68     * If the value is not null
69     * Return the record.
70     * Else
71     * Navigate the underlying iterator in the backward direction
72     * till the record with non-null values is found.
73     * If non-null value is not found, return NULL.
74     * Otherwise, If the given aggregate function is MIN
75     * Get the first record from the underlying iterator,since the
76     * values are indexed and minimum value can be found from last
77     * record. Check the value of passed argument column.
78     * If the value is not null
79     * Return the record.
80     * Else
81     * Navigate the underlying iterator in the forward direction
82     * till the record with non-null values is found.
83     * If non-null value is not found, return NULL.
84     */

85    /**
86     * This method is responsible to return the first record from the
87     * underlying iterator.
88     * @return true if underlying iterator has records, false otherwise.
89     * @throws DException
90     */

91    public boolean first() throws DException {
92       if (maxMin == MAX) {
93          checkPrevious();
94       } else {
95          checkNext();
96       }
97       return true;
98    }
99
100    /**
101     * This method is responsible to return the last record from the
102     * underlying iterator.
103     * @return true if underlying iterator has records, false otherwise.
104     * @throws DException
105     */

106    public boolean last() throws DException {
107       if (maxMin == MAX) {
108          checkPrevious();
109       } else {
110          checkNext();
111       }
112       return true;
113    }
114
115    /**
116     * This method is responsible to return the next record from the
117     * underlying iterator. It checks the state of iterator. If the iterator is
118     * at BEFOREFIRST, returns the first record, otherwise, returns false,
119     * indicating that there are no more records.
120     * @return true if underlying iterator has records, false otherwise.
121     * @throws DException
122     */

123    public boolean next() throws DException {
124       if (status == BEFOREFIRST) {
125          return first();
126       }
127       status = AFTERLAST;
128       return false;
129    }
130
131    /**
132     * This method is responsible to return the previous record from the
133     * underlying iterator. It checks the state of iterator. If the iterator is
134     * at AFTERLAST, returns the last record, otherwise, returns false,
135     * indicating that there are no more records.
136     * @return true if underlying iterator has records, false otherwise.
137     * @throws DException
138     */

139    public boolean previous() throws DException {
140       if (status == AFTERLAST) {
141          return last();
142       }
143       status = BEFOREFIRST;
144       return false;
145    }
146
147    /**
148     * This method is responsible to assist the maxmin iterator for
149     * navigation in backward direction. Underlying iterator is navigated
150     * in the backward direction till the non-null value of passed column is
151     * found. If there is no record having non-null value of passed column,
152     * vaiable isHavingData is set to false indicating that underlying iterator
153     * has no data.
154     * @throws DException
155     */

156    private void checkPrevious() throws DException {
157       if (iterator.last()) {
158          FieldBase fb = (FieldBase) iterator.getColumnValues(childReference);
159          while (fb.isNull()) {
160             if (iterator.previous()) {
161                fb = (FieldBase) iterator.getColumnValues(childReference);
162             } else {
163                iterator.next();
164                return;
165             }
166          }
167          status = VALIDSTATE;
168       } else {
169          isHavingData = false;
170       }
171    }
172
173    /**
174     * This method is responsible to assist the maxmin iterator for
175     * navigation in forward direction. Underlying iterator is navigated
176     * in the forward direction till the non-null value of passed column is
177     * found. If there is no record having non-null value of passed column,
178     * vaiable isHavingData is set to false indicating that underlying iterator
179     * has no data.
180     * @throws DException
181     */

182    private void checkNext() throws DException {
183       if (iterator.first()) {
184          FieldBase fb = (FieldBase) iterator.getColumnValues(childReference);
185          while (fb.isNull()) {
186             if (iterator.next()) {
187                fb = (FieldBase) iterator.getColumnValues(childReference);
188             } else {
189                iterator.previous();
190                return;
191             }
192          }
193          status = VALIDSTATE;
194       } else {
195          isHavingData = false;
196       }
197    }
198
199    /**
200     * The following methods are used for the retrieval of given aggregate
201     * function. If the underlying iterator has no data, null is returned as
202     * the given aggregate function result, Otherwise, value of passed column
203     * is retrieved from the underlying iterator.
204     */

205    /**
206     * This method is used to retrieve the values of passed references.
207     * @param reference reference for which values are to be retrived.
208     * Reference may be column or parameter.
209     * @return NonShared FieldBases denoting the value of References. Non Shared
210     * FieldBases are those for which BufferRange is not shared with some other
211     * FieldBase.
212     * @throws DException
213     */

214    public Object JavaDoc getColumnValues(_Reference[] reference) throws DException {
215       Object JavaDoc[] values = new Object JavaDoc[reference.length];
216       for (int i = 0; i < reference.length; i++) {
217          values[i] = getColumnValues(reference[i]);
218       }
219       return values;
220    }
221
222    /**
223     * This method is used to retrieve the value of passed reference. It checks,
224     * whether the underlying iteartor has data, if does, the value of passed
225     * column in given aggregate function is returned from the underlying iterator.
226     * @param reference reference for which value is to be retrived.
227     * Reference may be column or parameter.
228     * @return NonShared FieldBase denoting the value of Reference. Non Shared
229     * FieldBases are those for which BufferRange is not shared with some other
230     * FieldBase.
231     * @throws DException
232     */

233    public Object JavaDoc getColumnValues(_Reference reference) throws DException {
234       for (int i = 0; i < aggregateColumns.length; i++) {
235          if (aggregateColumns[i].getColumn().trim().equalsIgnoreCase(reference.getColumn().trim())) {
236             return isHavingData ? iterator.getColumnValues(childReference) : FieldUtility.NULLFIELDBASE;
237          }
238       }
239       return isHavingData ? iterator.getColumnValues(reference) : FieldUtility.NULLFIELDBASE;
240    }
241
242    /**
243     * This method return the shared FieldBase for the passed reference. By Shared
244     * FieldBase we mean, BufferRange of FieldBase is shared with other FieldBase
245     * objects.
246     * @param reference reference for which value is to be retrived
247     * @return shared field base correspondition to passed column reference
248     * @throws DException
249     */

250    public FieldBase field(_Reference reference) throws DException {
251       for (int i = 0; i < aggregateColumns.length; i++) {
252          if (aggregateColumns[i].getColumn().trim().equalsIgnoreCase(reference.getColumn().trim())) {
253             return isHavingData ? iterator.field(childReference) : FieldUtility.NULLFIELDBASE;
254          }
255       }
256       return isHavingData ? iterator.field(reference) : FieldUtility.NULLFIELDBASE;
257    }
258
259    /**
260     * This method return the shared FieldBases for the passed references. By Shared
261     * FieldBase we mean, BufferRange of FieldBase is shared with other FieldBase
262     * objects.
263     * @param references reference for which values are to be retrived
264     * @return shared field base correspondition to passed column reference
265     * @throws DException
266     */

267    public FieldBase[] fields(_Reference[] references) throws com.daffodilwoods.database.resource.DException {
268       FieldBase[] values = new FieldBase[references.length];
269       for (int i = 0; i < references.length; i++) {
270          values[i] = field(references[i]);
271       }
272       return values;
273    }
274
275
276    public String JavaDoc toString() {
277       return "MaxMinIterator [" + iterator + "]";
278    }
279 }
280
Popular Tags