Skip to main content

graphrecords_query/operations/numeric/
exponential.rs

1use super::{numeric_bare, numeric_indexed};
2use crate::{
3    Bare, BareValueDomain, Explain, IndexDomain, Indexed, Labeled, Operand, QueryResult,
4    capabilities::ValueExponential,
5    element::Preserving,
6    execution::EvaluationCache,
7    operations::{Apply, ElementKernel, ElementPipeline, Operation, OperationContext, Prepare},
8    optimizer::{Estimate, OperationInputs, OptimizerHints, PlanIdentity, PlanInputs, Stats},
9    registry::operation_manifest,
10    traits::Exponential,
11};
12use graphrecords_core::GraphRecord;
13
14#[derive(Clone, Explain, Operation, OperationInputs, OptimizerHints, PlanIdentity, PlanInputs)]
15#[operation(scope = Element)]
16#[explain(label = "Exponential")]
17#[plan(optimizer_hints(allows_limit_pushdown, empty = if_any))]
18pub struct ExponentialOperation;
19
20impl Prepare for ExponentialOperation {
21    type Prepared<'a> = ();
22
23    fn prepare<'a>(
24        &'a self,
25        _graphrecord: &'a GraphRecord,
26        _cache: &'a EvaluationCache<'a>,
27    ) -> QueryResult<Self::Prepared<'a>> {
28        Ok(())
29    }
30}
31
32impl<I, V> ElementKernel<Indexed<I, V>> for ExponentialOperation
33where
34    I: IndexDomain,
35    V: ValueExponential,
36{
37    type Emission = Preserving;
38    type OutShape = Indexed<I, V>;
39
40    fn pipeline<'a>(
41        _graphrecord: &'a GraphRecord,
42        _prepared: Self::Prepared<'a>,
43    ) -> QueryResult<ElementPipeline<'a, Indexed<I, V>, Self>> {
44        Ok(numeric_indexed::<I, V, _>(Self::LABEL, V::exponential))
45    }
46
47    fn estimate(&self, input: Estimate, _stats: &Stats) -> Estimate {
48        input.with_unknown_distinct()
49    }
50}
51
52impl<V> ElementKernel<Bare<V>> for ExponentialOperation
53where
54    V: ValueExponential + BareValueDomain,
55{
56    type Emission = Preserving;
57    type OutShape = Bare<V>;
58
59    fn pipeline<'a>(
60        _graphrecord: &'a GraphRecord,
61        _prepared: Self::Prepared<'a>,
62    ) -> QueryResult<ElementPipeline<'a, Bare<V>, Self>> {
63        Ok(numeric_bare::<V, _>(Self::LABEL, V::exponential))
64    }
65
66    fn estimate(&self, input: Estimate, _stats: &Stats) -> Estimate {
67        input.with_unknown_distinct()
68    }
69}
70
71impl<O: Apply<ExponentialOperation>> Exponential for O {
72    type ReturnOperand = O::Output;
73
74    fn exp(&self) -> Self::ReturnOperand {
75        Self::ReturnOperand::new(OperationContext::new(self.clone(), ExponentialOperation))
76    }
77}
78
79operation_manifest! {
80    ExponentialOperation {
81        method: Exponential::exp;
82        scope: element;
83
84        kernel {
85            parameters: <I: IndexDomain, V: ValueExponential>;
86            input: Indexed<I, V>;
87            output: Indexed<I, V>;
88            emission: Preserving;
89        }
90
91        kernel {
92            parameters: <V: ValueExponential + BareValueDomain>;
93            input: Bare<V>;
94            output: Bare<V>;
95            emission: Preserving;
96        }
97    }
98}