1 21 package com.db4o; 22 23 import com.db4o.config.*; 24 import com.db4o.foundation.*; 25 import com.db4o.inside.marshall.*; 26 import com.db4o.query.*; 27 import com.db4o.reflect.*; 28 29 36 public class QCandidate extends TreeInt implements Candidate, Orderable { 37 38 40 YapReader _bytes; 42 43 final QCandidates _candidates; 44 45 private List4 _dependants; 47 48 boolean _include = true; 51 52 private Object _member; 53 54 Orderable _order; 56 57 Tree _pendingJoins; 59 60 private QCandidate _root; 62 63 YapClass _yapClass; 65 66 YapField _yapField; 69 MarshallerFamily _marshallerFamily; 70 71 private QCandidate(QCandidates qcandidates) { 72 super(0); 73 _candidates = qcandidates; 74 } 75 76 private QCandidate() { 77 this(null); 78 } 80 81 public QCandidate(QCandidates candidates, Object obj, int id, boolean include) { 82 super(id); 83 if (DTrace.enabled) { 84 DTrace.CREATE_CANDIDATE.log(id); 85 } 86 _candidates = candidates; 87 _order = this; 88 _member = obj; 89 _include = include; 90 91 if(id == 0){ 92 _key = candidates.generateCandidateId(); 93 } 94 } 95 96 public Object shallowClone() { 97 QCandidate qcan = new QCandidate(_candidates); 98 qcan.setBytes(_bytes); 99 qcan._dependants = _dependants; 100 qcan._include = _include; 101 qcan._member = _member; 102 qcan._order = _order; 103 qcan._pendingJoins = _pendingJoins; 104 qcan._root = _root; 105 qcan._yapClass = _yapClass; 106 qcan._yapField = _yapField; 107 108 return super.shallowCloneInternal(qcan); 109 } 110 111 void addDependant(QCandidate a_candidate) { 112 _dependants = new List4(_dependants, a_candidate); 113 } 114 115 private void checkInstanceOfCompare() { 116 if (_member instanceof Compare) { 117 _member = ((Compare) _member).compare(); 118 YapFile stream = getStream(); 119 _yapClass = stream.getYapClass(stream.reflector().forObject(_member)); 120 _key = (int) stream.getID(_member); 121 setBytes(stream.readReaderByID(getTransaction(), _key)); 122 } 123 } 124 125 public int compare(Tree a_to) { 126 return _order.compareTo(((QCandidate) a_to)._order); 127 } 128 129 public int compareTo(Object a_object) { 130 return _key - ((TreeInt) a_object)._key; 131 } 132 133 boolean createChild(final QCandidates a_candidates) { 134 if (!_include) { 135 return false; 136 } 137 138 if (_yapField != null) { 139 TypeHandler4 handler = _yapField.getHandler(); 140 if (handler != null) { 141 142 final YapReader[] arrayBytes = { _bytes }; 143 144 final TypeHandler4 arrayHandler = handler.readArrayHandler( 145 getTransaction(), _marshallerFamily, arrayBytes); 146 147 if (arrayHandler != null) { 148 149 final int offset = arrayBytes[0]._offset; 150 boolean outerRes = true; 151 152 157 Iterator4 i = a_candidates.iterateConstraints(); 158 while (i.moveNext()) { 159 160 QCon qcon = (QCon) i.current(); 161 QField qf = qcon.getField(); 162 if (qf == null || qf.i_name.equals(_yapField.getName())) { 163 164 QCon tempParent = qcon.i_parent; 165 qcon.setParent(null); 166 167 final QCandidates candidates = new QCandidates( 168 a_candidates.i_trans, null, qf); 169 candidates.addConstraint(qcon); 170 171 qcon.setCandidates(candidates); 172 arrayHandler.readCandidates(_marshallerFamily,arrayBytes[0], candidates); 173 arrayBytes[0]._offset = offset; 174 175 final boolean isNot = qcon.isNot(); 176 if (isNot) { 177 qcon.removeNot(); 178 } 179 180 candidates.evaluate(); 181 182 final Tree.ByRef pending = new Tree.ByRef(); 183 final boolean[] innerRes = { isNot }; 184 candidates.traverse(new Visitor4() { 185 public void visit(Object obj) { 186 187 QCandidate cand = (QCandidate) obj; 188 189 if (cand.include()) { 190 innerRes[0] = !isNot; 191 } 192 193 195 if (cand._pendingJoins != null) { 196 cand._pendingJoins 197 .traverse(new Visitor4() { 198 public void visit( 199 Object a_object) { 200 QPending newPending = (QPending) a_object; 201 202 newPending 211 .changeConstraint(); 212 QPending oldPending = (QPending) Tree 213 .find( 214 pending.value, 215 newPending); 216 if (oldPending != null) { 217 218 229 if (oldPending._result != newPending._result) { 230 oldPending._result = QPending.BOTH; 231 } 232 233 } else { 234 pending.value = Tree 235 .add( 236 pending.value, 237 newPending); 238 } 239 } 240 }); 241 } 242 } 243 }); 244 245 if (isNot) { 246 qcon.not(); 247 } 248 249 if (pending.value != null) { 253 pending.value.traverse(new Visitor4() { 254 public void visit(Object a_object) { 255 getRoot().evaluate((QPending) a_object); 256 } 257 }); 258 } 259 260 if (!innerRes[0]) { 261 262 if (Debug.queries) { 263 System.out 264 .println(" Array evaluation false. Constraint:" 265 + qcon.i_id); 266 } 267 268 273 qcon.visit(getRoot(), qcon.evaluator().not(false)); 274 275 outerRes = false; 276 } 277 278 qcon.setParent(tempParent); 279 280 } 281 } 282 283 return outerRes; 284 } 285 286 290 if (handler.getTypeID() == YapConst.TYPE_SIMPLE) { 291 a_candidates.i_currentConstraint.visit(this); 292 return true; 293 } 294 } 295 } 296 297 if(_yapField == null || _yapField instanceof YapFieldNull){ 298 return false; 299 } 300 301 _yapClass.findOffset(_bytes, _yapField); 302 QCandidate candidate = readSubCandidate(a_candidates); 303 if (candidate == null) { 304 return false; 305 } 306 307 if (a_candidates.i_yapClass != null 309 && a_candidates.i_yapClass.isStrongTyped()) { 310 if (_yapField != null) { 311 TypeHandler4 handler = _yapField.getHandler(); 312 if (handler != null 313 && (handler.getTypeID() == YapConst.TYPE_CLASS)) { 314 YapClass yc = (YapClass) handler; 315 if (yc instanceof YapClassAny) { 316 yc = candidate.readYapClass(); 317 } 318 if(yc == null){ 319 return false; 320 } 321 if (!yc.canHold(a_candidates.i_yapClass.classReflector())) { 322 return false; 323 } 324 } 325 } 326 } 327 328 addDependant(a_candidates.addByIdentity(candidate)); 329 return true; 330 } 331 332 void doNotInclude() { 333 _include = false; 334 if (_dependants != null) { 335 Iterator4 i = new Iterator4Impl(_dependants); 336 _dependants = null; 337 while (i.moveNext()) { 338 ((QCandidate) i.current()).doNotInclude(); 339 } 340 } 341 } 342 343 public boolean duplicates() { 344 return _order.hasDuplicates(); 345 } 346 347 boolean evaluate(final QConObject a_constraint, final QE a_evaluator) { 348 if (a_evaluator.identity()) { 349 return a_evaluator.evaluate(a_constraint, this, null); 350 } 351 if (_member == null) { 352 _member = value(); 353 } 354 return a_evaluator.evaluate(a_constraint, this, a_constraint 355 .translate(_member)); 356 } 357 358 boolean evaluate(QPending a_pending) { 359 360 if (Debug.queries) { 361 System.out.println("Pending arrived Join: " + a_pending._join.i_id 362 + " Constraint:" + a_pending._constraint.i_id + " res:" 363 + a_pending._result); 364 } 365 366 QPending oldPending = (QPending) Tree.find(_pendingJoins, a_pending); 367 368 if (oldPending == null) { 369 a_pending.changeConstraint(); 370 _pendingJoins = Tree.add(_pendingJoins, a_pending); 371 return true; 372 } 373 _pendingJoins = _pendingJoins.removeNode(oldPending); 374 oldPending._join.evaluatePending(this, oldPending, a_pending._result); 375 return false; 376 } 377 378 ReflectClass classReflector() { 379 readYapClass(); 380 if (_yapClass == null) { 381 return null; 382 } 383 return _yapClass.classReflector(); 384 } 385 386 388 public ObjectContainer objectContainer() { 389 return getStream(); 390 } 391 392 public Object getObject() { 393 Object obj = value(true); 394 if (obj instanceof YapReader) { 395 YapReader reader = (YapReader) obj; 396 int offset = reader._offset; 397 obj = _marshallerFamily._string.readFromOwnSlot(getStream(), reader); 398 reader._offset = offset; 399 } 400 return obj; 401 } 402 403 QCandidate getRoot() { 404 return _root == null ? this : _root; 405 } 406 407 private YapFile getStream() { 408 return getTransaction().i_file; 409 } 410 411 private Transaction getTransaction() { 412 return _candidates.i_trans; 413 } 414 415 public boolean hasDuplicates() { 416 417 421 return _root != null; 422 } 423 424 public void hintOrder(int a_order, boolean a_major) { 425 _order = new Order(); 426 _order.hintOrder(a_order, a_major); 427 } 428 429 public boolean include() { 430 return _include; 431 } 432 433 437 public void include(boolean flag) { 438 _include = flag; 441 } 442 443 public void isDuplicateOf(Tree a_tree) { 444 _size = 0; 445 _root = (QCandidate) a_tree; 446 } 447 448 private ReflectClass memberClass() { 449 return getTransaction().reflector().forObject(_member); 450 } 451 452 YapComparable prepareComparison(YapStream a_stream, Object a_constraint) { 453 if (_yapField != null) { 454 return _yapField.prepareComparison(a_constraint); 455 } 456 if (_yapClass == null) { 457 458 YapClass yc = null; 459 if (_bytes != null) { 460 yc = a_stream.produceYapClass(a_stream.reflector().forObject(a_constraint)); 461 } else { 462 if (_member != null) { 463 yc = a_stream.getYapClass(a_stream.reflector().forObject(_member)); 464 } 465 } 466 if (yc != null) { 467 if (_member != null && _member.getClass().isArray()) { 468 TypeHandler4 ydt = (TypeHandler4) yc 469 .prepareComparison(a_constraint); 470 if (a_stream.reflector().array().isNDimensional( 471 memberClass())) { 472 YapArrayN yan = new YapArrayN(a_stream, ydt, false); 473 return yan; 474 } 475 YapArray ya = new YapArray(a_stream, ydt, false); 476 return ya; 477 478 } 479 return yc.prepareComparison(a_constraint); 480 481 } 482 return null; 483 } 484 return _yapClass.prepareComparison(a_constraint); 485 } 486 487 private void read() { 488 if (_include) { 489 if (_bytes == null) { 490 if (_key > 0) { 491 if (DTrace.enabled) { 492 DTrace.CANDIDATE_READ.log(_key); 493 } 494 setBytes(getStream().readReaderByID(getTransaction(), _key)); 495 if (_bytes == null) { 496 _include = false; 497 } 498 } else { 499 _include = false; 500 } 501 } 502 } 503 } 504 505 private QCandidate readSubCandidate(QCandidates candidateCollection) { 506 read(); 507 if (_bytes != null) { 508 509 QCandidate subCandidate = null; 510 final int offset = _bytes._offset; 511 try { 512 subCandidate = _yapField.i_handler.readSubCandidate(_marshallerFamily, _bytes, candidateCollection, false); 513 } catch (Exception e) { 514 return null; 515 } 516 _bytes._offset = offset; 517 518 if (subCandidate != null) { 519 subCandidate._root = getRoot(); 520 return subCandidate; 521 } 522 } 523 return null; 524 } 525 526 private void readThis(boolean a_activate) { 527 read(); 528 529 Transaction trans = getTransaction(); 530 if (trans != null) { 531 532 _member = trans.stream().getByID1(trans, _key); 533 534 if (_member != null && (a_activate || _member instanceof Compare)) { 535 trans.stream().activate1(trans, _member); 536 checkInstanceOfCompare(); 537 } 538 } 539 } 540 541 YapClass readYapClass() { 542 if (_yapClass == null) { 543 read(); 544 if (_bytes != null) { 545 546 _bytes._offset = 0; 547 548 YapStream stream = getStream(); 549 ObjectHeader objectHeader = new ObjectHeader(stream, _bytes); 550 _yapClass = objectHeader.yapClass(); 551 552 if (_yapClass != null) { 553 if (stream.i_handlers.ICLASS_COMPARE 554 .isAssignableFrom(_yapClass.classReflector())) { 555 readThis(false); 556 } 557 } 558 } 559 } 560 return _yapClass; 561 } 562 563 public String toString() { 564 if (!Debug4.prettyToStrings) { 565 return super.toString(); 566 } 567 String str = "QCandidate "; 568 if (_yapClass != null) { 569 str += "\n YapClass " + _yapClass.getName(); 570 } 571 if (_yapField != null) { 572 str += "\n YapField " + _yapField.getName(); 573 } 574 if (_member != null) { 575 str += "\n Member " + _member.toString(); 576 } 577 if (_root != null) { 578 str += "\n rooted by:\n"; 579 str += _root.toString(); 580 } else { 581 str += "\n ROOT"; 582 } 583 return str; 584 } 585 586 void useField(QField a_field) { 587 read(); 588 if (_bytes == null) { 589 _yapField = null; 590 return; 591 } 592 readYapClass(); 593 _member = null; 594 if (a_field == null) { 595 _yapField = null; 596 return; 597 } 598 if (_yapClass == null) { 599 _yapField = null; 600 return; 601 } 602 _yapField = a_field.getYapField(_yapClass); 603 604 _marshallerFamily = _yapClass.findOffset(_bytes, _yapField); 605 606 if (_yapField == null || _marshallerFamily == null ) { 607 if (_yapClass.holdsAnyClass()) { 608 _yapField = null; 610 } else { 611 613 _yapField = new YapFieldNull(); 614 } 615 } 616 } 617 618 Object value() { 619 return value(false); 620 } 621 622 Object value(boolean a_activate) { 625 if (_member == null) { 626 if (_yapField == null) { 627 readThis(a_activate); 628 } else { 629 int offset = _bytes._offset; 631 try { 632 _member = _yapField.readQuery(getTransaction(),_marshallerFamily, _bytes); 633 } catch (CorruptionException ce) { 634 _member = null; 635 } 636 _bytes._offset = offset; 637 checkInstanceOfCompare(); 638 } 639 } 640 return _member; 641 } 642 643 void setBytes(YapReader bytes){ 644 _bytes = bytes; 645 } 646 } 647 | Popular Tags |