(e ast.Expr)
| 655 | } |
| 656 | |
| 657 | func (c *coster) costComprehension(e ast.Expr) CostEstimate { |
| 658 | comp := e.AsComprehension() |
| 659 | var sum CostEstimate |
| 660 | sum = sum.Add(c.cost(comp.IterRange())) |
| 661 | sum = sum.Add(c.cost(comp.AccuInit())) |
| 662 | c.pushLocalVar(comp.AccuVar(), comp.AccuInit()) |
| 663 | |
| 664 | // Track the iterRange of each IterVar and AccuVar for field path construction |
| 665 | if comp.HasIterVar2() { |
| 666 | c.pushIterKey(comp.IterVar(), comp.IterRange()) |
| 667 | c.pushIterValue(comp.IterVar2(), comp.IterRange()) |
| 668 | } else { |
| 669 | c.pushIterSingle(comp.IterVar(), comp.IterRange()) |
| 670 | } |
| 671 | |
| 672 | // Determine the cost for each element in the loop |
| 673 | loopCost := c.cost(comp.LoopCondition()) |
| 674 | stepCost := c.cost(comp.LoopStep()) |
| 675 | |
| 676 | // Clear the intermediate variable tracking. |
| 677 | c.popLocalVar(comp.IterVar()) |
| 678 | if comp.HasIterVar2() { |
| 679 | c.popLocalVar(comp.IterVar2()) |
| 680 | } |
| 681 | |
| 682 | // Determine the result cost. |
| 683 | sum = sum.Add(c.cost(comp.Result())) |
| 684 | c.localVars.pop(comp.AccuVar()) |
| 685 | |
| 686 | // Estimate the cost of the loop. |
| 687 | rangeCnt := c.sizeOrUnknown(comp.IterRange()) |
| 688 | rangeCost := rangeCnt.MultiplyByCost(stepCost.Add(loopCost)) |
| 689 | sum = sum.Add(rangeCost) |
| 690 | |
| 691 | switch k := comp.AccuInit().Kind(); k { |
| 692 | case ast.LiteralKind: |
| 693 | c.setSize(e, c.computeSize(comp.AccuInit())) |
| 694 | case ast.ListKind, ast.MapKind: |
| 695 | c.setSize(e, &rangeCnt) |
| 696 | // For a step which produces a container value, it will have an entry size associated |
| 697 | // with its expression id. |
| 698 | if stepEntrySize := c.computeEntrySize(comp.LoopStep()); stepEntrySize != nil { |
| 699 | c.setEntrySize(e, stepEntrySize) |
| 700 | break |
| 701 | } |
| 702 | } |
| 703 | return sum |
| 704 | } |
| 705 | |
| 706 | func (c *coster) isBind(e ast.Expr) bool { |
| 707 | comp := e.AsComprehension() |
no test coverage detected