KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > medor > eval > lib > BinaryImplicitTC


1 /**
2  * MEDOR: Middleware Enabling Distributed Object Requests
3  *
4  * Copyright (C) 2001-2003 France Telecom R&D
5  * Contact: alexandre.lefebvre@rd.francetelecom.com
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  *
21  * Initial developers: M. Alia, A. Lefebvre
22  */

23
24 /**
25  * Package definition.
26  */

27
28 package org.objectweb.medor.eval.lib;
29
30 import org.objectweb.medor.api.MedorException;
31 import org.objectweb.medor.api.TupleStructure;
32 import org.objectweb.medor.eval.api.BinaryEvaluatedTC;
33 import org.objectweb.medor.eval.api.NodeEvaluator;
34 import org.objectweb.medor.expression.api.ParameterOperand;
35 import org.objectweb.medor.expression.api.Expression;
36 import org.objectweb.medor.expression.api.VariableOperand;
37 import org.objectweb.medor.expression.api.Operand;
38 import org.objectweb.medor.expression.api.ExpressionException;
39 import org.objectweb.medor.expression.lib.BasicVariableOperand;
40 import org.objectweb.medor.query.api.QueryNode;
41 import org.objectweb.medor.tuple.api.Tuple;
42 import org.objectweb.medor.tuple.api.TupleCollection;
43 import org.objectweb.medor.tuple.lib.MemoryTuple;
44
45 /**
46  * This class represents TupleCollection result of filtering or joining then
47  * projecting of two sub TupleCollection.
48  * <p>It is typically used for performing
49  * JoinProject and Intersection Operations. The indexes of the sub
50  * TupleCollection are getted by the to methods: getRightTCCursor() and
51  * getLeftTCCursor(). The type of the evaluation used is the Iterative one.
52  */

53 public class BinaryImplicitTC
54         extends BasicBinaryEvalutedTC
55         implements BinaryEvaluatedTC {
56
57     private ParameterOperand[] parameters;
58     private QueryNode query;
59     private Expression filter;
60     private TupleCollection leftTCResult;
61     private TupleCollection rightTCResult;
62     private Tuple tupleBuffer1,tupleBuffer2,concatResult;
63     private VariableOperand[] operandBuffer1,operandBuffer2,attConcatBuffers;
64     private int cursor;
65     private int leftTCSize, rightTCSize;
66     private boolean empty, isBuffer2Free = false ,isTheLast = false;
67     private Operand filterResult;
68
69     public BinaryImplicitTC(QueryNode query,
70                             NodeEvaluator leftNodeEvaluator,
71                             NodeEvaluator rightNodeEvaluator,
72                             ParameterOperand[] parameters)
73         throws MedorException {
74         this.closed = false;
75         this.parameters = parameters;
76         this.query = query;
77         this.filter = query.getQueryFilter();
78         try {
79             this.filterResult = filter.compileExpression();
80         }
81         catch (ExpressionException e) {
82             throw new MedorException(e);
83         }
84
85         // Fetching the left TupleCollection
86
leftTCResult = leftNodeEvaluator.fetchData(parameters);
87
88         // Fetching the right TupleCollection
89
rightTCResult = rightNodeEvaluator.fetchData(parameters);
90
91         leftTCSize = leftTCResult.getMetaData().getSize();
92         rightTCSize = rightTCResult.getMetaData().getSize();
93
94         // init the buffers of results
95
operandBuffer1 = new VariableOperand[query.getTupleStructure().getSize()];
96         operandBuffer2 = new VariableOperand[query.getTupleStructure().getSize()];
97         for (int cpt = 0; (cpt < query.getTupleStructure().getSize()); cpt++) {
98             operandBuffer1[cpt] =
99                 new BasicVariableOperand(
100                     query.getTupleStructure().getField(cpt + 1).getType());
101             operandBuffer2[cpt] =
102                 new BasicVariableOperand(
103                     query.getTupleStructure().getField(cpt + 1).getType());
104         }
105         tupleBuffer1 = new MemoryTuple(operandBuffer1);// Creating the buffer Tuple
106
tupleBuffer2 = new MemoryTuple(operandBuffer2);
107
108         // Init the Tuple concat
109
attConcatBuffers = new VariableOperand[leftTCSize + rightTCSize];
110         for (int cpt = 0; (cpt < leftTCSize); cpt++) {
111             attConcatBuffers[cpt] =
112                 new BasicVariableOperand(
113                     leftTCResult.getMetaData().getField(cpt + 1).getType());
114         }
115
116         for (int cpt = leftTCSize; (cpt < leftTCSize + rightTCSize); cpt++) {
117             attConcatBuffers[cpt] =
118                 new BasicVariableOperand(
119                     rightTCResult.getMetaData().getField(cpt + 1 - leftTCSize).getType());
120         }
121         concatResult = new MemoryTuple(attConcatBuffers); // Creating the buffer Tuple
122

123         // One method evaluation is to supose that if one of the two TupleCollection is empty then this TupleCollection
124
// object is then empty.
125
empty = (leftTCResult.isEmpty() || rightTCResult.isEmpty());
126         if (empty) {
127             cursor = 0;
128         } else {
129             // move the cursor to the first result if there is one and verfy if it is the last one
130
try {
131                 init();
132             }
133             catch (ExpressionException e) {
134                 throw new MedorException(e);
135             }
136         }
137     }
138
139     public TupleStructure getMetaData() throws MedorException {
140         return query.getTupleStructure();
141     }
142
143     public boolean isLast() throws MedorException {
144         if (closed) {
145             throw new MedorException("Impossible to use a closed TupleCollection");
146         }
147         return isTheLast;
148     }
149
150     public void close() throws MedorException {
151         closed = true;
152         if (leftTCResult!=null)
153             leftTCResult.close();
154         if (rightTCResult!=null)
155             rightTCResult.close();
156     }
157
158     public int card() throws MedorException {
159         return cursor;
160     }
161
162     public synchronized boolean next() throws MedorException {
163         if (closed) {
164             throw new MedorException("Impossible to use a closed TupleCollection");
165         }
166         Tuple leftTuple;
167         Tuple rightTuple;
168         boolean isMoved = false;
169
170         if (isEmpty() || (cursor == -2))
171             isMoved = false;
172         else if (isLast()) {
173             // All the tuples are iterated. we are at the last one
174
cursor = -2;
175             isMoved = false;
176         } else {
177             try {
178                 isMoved = true; // we are really at the next Tuple result
179
cursor++;
180                 do {
181                     // We verify if this tuple is the last one or not.
182
if (rightTCResult.next()) {
183                         leftTuple = leftTCResult.getTuple();
184                         rightTuple = rightTCResult.getTuple();
185                         concatTuple(leftTuple, rightTuple);
186                         filter.evaluate(parameters, concatResult);
187                     } else {
188                         if (leftTCResult.next()) {
189                             rightTCResult.first();
190                             rightTuple = rightTCResult.getTuple();
191                             leftTuple = leftTCResult.getTuple();
192                             // the result of the concatenation is always in the resultTuple
193
concatTuple(leftTuple, rightTuple);
194                             filter.evaluate(parameters, concatResult);
195                         } else
196                         // There no tuples to fetch
197
isTheLast = true;
198                     }
199                 } while (!(isTheLast) && !(filterResult.getBoolean()));
200                 if (!isTheLast) {
201                     if (isBuffer2Free) {
202                         // Loading the next result and storing in the nextTuple buffer
203
query.getTupleLoader().loadTuple(
204                             concatResult, operandBuffer2, parameters);
205                         isBuffer2Free = false;
206                     } else {
207                         // Loading the next result and storing in the currentTuple buffer
208
query.getTupleLoader().loadTuple(
209                             concatResult, operandBuffer1, parameters);
210                         isBuffer2Free = true;
211                     }
212
213                 } else {
214                     // Switch loadong result to the free buffer
215
isBuffer2Free = !isBuffer2Free;
216                 }
217             }
218             catch (ExpressionException e) {
219                 throw new MedorException(e);
220             }
221         }
222         return isMoved;
223     }
224
225     /**
226      * This method Move the cursor to the first result if there is one, load it, then it verfy if it is the last one.
227      * In the case of the last one it returns false whether it returns true.
228      */

229     private boolean init() throws MedorException, ExpressionException {
230
231         leftTCResult.first();// go to the first Tuple to iterate
232
rightTCResult.first();
233         isTheLast = false;
234         Tuple leftTuple = leftTCResult.getTuple();// Get the left tuple
235
Tuple rightTuple = rightTCResult.getTuple(); // Get the right Tuple
236
concatTuple(leftTuple, rightTuple);
237         // Start iterating and filtering to get the first Result
238
filter.evaluate(parameters, concatResult);
239         while (!empty && !filterResult.getBoolean()) {
240             if (rightTCResult.next()) {
241                 rightTuple = rightTCResult.getTuple();
242                 concatTuple(leftTuple, rightTuple);
243                 filter.evaluate(parameters, concatResult);
244             } else {
245                 if (leftTCResult.next()) {
246                     rightTCResult.first();
247                     rightTuple = rightTCResult.getTuple();
248                     leftTuple = leftTCResult.getTuple();
249                     concatTuple(leftTuple, rightTuple);
250                     filter.evaluate(parameters, concatResult);
251                 } else//There is no result for this TupleCollection Object
252
empty = true;
253             }
254         }
255         if (empty) {
256             cursor = 0;
257         } else {
258             // Loading the first Result in the buffer1
259
query.getTupleLoader().loadTuple(
260                 concatResult, operandBuffer1, parameters);
261
262             //Init the cursor
263
cursor = 1;
264             do {
265                 // Verfy if this first Result is not the last one
266
if (rightTCResult.next()) {
267                     rightTuple = rightTCResult.getTuple();
268                     concatTuple(leftTuple, rightTuple);
269                     filter.evaluate(parameters, concatResult);
270                 } else {
271                     if (leftTCResult.next()) {
272                         rightTCResult.first();
273                         rightTuple = rightTCResult.getTuple();
274                         leftTuple = leftTCResult.getTuple();
275                         concatTuple(leftTuple, rightTuple);
276                         filter.evaluate(parameters, concatResult);
277                     } else //There is only one result for this TupleCollection Object
278
isTheLast = true;
279                 }
280             } while (!(isTheLast) && !(filterResult.getBoolean()));
281             if (!isTheLast) {
282                 // Loading the next Result in the buffer2
283
query.getTupleLoader().loadTuple(
284                     concatResult, operandBuffer2, parameters);
285             }
286         }
287         return (!empty);
288     }
289
290     public synchronized void first() throws MedorException {
291         if (closed) {
292             throw new MedorException("Impossible to use a closed TupleCollection");
293         }
294         //The Initialization
295
try {
296             init();
297         }
298         catch (ExpressionException e) {
299             e.printStackTrace(); //To change body of catch statement use Options | File Templates.
300
}
301     }
302
303     public synchronized int getRow() throws MedorException {
304         if (closed) {
305             throw new MedorException("Impossible to use a closed TupleCollection");
306         }
307         return cursor;
308     }
309
310     public synchronized Tuple getTuple() throws MedorException {
311         if (closed) {
312             throw new MedorException("Impossible to use a closed TupleCollection");
313         }
314         if (!isEmpty() && getRow() >= 1) {
315             if (isBuffer2Free)
316                 return tupleBuffer2;
317             else
318                 return tupleBuffer1;
319         } else
320             throw new MedorException(" No elements fetched in this TupleCollection " + getRow());
321     }
322
323     public synchronized boolean isEmpty() throws MedorException {
324         if (closed) {
325             throw new MedorException("Impossible to use a closed TupleCollection");
326         }
327         return empty;
328     }
329
330     public synchronized boolean row(int numTuple) throws MedorException {
331         if (closed) {
332             throw new MedorException("Impossible to use a closed TupleCollection");
333         }
334         if ((cursor > numTuple) || (cursor < 0)) {
335             first();
336         }
337         boolean stop = false;
338         while ((cursor < numTuple) && !stop) {
339             if (!next()) {
340                 stop = true;
341             }
342         }
343         if (cursor != numTuple)
344             return false; // Tuple index error
345
else {
346             return true;
347         }
348
349     }
350
351     public synchronized Tuple getTuple(int numTuple) throws MedorException {
352         if (closed) {
353             throw new MedorException("Impossible to use a closed TupleCollection");
354         }
355         row(numTuple);
356         return getTuple();
357     }
358
359     public synchronized int getLeftTCCursor() throws MedorException {
360         if (closed) {
361             throw new MedorException("Impossible to use a closed TupleCollection");
362         }
363         return leftTCResult.getRow();
364     }
365
366     public synchronized int getRightTCCursor() throws MedorException {
367         if (closed) {
368             throw new MedorException("Impossible to use a closed TupleCollection");
369         }
370         return rightTCResult.getRow();
371     }
372
373     private void concatTuple(Tuple t1, Tuple t2) throws MedorException {
374         for (int cpt = 0; (cpt < leftTCSize); cpt++) {
375             attConcatBuffers[cpt] =
376                 (VariableOperand) t1.getLikeOperand(cpt + 1);
377         }
378         for (int cpt = 0; (cpt < rightTCSize); cpt++) {
379             attConcatBuffers[cpt + leftTCSize] =
380                 (VariableOperand) t2.getLikeOperand(cpt + 1);
381         }
382     }
383 }
Popular Tags