use std::sync::Arc;
use crate::builtins::BuiltinMethod;
use crate::parse::ast::Expr;
use crate::vm::Program;
use super::NumOp;
#[derive(Debug, Clone)]
pub struct ReducerSpec {
pub op: ReducerOp,
pub predicate: Option<Arc<Program>>,
pub projection: Option<Arc<Program>>,
pub predicate_expr: Option<Arc<Expr>>,
pub projection_expr: Option<Arc<Expr>>,
}
#[derive(Debug, Clone)]
pub struct PredicateSinkSpec {
pub op: PredicateSinkOp,
pub predicate: Arc<Program>,
}
#[derive(Debug, Clone)]
pub struct MembershipSinkSpec {
pub op: MembershipSinkOp,
pub target: MembershipSinkTarget,
pub method: BuiltinMethod,
}
#[derive(Debug, Clone)]
pub enum MembershipSinkTarget {
Literal(crate::data::value::Val),
Program(Arc<Program>),
}
#[derive(Debug, Clone)]
pub struct ArgExtremeSinkSpec {
pub want_max: bool,
pub key: Arc<Program>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PredicateSinkOp {
Any,
All,
FindIndex,
IndicesWhere,
FindOne,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MembershipSinkOp {
Includes,
Index,
IndicesOf,
}
impl PredicateSinkSpec {
pub(crate) fn sink_programs(&self) -> impl Iterator<Item = &Arc<Program>> {
std::iter::once(&self.predicate)
}
pub(crate) fn predicate_kernel_index(&self) -> usize {
0
}
}
impl MembershipSinkSpec {
pub(crate) fn sink_programs(&self) -> impl Iterator<Item = &Arc<Program>> {
match &self.target {
MembershipSinkTarget::Literal(_) => None,
MembershipSinkTarget::Program(program) => Some(program),
}
.into_iter()
}
}
impl ArgExtremeSinkSpec {
pub(crate) fn sink_programs(&self) -> impl Iterator<Item = &Arc<Program>> {
std::iter::once(&self.key)
}
pub(crate) fn key_kernel_index(&self) -> usize {
0
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ReducerOp {
Count,
Numeric(NumOp),
}
impl ReducerSpec {
pub fn count() -> Self {
Self {
op: ReducerOp::Count,
predicate: None,
projection: None,
predicate_expr: None,
projection_expr: None,
}
}
pub fn numeric_op(&self) -> Option<NumOp> {
match self.op {
ReducerOp::Numeric(op) => Some(op),
ReducerOp::Count => None,
}
}
pub(crate) fn sink_programs(&self) -> impl Iterator<Item = &Arc<Program>> {
self.predicate.iter().chain(self.projection.iter())
}
pub(crate) fn predicate_kernel_index(&self) -> Option<usize> {
self.predicate.as_ref().map(|_| 0)
}
pub(crate) fn projection_kernel_index(&self) -> Option<usize> {
self.projection
.as_ref()
.map(|_| usize::from(self.predicate.is_some()))
}
pub fn method(&self) -> Option<BuiltinMethod> {
match self.op {
ReducerOp::Count => Some(BuiltinMethod::Count),
ReducerOp::Numeric(op) => Some(op.method()),
}
}
}