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

Method costCall

interpreter/runtimecost.go:254–332  ·  view source on GitHub ↗
(call InterpretableCall, args []ref.Val, result ref.Val)

Source from the content-addressed store, hash-verified

252}
253
254func (c *CostTracker) costCall(call InterpretableCall, args []ref.Val, result ref.Val) uint64 {
255 var cost uint64
256 if len(c.overloadTrackers) != 0 {
257 if tracker, found := c.overloadTrackers[call.OverloadID()]; found {
258 callCost := tracker(args, result)
259 if callCost != nil {
260 cost += *callCost
261 return cost
262 }
263 }
264 }
265 if c.Estimator != nil {
266 callCost := c.Estimator.CallCost(call.Function(), call.OverloadID(), args, result)
267 if callCost != nil {
268 cost += *callCost
269 return cost
270 }
271 }
272 // if user didn't specify, the default way of calculating runtime cost would be used.
273 // if user has their own implementation of ActualCostEstimator, make sure to cover the mapping between overloadId and cost calculation
274 switch call.OverloadID() {
275 // O(n) functions
276 case overloads.StartsWithString, overloads.EndsWithString:
277 cost += uint64(math.Ceil(float64(actualSize(args[1])) * common.StringTraversalCostFactor))
278 case overloads.StringToBytes, overloads.BytesToString, overloads.ExtQuoteString, overloads.ExtFormatString:
279 cost += uint64(math.Ceil(float64(actualSize(args[0])) * common.StringTraversalCostFactor))
280 case overloads.InList:
281 // If a list is composed entirely of constant values this is O(1), but we don't account for that here.
282 // We just assume all list containment checks are O(n).
283 cost += actualSize(args[1])
284 // O(min(m, n)) functions
285 case overloads.LessString, overloads.GreaterString, overloads.LessEqualsString, overloads.GreaterEqualsString,
286 overloads.LessBytes, overloads.GreaterBytes, overloads.LessEqualsBytes, overloads.GreaterEqualsBytes,
287 overloads.Equals, overloads.NotEquals:
288 // When we check the equality of 2 scalar values (e.g. 2 integers, 2 floating-point numbers, 2 booleans etc.),
289 // the CostTracker.ActualSize() function by definition returns 1 for each operand, resulting in an overall cost
290 // of 1.
291 lhsSize := actualSize(args[0])
292 rhsSize := actualSize(args[1])
293 minSize := lhsSize
294 if rhsSize < minSize {
295 minSize = rhsSize
296 }
297 cost += uint64(math.Ceil(float64(minSize) * common.StringTraversalCostFactor))
298 // O(m+n) functions
299 case overloads.AddString, overloads.AddBytes:
300 // In the worst case scenario, we would need to reallocate a new backing store and copy both operands over.
301 cost += uint64(math.Ceil(float64(actualSize(args[0])+actualSize(args[1])) * common.StringTraversalCostFactor))
302 // O(nm) functions
303 case overloads.Matches, overloads.MatchesString:
304 // https://swtch.com/~rsc/regexp/regexp1.html applies to RE2 implementation supported by CEL
305 // Add one to string length for purposes of cost calculation to prevent product of string and regex to be 0
306 // in case where string is empty but regex is still expensive.
307 strCost := uint64(math.Ceil((1.0 + float64(actualSize(args[0]))) * common.StringTraversalCostFactor))
308 // We don't know how many expressions are in the regex, just the string length (a huge
309 // improvement here would be to somehow get a count the number of expressions in the regex or
310 // how many states are in the regex state machine and use that to measure regex cost).
311 // For now, we're making a guess that each expression in a regex is typically at least 4 chars

Callers 1

ObserveMethod · 0.45

Calls 4

actualSizeFunction · 0.70
OverloadIDMethod · 0.65
CallCostMethod · 0.65
FunctionMethod · 0.65

Tested by

no test coverage detected