-
Notifications
You must be signed in to change notification settings - Fork 67
/
bufferfilter.go
84 lines (74 loc) · 2.05 KB
/
bufferfilter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package expr
import (
"fmt"
"unicode/utf8"
"github.com/brimdata/zed"
"github.com/brimdata/zed/pkg/byteconv"
"github.com/brimdata/zed/pkg/stringsearch"
)
const (
opAnd = iota
opOr
opFieldNameFinder
opStringCaseFinder
opStringFinder
)
// BufferFilter is a filter for byte slices containing ZNG values.
type BufferFilter struct {
op int
left *BufferFilter
right *BufferFilter
fnf *FieldNameFinder
cf *stringsearch.CaseFinder
f *stringsearch.Finder
}
func NewAndBufferFilter(left, right *BufferFilter) *BufferFilter {
return &BufferFilter{op: opAnd, left: left, right: right}
}
func NewOrBufferFilter(left, right *BufferFilter) *BufferFilter {
return &BufferFilter{op: opOr, left: left, right: right}
}
func NewBufferFilterForFieldName(pattern string) *BufferFilter {
return &BufferFilter{
op: opFieldNameFinder,
fnf: NewFieldNameFinder(pattern),
}
}
func NewBufferFilterForString(pattern string) *BufferFilter {
if len(pattern) < 2 {
// Very short patterns are unprofitable.
return nil
}
return &BufferFilter{op: opStringFinder, f: stringsearch.NewFinder(pattern)}
}
func NewBufferFilterForStringCase(pattern string) *BufferFilter {
if len(pattern) < 2 {
// Very short patterns are unprofitable.
return nil
}
for _, r := range pattern {
if r >= utf8.RuneSelf {
// stringCaseFinder is sensitive to case for letters
// with multibyte UTF-8 encodings.
return nil
}
}
return &BufferFilter{op: opStringCaseFinder, cf: stringsearch.NewCaseFinder(pattern)}
}
// Eval returns true if buf matches the receiver and false otherwise.
func (b *BufferFilter) Eval(zctx *zed.Context, buf []byte) bool {
switch b.op {
case opAnd:
return b.left.Eval(zctx, buf) && b.right.Eval(zctx, buf)
case opOr:
return b.left.Eval(zctx, buf) || b.right.Eval(zctx, buf)
case opFieldNameFinder:
return b.fnf.Find(zctx, buf)
case opStringCaseFinder:
return b.cf.Next(byteconv.UnsafeString(buf)) > -1
case opStringFinder:
return b.f.Next(byteconv.UnsafeString(buf)) > -1
default:
panic(fmt.Sprintf("BufferFilter: unknown op %d", b.op))
}
}