1 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 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 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 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); 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 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 cursor = -2; 159 moved = false; 160 } 161 else { 162 try { 163 moved = true; 165 cursor++; 166 do { 167 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 query.getTupleLoader().loadTuple(currentTuple, 180 operandBuffer2, parameters); 181 isBuffer2Free = false; 182 } 183 else { 184 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 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; } 224 } 225 if (empty) { 226 cursor = -2; 227 } 228 else { 229 query.getTupleLoader().loadTuple(currentTuple, 231 operandBuffer1, parameters); 232 cursor = 1; 233 if (prefetchBuffer != null) { 234 prefetchBuffer.addPrefetchTuple(); 235 } 236 do { 237 if (subTupleCollection.next()) { 239 currentTuple = subTupleCollection.getTuple(); 240 filter.evaluate(parameters, currentTuple); 241 } 242 else { 243 isTheLast = true; 245 } 246 } while (!(isTheLast) && !(filterResult.getBoolean())); 247 if (!isTheLast) { 248 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 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 |