(scans)
| 574 | } |
| 575 | |
| 576 | function stratify(scans) { |
| 577 | if(!scans.length) return [new BlockStratum([], [])]; |
| 578 | |
| 579 | let aggregates = []; |
| 580 | let variableInfo = {}; |
| 581 | let blockLevel = {}; |
| 582 | |
| 583 | let provide = (variable, scan) => { |
| 584 | if(join.isVariable(variable)) { |
| 585 | let info = variableInfo[variable.id] |
| 586 | if(!info) { |
| 587 | info = variableInfo[variable.id] = {providers: []}; |
| 588 | } |
| 589 | info.providers.push(scan); |
| 590 | } |
| 591 | } |
| 592 | |
| 593 | let maybeLevelVariable = (scan, level, variable) => { |
| 594 | if(join.isVariable(variable)) { |
| 595 | let info = variableInfo[variable.id] |
| 596 | let minLevel = level; |
| 597 | for(let provider of info.providers) { |
| 598 | let providerLevel = blockLevel[provider.id] || 0; |
| 599 | minLevel = Math.min(minLevel, providerLevel); |
| 600 | } |
| 601 | info.level = minLevel; |
| 602 | } |
| 603 | } |
| 604 | |
| 605 | for(let scan of scans) { |
| 606 | if(scan instanceof join.Scan) { |
| 607 | provide(scan.e, scan); |
| 608 | provide(scan.a, scan); |
| 609 | provide(scan.v, scan); |
| 610 | } else if(scan instanceof Aggregate || scan instanceof Sort) { |
| 611 | aggregates.push(scan); |
| 612 | blockLevel[scan.id] = 1; |
| 613 | for(let ret of scan.returns) { |
| 614 | provide(ret, scan); |
| 615 | } |
| 616 | } else if(scan instanceof join.Constraint) { |
| 617 | for(let ret of scan.returns) { |
| 618 | provide(ret, scan); |
| 619 | } |
| 620 | } else if(scan instanceof join.IfScan) { |
| 621 | for(let output of scan.outputs) { |
| 622 | provide(output, scan); |
| 623 | } |
| 624 | } else if(scan instanceof join.NotScan) { |
| 625 | // not can never provide a variable, so there's nothing |
| 626 | // we need to do here |
| 627 | } |
| 628 | } |
| 629 | |
| 630 | // Before we start to stratify, we need to run through all the aggregates |
| 631 | // to determine what level their returns should be at. If the aggregate is |
| 632 | // the only provider for the return, then it should be at the same level as |
| 633 | // the aggregate itself. If, however, there are other scans that provide the |
no test coverage detected