MCPcopy Create free account
hub / github.com/cel-expr/cel-go / Observe

Method Observe

interpreter/runtimecost.go:94–172  ·  view source on GitHub ↗

Observe computes the incremental cost of each step and records it into the CostTracker associated with the evaluation.

(vars Activation, id int64, programStep any, val ref.Val)

Source from the content-addressed store, hash-verified

92// Observe computes the incremental cost of each step and records it into the CostTracker associated
93// with the evaluation.
94func (ct *costTrackerFactory) Observe(vars Activation, id int64, programStep any, val ref.Val) {
95 frame := AsFrame(vars)
96 state := ct.GetState(frame)
97 if state == nil {
98 return
99 }
100 tracker, ok := state.(*CostTracker)
101 if !ok {
102 // The state is configured with CostTrackFactory so this shouldn't happen.
103 return
104 }
105 switch t := programStep.(type) {
106 case ConstantQualifier:
107 // TODO: Push identifiers on to the stack before observing constant qualifiers that apply to them
108 // and enable the below pop. Once enabled this can case can be collapsed into the Qualifier case.
109 tracker.cost++
110 case InterpretableConst:
111 // zero cost
112 case InterpretableAttribute:
113 switch a := t.Attr().(type) {
114 case *conditionalAttribute:
115 // Ternary has no direct cost. All cost is from the conditional and the true/false branch expressions.
116 tracker.stack.drop(a.falsy.ID(), a.truthy.ID(), a.expr.ID())
117 default:
118 tracker.stack.drop(t.Attr().ID())
119 tracker.cost += common.SelectAndIdentCost
120 }
121 if !tracker.presenceTestHasCost {
122 if _, isTestOnly := programStep.(*evalTestOnly); isTestOnly {
123 tracker.cost -= common.SelectAndIdentCost
124 }
125 }
126 case *evalExhaustiveConditional:
127 // Ternary has no direct cost. All cost is from the conditional and the true/false branch expressions.
128 tracker.stack.drop(t.attr.falsy.ID(), t.attr.truthy.ID(), t.attr.expr.ID())
129
130 // While the field names are identical, the boolean operation eval structs do not share an interface and so
131 // must be handled individually.
132 case *evalOr:
133 for _, term := range t.terms {
134 tracker.stack.drop(term.ID())
135 }
136 case *evalAnd:
137 for _, term := range t.terms {
138 tracker.stack.drop(term.ID())
139 }
140 case *evalExhaustiveOr:
141 for _, term := range t.terms {
142 tracker.stack.drop(term.ID())
143 }
144 case *evalExhaustiveAnd:
145 for _, term := range t.terms {
146 tracker.stack.drop(term.ID())
147 }
148 case *evalFold:
149 tracker.stack.drop(t.iterRange.ID())
150 case Qualifier:
151 tracker.cost++

Callers

nothing calls this directly

Calls 11

GetStateMethod · 0.95
AsFrameFunction · 0.85
dropMethod · 0.80
dropArgsMethod · 0.80
AttrMethod · 0.65
IDMethod · 0.65
ArgsMethod · 0.65
InitValsMethod · 0.65
TypeMethod · 0.65
costCallMethod · 0.45
pushMethod · 0.45

Tested by

no test coverage detected