125 lines
4.3 KiB
Markdown
125 lines
4.3 KiB
Markdown
# filter - a simple struct field filter for go
|
|
|
|
## Usage
|
|
|
|
```
|
|
// Example data structure
|
|
type Example struct {
|
|
String string
|
|
Int int
|
|
Bool bool
|
|
Struct Struct1
|
|
}
|
|
|
|
type Struct1 struct {
|
|
String string
|
|
Struct Struct2
|
|
}
|
|
|
|
type Struct2 struct {
|
|
Int int
|
|
}
|
|
|
|
// Filter implements the filter.Filter interface
|
|
type Filter []Example
|
|
|
|
func (v Filter) Len() int { return len(v) }
|
|
func (v Filter) Index(i int) interface{} { return v[i] }
|
|
func (v *Filter) Remove(i, j int) { *v = append((*v)[:i], (*v)[j:]...) }
|
|
|
|
// Example data
|
|
var data = Filter{
|
|
{"str1", 42, true, Struct1{"s1", Struct2{1}}},
|
|
{"2str", 42, true, Struct1{"s2", Struct2{2}}},
|
|
{"str3", 42, false, Struct1{"s3", Struct2{3}}},
|
|
}
|
|
```
|
|
|
|
### Struct fields
|
|
|
|
Supported struct field values are:
|
|
|
|
* `int`, `int8`, `int16`, `int32`, `int64`
|
|
* `float32`, `float64`
|
|
* `string`
|
|
* `bool`
|
|
|
|
For nested structs:
|
|
|
|
* `struct`
|
|
|
|
### Filter logic
|
|
|
|
Supported logical matching:
|
|
|
|
* `AND` - all of the queries have to match
|
|
* `OR` - only one query has to match
|
|
* `NOT` - none of the queries have to match
|
|
|
|
### Explicit match
|
|
|
|
```
|
|
filter.NewQuery("Bool:true", filter.OR).Filter(&data)
|
|
|
|
data = [{str1 42 true {s1 {1}}} {str2 42 true {s2 {2}}}]
|
|
```
|
|
|
|
### Wildcard match
|
|
|
|
Wildcard operator: `*`
|
|
To match the `'*'` character use: `**`
|
|
|
|
```
|
|
filter.NewQuery("String:s*", filter.OR).Filter(&data)
|
|
|
|
data = [{str1 42 true {s1 {1}}} {str3 42 false {s3 {3}}}]
|
|
```
|
|
|
|
### Nested struct match
|
|
|
|
```
|
|
filter.NewQuery("Struct.Struct.Int:3", filter.OR).Filter(&data)
|
|
|
|
data = [{str3 42 false {s3 {3}}}]
|
|
```
|
|
|
|
### Multiple matches
|
|
|
|
```
|
|
filter.NewQuery("Struct.String:*2 Bool:true", filter.AND).Filter(&data)
|
|
|
|
data = [{2str 42 true {s2 {2}}}]
|
|
```
|
|
|
|
## Benchmarks
|
|
|
|
```
|
|
go test -cpu 1,2,4 --bench .
|
|
BenchmarkNewQuerySimple 3000000 401 ns/op 176 B/op 7 allocs/op
|
|
BenchmarkNewQuerySimple-2 5000000 390 ns/op 176 B/op 7 allocs/op
|
|
BenchmarkNewQuerySimple-4 2000000 792 ns/op 176 B/op 7 allocs/op
|
|
BenchmarkNewQueryComplex 1000000 1416 ns/op 656 B/op 17 allocs/op
|
|
BenchmarkNewQueryComplex-2 1000000 1384 ns/op 656 B/op 17 allocs/op
|
|
BenchmarkNewQueryComplex-4 1000000 2488 ns/op 656 B/op 17 allocs/op
|
|
BenchmarkNewQueryComplexOr 1000000 1192 ns/op 640 B/op 17 allocs/op
|
|
BenchmarkNewQueryComplexOr-2 1000000 1158 ns/op 640 B/op 17 allocs/op
|
|
BenchmarkNewQueryComplexOr-4 1000000 1963 ns/op 640 B/op 17 allocs/op
|
|
BenchmarkFilterSimple 2000000 907 ns/op 432 B/op 12 allocs/op
|
|
BenchmarkFilterSimple-2 2000000 899 ns/op 432 B/op 12 allocs/op
|
|
BenchmarkFilterSimple-4 1000000 1468 ns/op 432 B/op 12 allocs/op
|
|
BenchmarkFilterComplex 500000 3129 ns/op 672 B/op 48 allocs/op
|
|
BenchmarkFilterComplex-2 500000 3208 ns/op 672 B/op 48 allocs/op
|
|
BenchmarkFilterComplex-4 500000 6644 ns/op 672 B/op 48 allocs/op
|
|
BenchmarkFilterComplexOr 500000 2698 ns/op 816 B/op 39 allocs/op
|
|
BenchmarkFilterComplexOr-2 500000 2832 ns/op 816 B/op 39 allocs/op
|
|
BenchmarkFilterComplexOr-4 500000 5509 ns/op 816 B/op 39 allocs/op
|
|
BenchmarkGenericFilterSimple 500000 2386 ns/op 1200 B/op 24 allocs/op
|
|
BenchmarkGenericFilterSimple-2 1000000 2360 ns/op 1200 B/op 24 allocs/op
|
|
BenchmarkGenericFilterSimple-4 1000000 3656 ns/op 1200 B/op 24 allocs/op
|
|
BenchmarkGenericFilterComplex 200000 7178 ns/op 1680 B/op 96 allocs/op
|
|
BenchmarkGenericFilterComplex-2 200000 7102 ns/op 1680 B/op 96 allocs/op
|
|
BenchmarkGenericFilterComplex-4 200000 12602 ns/op 1680 B/op 96 allocs/op
|
|
BenchmarkGenericFilterComplexOr 200000 5454 ns/op 2456 B/op 61 allocs/op
|
|
BenchmarkGenericFilterComplexOr-2 300000 5444 ns/op 2456 B/op 61 allocs/op
|
|
BenchmarkGenericFilterComplexOr-4 300000 9970 ns/op 2456 B/op 61 allocs/op
|
|
```
|