KickJava   Java API By Example, From Geeks To Geeks.

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


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 package org.objectweb.medor.eval.lib;
25
26 import org.objectweb.jorm.type.api.PType;
27 import org.objectweb.medor.api.MedorException;
28 import org.objectweb.medor.api.TupleStructure;
29 import org.objectweb.medor.eval.api.BinaryEvaluatedTC;
30 import org.objectweb.medor.eval.api.NodeEvaluator;
31 import org.objectweb.medor.eval.prefetch.api.PrefetchBuffer;
32 import org.objectweb.medor.eval.prefetch.api.PrefetchBufferHolder;
33 import org.objectweb.medor.expression.api.Expression;
34 import org.objectweb.medor.expression.api.ExpressionException;
35 import org.objectweb.medor.expression.api.Operand;
36 import org.objectweb.medor.expression.api.ParameterOperand;
37 import org.objectweb.medor.expression.api.VariableOperand;
38 import org.objectweb.medor.expression.lib.BasicVariableOperand;
39 import org.objectweb.medor.query.api.QueryNode;
40 import org.objectweb.medor.tuple.api.Tuple;
41 import org.objectweb.medor.tuple.api.TupleCollection;
42 import org.objectweb.medor.tuple.lib.MemoryTuple;
43 import org.objectweb.util.monolog.api.BasicLevel;
44
45 /**
46  * This classe is a TupleCollection result of a Select + Project Operations.
47  * It can be seen as a simple filtering of a sigle TupleCollection. It can be
48  * implemented with the BinaryImplicitTC but this implementation is more
49  * optimized and simplified.
50  */

51 public class SelProjEvaluatedTC
52         extends BasicBinaryEvalutedTC
53         implements BinaryEvaluatedTC, PrefetchBufferHolder {
54
55     private QueryNode query;
56     private Expression filter;
57     private TupleCollection subTupleCollection;
58     private ParameterOperand[] parameters;
59     private Tuple tupleBuffer1,tupleBuffer2;
60     private VariableOperand[] operandBuffer1,operandBuffer2;
61     private int cursor;
62     private boolean empty, isTheLast = false, isBuffer2Free = false;
63     //boolean to indicate whether close() has been explicitely called
64
private boolean userHasClosed = false;
65     Operand filterResult;
66     PrefetchBuffer prefetchBuffer;
67
68     public SelProjEvaluatedTC(QueryNode query,
69                               NodeEvaluator subNodeEvaluator,
70                               ParameterOperand[] parameters,
71                               PrefetchBuffer pb)
72         throws MedorException {
73         super();
74         this.query = query;
75         this.parameters = parameters;
76         this.filter = query.getQueryFilter();
77         try {
78             this.filterResult = filter.compileExpression();
79         }
80         catch (ExpressionException e) {
81             throw new MedorException(e);
82         }
83         this.prefetchBuffer = pb;
84         if (prefetchBuffer != null) {
85             pb.setTupleCollection(this);
86         }
87
88         // Init the two buffers
89
int size = query.getTupleStructure().getSize();
90         operandBuffer1 = new BasicVariableOperand[size];
91         operandBuffer2 = new BasicVariableOperand[size];
92         for (int cpt = 0; (cpt < query.getTupleStructure().getSize()); cpt++) {
93             PType type = query.getTupleStructure().getField(cpt + 1).getType();
94             operandBuffer1[cpt] = new BasicVariableOperand(type);
95             operandBuffer2[cpt] = new BasicVariableOperand(type);
96         }
97         tupleBuffer1 = new MemoryTuple(operandBuffer1); // Creating the Buffer1
98
tupleBuffer2 = new MemoryTuple(operandBuffer2);
99         subTupleCollection = subNodeEvaluator.fetchData(parameters);
100         empty = (subTupleCollection.isEmpty());
101         if (empty)
102             cursor = 0;
103         else
104             this.init();
105     }
106
107     public void invalidatePrefetchBuffer() throws MedorException {
108         if (debug) {
109             log.log(BasicLevel.DEBUG, "Invalidating PrefetchBuffer " + prefetchBuffer + " for " + this);
110         }
111         prefetchBuffer = null;
112         if (userHasClosed) {
113             if (debug) {
114                 log.log(BasicLevel.DEBUG, "The tupleCollection was closed earlier: closing it for real");
115             }
116             this.close();
117         }
118     }
119
120     public void close() throws MedorException {
121         if (debug) {
122             log.log(BasicLevel.DEBUG, "Closing TupleCollection " + this);
123         }
124         userHasClosed = true;
125         //closing only if the prefetchBuffer is null or has been closed.
126
if (prefetchBuffer == null || prefetchBuffer.isClosed()) {
127             if (debug) {
128                 log.log(BasicLevel.DEBUG, "PrefetchBuffer " + prefetchBuffer + " is null or was closed previously: real close of the TupleCollection");
129             }
130             prefetchBuffer = null;
131             super.close();
132             if (subTupleCollection != null) {
133                 subTupleCollection.close();
134             }
135         }
136     }
137
138     public TupleStructure getMetaData() throws MedorException {
139         return query.getTupleStructure();
140     }
141
142     public boolean isLast() throws MedorException {
143         return isTheLast;
144     }
145
146     public int card() throws MedorException {
147         return cursor;
148     }
149
150     public boolean next() throws MedorException {
151         Tuple currentTuple = null;
152         boolean moved = false;
153
154         if (isEmpty() || (cursor == -2))
155             moved = false;
156         else if (isLast()) {
157             // we have iterated all tuples
158
cursor = -2;
159             moved = false;
160         }
161         else {
162             try {
163                 // we move to the next Result
164
moved = true;
165                 cursor++;
166                 do {
167                     //Verify if there is others results
168
if (subTupleCollection.next()) {
169                         currentTuple = subTupleCollection.getTuple();
170                         filter.evaluate(parameters, currentTuple);
171                     }
172                     else {
173                         isTheLast = true;
174                     }
175                 } while (!(isTheLast) && !(filterResult.getBoolean()));
176                 if (!isTheLast) {
177                     if (isBuffer2Free) {
178                         //Load the next Result in the buffer2
179
query.getTupleLoader().loadTuple(currentTuple,
180                             operandBuffer2, parameters);
181                         isBuffer2Free = false;
182                     }
183                     else {
184                         //Load the next Result in the buffer1
185
query.getTupleLoader().loadTuple(currentTuple,
186                             operandBuffer1, parameters);
187                         isBuffer2Free = true;
188                     }
189                     if (prefetchBuffer != null) {
190                         prefetchBuffer.addPrefetchTuple();
191                     }
192                 }
193                 else
194                     isBuffer2Free = !isBuffer2Free;
195             }
196             catch (ExpressionException e) {
197                 throw new MedorException(e);
198             }
199         }
200         return moved;
201     }
202
203     /**
204      * This method Move the cursor to the first result if there is one, load it,
205      * then it verfy if it is the last one. In the case of the last one it
206      * returns false whether it returns true.
207      */

208     private boolean init() throws MedorException {
209         subTupleCollection.first();
210         isTheLast = false;
211         Tuple currentTuple;
212         isBuffer2Free = false;
213         currentTuple = subTupleCollection.getTuple();
214         try {
215             filter.evaluate(parameters, currentTuple);
216             while (!empty && !filterResult.getBoolean()) {
217                 if (subTupleCollection.next()) {
218                     currentTuple = subTupleCollection.getTuple();
219                     filter.evaluate(parameters, currentTuple);
220                 }
221                 else {
222                     empty = true;//This TupleCollection result is empty
223
}
224             }
225             if (empty) {
226                 cursor = -2;
227             }
228             else {
229                 // Loading the first result in the buffer1
230
query.getTupleLoader().loadTuple(currentTuple,
231                     operandBuffer1, parameters);
232                 cursor = 1;
233                 if (prefetchBuffer != null) {
234                     prefetchBuffer.addPrefetchTuple();
235                 }
236                 do {
237                     // Verify if there is other result
238
if (subTupleCollection.next()) {
239                         currentTuple = subTupleCollection.getTuple();
240                         filter.evaluate(parameters, currentTuple);
241                     }
242                     else {
243                         // There is no more results
244
isTheLast = true;
245                     }
246                 } while (!(isTheLast) && !(filterResult.getBoolean()));
247                 if (!isTheLast) {
248                     // Loading the next Result in the buffer2
249
query.getTupleLoader().loadTuple(currentTuple,
250                         operandBuffer2, parameters);
251                     if (prefetchBuffer != null) {
252                         prefetchBuffer.addPrefetchTuple();
253                     }
254                 }
255             }
256         }
257         catch (ExpressionException e) {
258             throw new MedorException(e);
259         }
260         return (!empty);
261     }
262
263     public void first() throws MedorException {
264         //The Initialisation
265
init();
266     }
267
268     public int getRow() throws MedorException {
269         return (empty || cursor<1
270                 ? cursor
271                 : (isBuffer2Free ? 1 : 0) + cursor);
272     }
273
274     public Tuple getTuple() throws MedorException {
275         if (!isEmpty() && getRow() >= 1) {
276             if (isBuffer2Free)
277                 return tupleBuffer2;
278             else
279                 return tupleBuffer1;
280         }
281         else
282             throw new MedorException(" No elements fetched in this TupleCollection");
283     }
284
285     public synchronized Tuple getTuple(int numTuple) throws MedorException {
286         row(numTuple);
287         return getTuple();
288     }
289
290     public boolean isEmpty() throws MedorException {
291         return empty;
292     }
293
294     public boolean row(int numTuple) throws MedorException {
295         first();
296         int cpt = 1;
297         boolean stop = false;
298         while ((cpt < numTuple) && !stop) {
299             if (!next())
300                 stop = true;
301             else
302                 cpt++;
303         }
304         if (cpt < numTuple)
305             return false;
306         else {
307             cursor = numTuple;
308             return true;
309         }
310
311     }
312
313     public int getLeftTCCursor() throws MedorException {
314         return subTupleCollection.getRow();
315     }
316
317     public int getRightTCCursor() throws MedorException {
318         return -1;
319     }
320 }
321
Popular Tags