| 428 | func (*SpansetFilter) __spansetExpression() {} |
| 429 | |
| 430 | func (f *SpansetFilter) evaluate(input []*Spanset) ([]*Spanset, error) { |
| 431 | var ( |
| 432 | // When evaluating the input, it is most efficient to return the input when we can. |
| 433 | // This is possible when every input spanset and span passes the filter. |
| 434 | // If anything fails, then we use a copy-on-write approach, copying the input up to the mismatch and then |
| 435 | // appending further spansets after. |
| 436 | outputBuffer []*Spanset |
| 437 | forked bool |
| 438 | ) |
| 439 | |
| 440 | fork := func(i int) { |
| 441 | if !forked { |
| 442 | // The output is being initially forked, so copy all previously identical spansets into the output. |
| 443 | if i > 0 { |
| 444 | outputBuffer = append(outputBuffer, input[:i]...) |
| 445 | } |
| 446 | } |
| 447 | forked = true |
| 448 | } |
| 449 | |
| 450 | for i, ss := range input { |
| 451 | if ss == nil || len(ss.Spans) == 0 { |
| 452 | // This spanset is nil or empty so it's dropped. |
| 453 | fork(i) |
| 454 | continue |
| 455 | } |
| 456 | |
| 457 | f.matchingSpansBuffer = f.matchingSpansBuffer[:0] |
| 458 | |
| 459 | for _, s := range ss.Spans { |
| 460 | result, err := f.Expression.execute(s) |
| 461 | if err != nil { |
| 462 | return nil, err |
| 463 | } |
| 464 | |
| 465 | if b, ok := result.Bool(); !ok || !b { |
| 466 | continue |
| 467 | } |
| 468 | |
| 469 | f.matchingSpansBuffer = append(f.matchingSpansBuffer, s) |
| 470 | } |
| 471 | |
| 472 | if len(f.matchingSpansBuffer) == 0 { |
| 473 | // All spans were filtered out of this spanset. |
| 474 | fork(i) |
| 475 | continue |
| 476 | } |
| 477 | |
| 478 | if len(f.matchingSpansBuffer) == len(ss.Spans) { |
| 479 | // All matched, so we can use this input spanset exactly as-is. |
| 480 | // If we have forked the overall input previously, |
| 481 | // then copy it to the new output. |
| 482 | // Otherwise we are continuing to use the input and nothing do to. |
| 483 | if forked { |
| 484 | outputBuffer = append(outputBuffer, ss) |
| 485 | } |
| 486 | continue |
| 487 | } |