| 509 | } |
| 510 | |
| 511 | void utilizeIndices |
| 512 | ( |
| 513 | ExecutionPlan *plan |
| 514 | ) { |
| 515 | GraphContext *gc = QueryCtx_GetGraphCtx(); |
| 516 | // return immediately if the graph has no indices |
| 517 | if(!GraphContext_HasIndices(gc)) return; |
| 518 | |
| 519 | // collect all label scans |
| 520 | OpBase **scanOps = ExecutionPlan_CollectOps(plan->root, |
| 521 | OPType_NODE_BY_LABEL_SCAN); |
| 522 | |
| 523 | int scanOpCount = array_len(scanOps); |
| 524 | for(int i = 0; i < scanOpCount; i++) { |
| 525 | NodeByLabelScan *scanOp = (NodeByLabelScan *)scanOps[i]; |
| 526 | |
| 527 | // make sure scan is followed by filter(s) |
| 528 | OpBase *parent = scanOp->op.parent; |
| 529 | if(parent->type != OPType_FILTER) { |
| 530 | // no filters to utilize |
| 531 | continue; |
| 532 | } |
| 533 | |
| 534 | // try to reduce label scan + filter(s) to a single IndexScan operation |
| 535 | reduce_scan_op(plan, scanOp); |
| 536 | } |
| 537 | |
| 538 | // collect all conditional traverse |
| 539 | OpBase **condOps = ExecutionPlan_CollectOps(plan->root, |
| 540 | OPType_CONDITIONAL_TRAVERSE); |
| 541 | |
| 542 | uint condOpCount = array_len(condOps); |
| 543 | for(uint i = 0; i < condOpCount; i++) { |
| 544 | OpCondTraverse *condOp = (OpCondTraverse *)condOps[i]; |
| 545 | // try to reduce conditional travers + filter(s) to a single IndexScan operation |
| 546 | reduce_cond_op(plan, condOp); |
| 547 | } |
| 548 | |
| 549 | // cleanup |
| 550 | array_free(scanOps); |
| 551 | array_free(condOps); |
| 552 | } |
| 553 |
no test coverage detected