graphrecords_query/operations/ordering/
first.rs1use crate::{
2 Bare, BareValueDomain, EvaluateOperand, Explain, IndexDomain, Indexed, Multiple, Operand,
3 Ordered, QueryResult, Single, ValueDomain,
4 execution::EvaluationCache,
5 operands::OperandHandle,
6 operations::{
7 Apply, BareStream, KeyedStream, LaneKernel, Operation, OperationContext, Prepare,
8 },
9 optimizer::{Estimate, OperationInputs, OptimizerHints, PlanIdentity, PlanInputs, Stats},
10 registry::operation_manifest,
11 traits::First,
12};
13use graphrecords_core::GraphRecord;
14
15#[derive(Clone, Explain, Operation, OperationInputs, OptimizerHints, PlanIdentity, PlanInputs)]
16#[operation(scope = Lane)]
17#[explain(label = "First")]
18#[plan(optimizer_hints(empty = if_any))]
19pub struct FirstOperation;
20
21impl Prepare for FirstOperation {
22 type Prepared<'a> = ();
23
24 fn prepare<'a>(
25 &'a self,
26 _graphrecord: &'a GraphRecord,
27 _cache: &'a EvaluationCache<'a>,
28 ) -> QueryResult<Self::Prepared<'a>> {
29 Ok(())
30 }
31}
32
33impl<I: IndexDomain, V: ValueDomain> LaneKernel<Indexed<I, V>, Multiple<Ordered>>
34 for FirstOperation
35{
36 type Output = OperandHandle<Indexed<I, V>, Single>;
37
38 fn execute<'a>(
39 _graphrecord: &'a GraphRecord,
40 mut values: KeyedStream<'a, I, V, Multiple<Ordered>>,
41 _prepared: Self::Prepared<'a>,
42 ) -> QueryResult<<Self::Output as EvaluateOperand>::ReturnValue<'a>> {
43 Ok(values.next())
44 }
45
46 fn estimate(&self, input: Estimate, _stats: &Stats) -> Estimate {
47 input.zero_or_one()
48 }
49}
50
51impl<V: BareValueDomain> LaneKernel<Bare<V>, Multiple<Ordered>> for FirstOperation {
52 type Output = OperandHandle<Bare<V>, Single>;
53
54 fn execute<'a>(
55 _graphrecord: &'a GraphRecord,
56 mut values: BareStream<'a, V, Multiple<Ordered>>,
57 _prepared: Self::Prepared<'a>,
58 ) -> QueryResult<<Self::Output as EvaluateOperand>::ReturnValue<'a>> {
59 Ok(values.next())
60 }
61
62 fn estimate(&self, input: Estimate, _stats: &Stats) -> Estimate {
63 input.zero_or_one()
64 }
65}
66
67impl<O: Apply<FirstOperation>> First for O {
68 type ReturnOperand = O::Output;
69
70 fn first(&self) -> Self::ReturnOperand {
71 Self::ReturnOperand::new(OperationContext::new(self.clone(), FirstOperation))
72 }
73}
74
75operation_manifest! {
76 FirstOperation {
77 method: First::first;
78 scope: lane;
79
80 kernel {
81 parameters: <I: IndexDomain, V: ValueDomain>;
82 input: (Indexed<I, V>, Multiple<Ordered>);
83 output: OperandHandle<Indexed<I, V>, Single>;
84 }
85 kernel {
86 parameters: <V: BareValueDomain>;
87 input: (Bare<V>, Multiple<Ordered>);
88 output: OperandHandle<Bare<V>, Single>;
89 }
90 }
91}