mirror of https://github.com/grafana/loki
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
4.5 KiB
151 lines
4.5 KiB
|
6 months ago
|
package indexpointers
|
||
|
|
|
||
|
|
import (
|
||
|
|
"github.com/apache/arrow-go/v18/arrow/scalar"
|
||
|
|
)
|
||
|
|
|
||
|
|
// Predicate is an expression used to filter column values in a [Reader].
|
||
|
|
type Predicate interface{ isPredicate() }
|
||
|
|
|
||
|
|
// Supported predicates.
|
||
|
|
type (
|
||
|
|
// An AndPredicate is a [Predicate] which asserts that a row may only be
|
||
|
|
// included if both the Left and Right Predicate are true.
|
||
|
|
AndPredicate struct{ Left, Right Predicate }
|
||
|
|
|
||
|
|
// An OrPredicate is a [Predicate] which asserts that a row may only be
|
||
|
|
// included if either the Left or Right Predicate are true.
|
||
|
|
OrPredicate struct{ Left, Right Predicate }
|
||
|
|
|
||
|
|
// A NotePredicate is a [Predicate] which asserts that a row may only be
|
||
|
|
// included if the inner Predicate is false.
|
||
|
|
NotPredicate struct{ Inner Predicate }
|
||
|
|
|
||
|
|
// TruePredicate is a [Predicate] which always returns true.
|
||
|
|
TruePredicate struct{}
|
||
|
|
|
||
|
|
// FalsePredicate is a [Predicate] which always returns false.
|
||
|
|
FalsePredicate struct{}
|
||
|
|
|
||
|
|
// An EqualPredicate is a [Predicate] which asserts that a row may only be
|
||
|
|
// included if the Value of the Column is equal to the Value.
|
||
|
|
EqualPredicate struct {
|
||
|
|
Column *Column // Column to check.
|
||
|
|
Value scalar.Scalar // Value to check equality for.
|
||
|
|
}
|
||
|
|
|
||
|
|
// An InPredicate is a [Predicate] which asserts that a row may only be
|
||
|
|
// included if the Value of the Column is present in the provided Values.
|
||
|
|
InPredicate struct {
|
||
|
|
Column *Column // Column to check.
|
||
|
|
Values []scalar.Scalar // Values to check for inclusion.
|
||
|
|
}
|
||
|
|
|
||
|
|
// A GreaterThanPredicate is a [Predicate] which asserts that a row may only
|
||
|
|
// be included if the Value of the Column is greater than the provided Value.
|
||
|
|
GreaterThanPredicate struct {
|
||
|
|
Column *Column // Column to check.
|
||
|
|
Value scalar.Scalar // Value for which rows in Column must be greater than.
|
||
|
|
}
|
||
|
|
|
||
|
|
// A LessThanPredicate is a [Predicate] which asserts that a row may only be
|
||
|
|
// included if the Value of the Column is less than the provided Value.
|
||
|
|
LessThanPredicate struct {
|
||
|
|
Column *Column // Column to check.
|
||
|
|
Value scalar.Scalar // Value for which rows in Column must be less than.
|
||
|
|
}
|
||
|
|
|
||
|
|
// FuncPredicate is a [Predicate] which asserts that a row may only be
|
||
|
|
// included if the Value of the Column passes the Keep function.
|
||
|
|
//
|
||
|
|
// Instances of FuncPredicate are ineligible for page filtering and should
|
||
|
|
// only be used when there isn't a more explicit Predicate implementation.
|
||
|
|
FuncPredicate struct {
|
||
|
|
Column *Column // Column to check.
|
||
|
|
|
||
|
|
// Keep is invoked with the column and value pair to check. Keep is given
|
||
|
|
// the Column instance to allow for reusing the same function across
|
||
|
|
// multiple columns, if necessary.
|
||
|
|
//
|
||
|
|
// If Keep returns true, the row is kept.
|
||
|
|
Keep func(column *Column, value scalar.Scalar) bool
|
||
|
|
}
|
||
|
|
)
|
||
|
|
|
||
|
|
func (AndPredicate) isPredicate() {}
|
||
|
|
func (OrPredicate) isPredicate() {}
|
||
|
|
func (NotPredicate) isPredicate() {}
|
||
|
|
func (TruePredicate) isPredicate() {}
|
||
|
|
func (FalsePredicate) isPredicate() {}
|
||
|
|
func (EqualPredicate) isPredicate() {}
|
||
|
|
func (InPredicate) isPredicate() {}
|
||
|
|
func (GreaterThanPredicate) isPredicate() {}
|
||
|
|
func (LessThanPredicate) isPredicate() {}
|
||
|
|
func (FuncPredicate) isPredicate() {}
|
||
|
|
|
||
|
|
// walkPredicate traverses a predicate in depth-first order: it starts by
|
||
|
|
// calling fn(p). If fn(p) returns true, walkPredicate is invoked recursively
|
||
|
|
// with fn for each of the non-nil children of p, followed by a call of
|
||
|
|
// fn(nil).
|
||
|
|
func walkPredicate(p Predicate, fn func(Predicate) bool) {
|
||
|
|
if p == nil || !fn(p) {
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
switch p := p.(type) {
|
||
|
|
case AndPredicate:
|
||
|
|
walkPredicate(p.Left, fn)
|
||
|
|
walkPredicate(p.Right, fn)
|
||
|
|
|
||
|
|
case OrPredicate:
|
||
|
|
walkPredicate(p.Left, fn)
|
||
|
|
walkPredicate(p.Right, fn)
|
||
|
|
|
||
|
|
case NotPredicate:
|
||
|
|
walkPredicate(p.Inner, fn)
|
||
|
|
|
||
|
|
case TruePredicate: // No children.
|
||
|
|
case FalsePredicate: // No children.
|
||
|
|
case EqualPredicate: // No children.
|
||
|
|
case InPredicate: // No children.
|
||
|
|
case GreaterThanPredicate: // No children.
|
||
|
|
case LessThanPredicate: // No children.
|
||
|
|
case FuncPredicate: // No children.
|
||
|
|
|
||
|
|
default:
|
||
|
|
panic("streams.walkPredicate: unsupported predicate type")
|
||
|
|
}
|
||
|
|
|
||
|
|
fn(nil)
|
||
|
|
}
|
||
|
|
|
||
|
|
func WhereTimeRangeOverlapsWith(
|
||
|
|
colMinTimestamp *Column,
|
||
|
|
colMaxTimestamp *Column,
|
||
|
|
start scalar.Scalar,
|
||
|
|
end scalar.Scalar,
|
||
|
|
) Predicate {
|
||
|
|
return AndPredicate{
|
||
|
|
Left: OrPredicate{
|
||
|
|
Left: EqualPredicate{
|
||
|
|
Column: colMaxTimestamp,
|
||
|
|
Value: start,
|
||
|
|
},
|
||
|
|
Right: GreaterThanPredicate{
|
||
|
|
Column: colMaxTimestamp,
|
||
|
|
Value: start,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
Right: OrPredicate{
|
||
|
|
Left: EqualPredicate{
|
||
|
|
Column: colMinTimestamp,
|
||
|
|
Value: end,
|
||
|
|
},
|
||
|
|
Right: LessThanPredicate{
|
||
|
|
Column: colMinTimestamp,
|
||
|
|
Value: end,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
}
|
||
|
|
}
|