KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > daffodilwoods > daffodildb > server > sql99 > dql > iterator > set > ExceptDistinctIterator


1 package com.daffodilwoods.daffodildb.server.sql99.dql.iterator.set;
2
3 import com.daffodilwoods.daffodildb.client.*;
4 import com.daffodilwoods.daffodildb.server.sql99.common.*;
5 import com.daffodilwoods.daffodildb.server.sql99.dql.iterator.*;
6 import com.daffodilwoods.daffodildb.server.sql99.utils.*;
7 import com.daffodilwoods.daffodildb.utils.comparator.*;
8 import com.daffodilwoods.database.resource.*;
9
10 /**
11  * <p>Title: ExceptDistinctIterator </p>
12  * <p>This class is required to retrieve the records from a query having EXCEPT
13  * DISTINCT clause. The Except Distinct operator of two result set displays, all
14  * the disinct records from the left iterator that are not present in the right
15  * iterator. The underlying iterators data is SORTED. Since, the duplicate rows
16  * are retrieved sequencially to ensure distinct records retrieval. </p>
17  * <p>Copyright: Copyright (c) 2003</p>
18  * <p>Company: </p>
19  * @author unascribed
20  * @version 1.0
21  */

22 public class ExceptDistinctIterator extends ExceptAllIterator {
23
24    /**
25     * A public constructor, that takes five arguments, two are left and right iterators, and
26     * other two are left and right side selected column References. A comparator is also provided for the
27     * purpose of comparison.
28     *
29     * A state is also maintained, that specifies the current status of the current level iterator(this).
30     *
31     * The State INVALIDSTATE means iterator is not aligned properly and needs to be aligned
32     * before doing any further operations.
33     *
34     * The State VALIDSTATE means iterator is aligned properly and can be moved next()/ previous()
35     * as well as values can also be retrieved
36     *
37     * The State BEFOREFIRST means, iterator has reached before the first record or there is no record in the result set.
38     * Iterator is not aligned properly and needs to be aligned through calling first()/ last() before doing any further operations.
39     *
40     * The State AFTERLAST means, iterator has reached after the last record or there is no record in the result set.
41     * Iterator is not aligned properly and needs to be aligned through calling first()/ last() before doing any further operations.
42     *
43     * @param leftIterator left iterator
44     * @param rightIterator right iterator
45     * @param leftColumnReferences0 selected columns from left iterator
46     * @param rightColumnReferences0 selected columns from right iterator
47     * @param comparator0 comparator that is used to compare the selected column
48     * values from left iterator with that of right iterator
49     * @throws DException
50     */

51    public ExceptDistinctIterator(_Iterator leftIterator, _Iterator rightIterator, _Reference[] leftColumnReferences, _Reference[] rightColumnReferences, SuperComparator comparator0, _Reference[] orderLeftCD0, _Reference[] orderRightCD0, SuperComparator leftComparator0, SuperComparator rightComparator0) throws DException {
52       super(leftIterator, rightIterator, leftColumnReferences, rightColumnReferences, comparator0, orderLeftCD0, orderRightCD0, leftComparator0, rightComparator0);
53       checkInSecondIterator = true;
54       state = INVALIDSTATE;
55    }
56
57    /**
58     * This method is responsible for retrieving the first record.
59     * 1. First record from both underlying iterator is retrieved. If left
60     * iterator has no records, return false.
61     * 2. Now, a record has to be retrieved from the left iterator such that
62     * right iterator has no record that has same selected column values as
63     * that of current record from left iterator. If right iterator has no
64     * records, goto step 3, else goto step 4.
65     * 3. Variable checkInSecondIterator is set to false indicating that now,
66     * there is no need to check records from right iterator, all the records
67     * from the left iterator will be returned. Return true.
68     * 4. Selected Column Values got from right iterator are compared with that
69     * of current record from left iterator.
70     * a. If both values are same, navigate both iterators in forward direction
71     * to skip the common record. goto step 5.
72     * b. Else If left iterator has smaller values, right iterator can't get
73     * similar set of values if navigated in forward direction from current
74     * position, since the data of right iterator is sorted. Return true.
75     * c. Else navigate the right iterator in the forward direction till right
76     * iterator is pointed to record that has larger or equal values of
77     * selected columns as compared to left iterator. goto step 5.
78     * 5. If right iterator has no more records, goto step 3, else goto step 4.
79     *
80     * DETAILED DOCUMENTATION
81     *
82     * i. If leftiterator.first() returns false then the state 'll be set to AFTERLAST and the method 'll return false .
83     * ii. Else if rightIterator.first() return false then flag 'checkInSecondIterator' 'll be set to false implying
84     * that all records from the current position to the last of firstIterator 'll be the next valid records for ExceptDistinctIterator
85     * and the method 'll return true and state 'll be set to VALIDSTATE.
86     * iii.Else alignnext() 'll be called that 'll align to the next distinct valid record that is not present in the second iterator
87     * and its result 'll be returned.
88     *
89     * @return
90     * @throws DException
91     */

92    public boolean first() throws DException {
93       checkInSecondIterator = true;
94       if (!leftIterator.first()) {
95          state = AFTERLAST;
96          return false;
97       }
98       if (!rightIterator.first()) {
99          checkInSecondIterator = false;
100          state = VALIDSTATE;
101          return true;
102       }
103       return (state = alignNext() ? VALIDSTATE : AFTERLAST) != AFTERLAST;
104    }
105
106    /**
107     * This method is responsible for retrieving the next record.
108     * 1. Next distinct record from left iterator is retrieved. If no record
109     * found, return false.
110     * 2. Now, a record has to be retrieved from the left iterator such that
111     * right iterator has no record that has same selected column values as that
112     * of current record from left iterator. Selected Column Values got from right
113     * iterator are compared with that of current record from left iterator.
114     * a. If both values are same, navigate both iterators in forward direction
115     * to skip the common record. goto step 5.
116     * b. Else If left iterator has smaller values, right iterator can't get
117     * similar set of values if navigated in forward direction from current
118     * position, since the data of right iterator is sorted. Return true.
119     * c. Else navigate the right iterator in the forward direction till right
120     * iterator is pointed to record that has larger or equal values of
121     * selected columns as compared to left iterator. goto step 5.
122     * 3. If right iterator has no more records, Variable checkInSecondIterator
123     * is set to false indicating that now, there is no need to check records
124     * from right iterator, all the records from the left iterator will be
125     * returned. Return true, Else goto step 2.
126     *
127     * DETAILED DOCUMENTATION
128     *
129     * i. If previous state is INVALIDSTATE,
130     * through Invalid State Exception.
131     * ii. Else If previous state is AFTERLAST,
132     * return false.
133     * iii. Else If previous state is BEFOREFIRST,
134     * call and return its first() .
135     * iv. Else If left Iterator could not iterate to the valid next position then method 'll return false.
136     * v. Else alignnext() 'll be called that 'll align to the next valid record that is not present in the second iterator
137     * and its result 'll be returned.
138     *
139     * @return
140     * @throws DException
141     */

142    public boolean next() throws DException {
143       if (state == INVALIDSTATE) {
144          throw new DException("DSE4116", null);
145       }
146       if (state == BEFOREFIRST) {
147          return first();
148       }
149       if (!moveForwardDistinct(leftIterator, leftIterator.getColumnValues(orderLeftCD), orderLeftCD, true)) {
150          state = AFTERLAST;
151          return false;
152       }
153       return (state = alignNext() ? state : AFTERLAST) != AFTERLAST;
154    }
155
156    /**
157     * This method is responsible for retrieving the previous record.
158     * 1. Previous distinct record from left iterator is retrieved. If
159     * no record found, return false.
160     * 2. Now, a record has to be retrieved from the left iterator such that
161     * right iterator has no record that has same selected column values as that
162     * of current record from left iterator. Selected Column Values got from right
163     * iterator are compared with that of current record from left iterator.
164     * a. If both values are same, navigate both iterators in backward direction
165     * to skip the common record. goto step 6.
166     * b. Else If left iterator has larger values, right iterator can't get
167     * similar set of values if navigated in backward direction from current
168     * position, since the data of right iterator is sorted. Return true.
169     * c. Else navigate the right iterator in the backward direction till right
170     * iterator is pointed to record that has smaller or equal values of
171     * selected columns as compared to left iterator. goto step 5.
172     * 3. If right iterator has no more records, Variable checkInSecondIterator
173     * is set to false indicating that now, there is no need to check records
174     * from right iterator, all the records from the left iterator will be
175     * returned. Return true, Else goto step 2.
176     *
177     * DETAILED DOCUMENTATION
178     *
179     * i. If previous state is INVALIDSTATE,
180     * through Invalid State Exception.
181     * ii. Else If previous state is BEFOREFIRST,
182     * return false.
183     * iii.Else If previous state is AFTERLAST,
184     * call and return its last() .
185     * iv. Else If left Iterator could not iterate to the valid previous position then method 'll return false.
186     * v. Else alignprevious() 'll be called that 'll align to the previous valid record that is not present in the second iterator
187     * and its result 'll be returned.
188     *
189     * @return
190     * @throws DException
191     */

192    public boolean previous() throws DException {
193       if (state == INVALIDSTATE) {
194          throw new DException("DSE4117", null);
195       }
196       if (state == AFTERLAST) {
197          return last();
198       }
199       if (!moveBackwardDistinct(leftIterator, leftIterator.getColumnValues(orderLeftCD), orderLeftCD, true)) {
200          state = BEFOREFIRST;
201          return false;
202       }
203       return (state = alignPrevious() ? state : BEFOREFIRST) != BEFOREFIRST;
204    }
205
206    /**
207     * This method is responsible for retrieving the last record.
208     * 1. Last record from both underlying iterator is retrieved. If left
209     * iterator has no records, return false.
210     * 2. Now, a record has to be retrieved from the left iterator such that
211     * right iterator has no record that has same selected column values as
212     * that of current record from left iterator. If right iterator has no
213     * records, goto step 3, else goto step 4.
214     * 3. Variable checkInSecondIterator is set to false indicating that now,
215     * there is no need to check records from right iterator, all the records
216     * from the left iterator will be returned. Return true.
217     * 4. Selected Column Values got from right iterator are compared with that
218     * of current record from left iterator.
219     * a. If both values are same, navigate both iterators in backward direction
220     * to skip the common record. goto step 5.
221     * b. Else If left iterator has larger values, right iterator can't get
222     * similar set of values if navigated in backward direction from current
223     * position, since the data of right iterator is sorted. Return true.
224     * c. Else navigate the right iterator in the backward direction till right
225     * iterator is pointed to record that has smaller or equal values of
226     * selected columns as compared to left iterator. goto step 5.
227     * 5. If right iterator has no more records, goto step 3, else goto step 4.
228     *
229     * DETAILED DOCUMENTAION
230     *
231     * Algo :
232     *
233     * i. If leftiterator.last() returns false then the state 'll be set to BEFOREFIRST and the method 'll return false .
234     * ii. Else if rightIterator.last() return false then flag 'checkInSecondIterator' 'll be set to false implying
235     * that all records from the current position to the first of firstIterator 'll be the distinct valid records for ExceptDistinctIterator
236     * and the method 'll return true and state 'll be set to VALIDSTATE.
237     * iii.Else alignprevious() 'll be called that 'll align to the Distinct previous valid record that is not present in the second iterator
238     * and its result 'll be returned.
239     *
240     * @return
241     * @throws DException
242     */

243    public boolean last() throws DException {
244       checkInSecondIterator = true;
245       if (!leftIterator.last()) {
246          state = BEFOREFIRST;
247          return false;
248       }
249       if (!rightIterator.last()) {
250          checkInSecondIterator = false;
251          state = VALIDSTATE;
252          return true;
253       }
254       return (state = alignPrevious() ? VALIDSTATE : BEFOREFIRST) != BEFOREFIRST;
255    }
256
257    /**
258     * This method is responsible to display the executionPlan of a Select Query.
259     * @return _ExecutionPlan
260     * @throws DException
261     */

262    public _ExecutionPlan getExecutionPlan() throws DException {
263       _ExecutionPlan cplans[] = new _ExecutionPlan[2];
264       cplans[0] = leftIterator.getExecutionPlan();
265       cplans[1] = rightIterator.getExecutionPlan();
266       return new ExecutionPlan("ExceptDistinctIterator", cplans, null, null, null);
267    }
268
269    /**
270     * This method is responsible to display the iterators hierarchy of a Select Query.
271     * @return ExecutionPlanForBrowser
272     * @throws DException
273     */

274    public ExecutionPlanForBrowser getExecutionPlanForBrowser() throws DException {
275       ExecutionPlanForBrowser cplans[] = new ExecutionPlanForBrowser[2];
276       cplans[0] = leftIterator.getExecutionPlanForBrowser();
277       cplans[1] = rightIterator.getExecutionPlanForBrowser();
278       return new ExecutionPlanForBrowser("Except Distinct", "ExceptDistinctIterator", cplans, null, null, null);
279    }
280
281    /**
282     * The purpose of this method is to align the left iterator in the forward
283     * direction to a record with distinct selected column values such that right
284     * iterator has no record with values of selected columns same as that of
285     * current record from left iterator.
286     *
287     * Algo :
288     *
289     * 1. if flag <checkInSecondIterator> is false, then method 'll return true.
290     * 2. Repeat step 3 to 6 unconditionally.
291     * 3. Else left and right side value 'll be evaluated .
292     * 4. Based on the comparison result, if both are equal then both the iterators 'll be moved to its next record. If
293     * left could not move, method 'll return false . If right iterator couldn't move then flag <checkInSecondIterator>
294     * 'll be set to false and the method 'll return tue.
295     * 5. IF left Value is greater than the right one, then right Iterator 'll be moved to its next distinct position.If right ]
296     * iterator couldn't moved successfully then flag <checkInSecondIterator>
297     * 'll be set to false and the method 'll return tue and continue in the loop.
298     * 6 Else return true.
299     *
300     * @return
301     * @throws DException
302     */

303    boolean alignNext() throws DException {
304       if (!checkInSecondIterator && !rightIterator.next()) {
305          return true;
306       } while (true) {
307          Object JavaDoc leftObjectValues = leftIterator.getColumnValues(orderLeftCD);
308          Object JavaDoc rightObjectValues = rightIterator.getColumnValues(orderRightCD);
309          int cmp = compare(leftObjectValues, rightObjectValues);
310          if (cmp == 0) {
311             if (!moveForwardDistinct(leftIterator, leftObjectValues, orderLeftCD, true)) {
312                return false;
313             }
314             if (!moveForwardDistinct(rightIterator, rightObjectValues, orderRightCD, false)) {
315                checkInSecondIterator = false;
316                return true;
317             }
318          } else if (cmp > 0) {
319             if (!moveForwardDistinct(rightIterator, rightObjectValues, orderRightCD, false)) {
320                checkInSecondIterator = false;
321                return true;
322             }
323          } else {
324             checkInSecondIterator = true;
325             return true;
326          }
327       }
328    }
329
330    /**
331     * The purpose of this method is to align the left iterator in the backward
332     * direction to a record with distinct selected column values such that right
333     * iterator has no record with values of selected columns same as that of
334     * current record from left iterator.
335     *
336     * Algo :
337     *
338     * 1. if flag <checkInSecondIterator> is false, then method 'll return true.
339     * 2. Repeat step 3 to 6 unconditionally.
340     * 3. Else left and right side value 'll be evaluated .
341     * 4. Based on the comparison result, if both are equal then both the iterators 'll be moved to its previous record. If
342     * left could not move, method 'll return false . If right iterator couldn't move then flag <checkInSecondIterator>
343     * 'll be set to false and the method 'll return tue.
344     * 5. IF left Value is smaller than the right one, then right Iterator 'll be moved to its previous distinct position.If right ]
345     * iterator couldn't moved successfully then flag <checkInSecondIterator>
346     * 'll be set to false and the method 'll return tue and continue in the loop.
347     * 6 Else return true.
348     *
349     * @return
350     * @throws DException
351     */

352    boolean alignPrevious() throws DException {
353       if (!checkInSecondIterator && !rightIterator.previous()) {
354          return true;
355       } while (true) {
356          Object JavaDoc leftObjectValues = leftIterator.getColumnValues(orderLeftCD);
357          Object JavaDoc rightObjectValues = rightIterator.getColumnValues(orderRightCD);
358          int cmp = compare(leftObjectValues, rightObjectValues);
359          if (cmp == 0) {
360             if (!moveBackwardDistinct(leftIterator, leftObjectValues, orderLeftCD, true)) {
361                return false;
362             }
363             if (!moveBackwardDistinct(rightIterator, rightObjectValues, orderRightCD, true)) {
364                checkInSecondIterator = false;
365                return true;
366             }
367          } else if (cmp < 0) {
368             if (!moveBackwardDistinct(rightIterator, rightObjectValues, orderRightCD, false)) {
369                checkInSecondIterator = false;
370                return true;
371             }
372          } else {
373             checkInSecondIterator = true;
374             return true;
375          }
376       }
377    }
378
379
380    public String JavaDoc toString() {
381       return "ExceptDistinctIterator [" + leftIterator + "] [" + rightIterator + "]";
382    }
383 }
384
Popular Tags