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

Method Observe

interpreter/runtimecost.go:97–175  ·  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

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