1 23 24 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 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 leftTCResult = leftNodeEvaluator.fetchData(parameters); 87 88 rightTCResult = rightNodeEvaluator.fetchData(parameters); 90 91 leftTCSize = leftTCResult.getMetaData().getSize(); 92 rightTCSize = rightTCResult.getMetaData().getSize(); 93 94 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); tupleBuffer2 = new MemoryTuple(operandBuffer2); 107 108 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); 123 empty = (leftTCResult.isEmpty() || rightTCResult.isEmpty()); 126 if (empty) { 127 cursor = 0; 128 } else { 129 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 cursor = -2; 175 isMoved = false; 176 } else { 177 try { 178 isMoved = true; cursor++; 180 do { 181 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 concatTuple(leftTuple, rightTuple); 194 filter.evaluate(parameters, concatResult); 195 } else 196 isTheLast = true; 198 } 199 } while (!(isTheLast) && !(filterResult.getBoolean())); 200 if (!isTheLast) { 201 if (isBuffer2Free) { 202 query.getTupleLoader().loadTuple( 204 concatResult, operandBuffer2, parameters); 205 isBuffer2Free = false; 206 } else { 207 query.getTupleLoader().loadTuple( 209 concatResult, operandBuffer1, parameters); 210 isBuffer2Free = true; 211 } 212 213 } else { 214 isBuffer2Free = !isBuffer2Free; 216 } 217 } 218 catch (ExpressionException e) { 219 throw new MedorException(e); 220 } 221 } 222 return isMoved; 223 } 224 225 229 private boolean init() throws MedorException, ExpressionException { 230 231 leftTCResult.first(); rightTCResult.first(); 233 isTheLast = false; 234 Tuple leftTuple = leftTCResult.getTuple(); Tuple rightTuple = rightTCResult.getTuple(); concatTuple(leftTuple, rightTuple); 237 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 empty = true; 253 } 254 } 255 if (empty) { 256 cursor = 0; 257 } else { 258 query.getTupleLoader().loadTuple( 260 concatResult, operandBuffer1, parameters); 261 262 cursor = 1; 264 do { 265 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 isTheLast = true; 279 } 280 } while (!(isTheLast) && !(filterResult.getBoolean())); 281 if (!isTheLast) { 282 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 try { 296 init(); 297 } 298 catch (ExpressionException e) { 299 e.printStackTrace(); } 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; 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 |