Skip to main content

graphrecords_query/operands/
mod.rs

1mod attributes;
2mod bool;
3mod context;
4mod edges;
5mod elements;
6mod errors;
7mod group;
8mod indices;
9mod nodes;
10mod references;
11mod values;
12
13use crate::{
14    BoxedIterator, Failure, IndexDomain, QueryResult,
15    element::{Arity, ElementShape, Return},
16    error::index::DuplicateIndex,
17    execution::EvaluationCache,
18    explain::Explanation,
19    optimizer::{Estimate, Estimated, PlanNode, Stats},
20    value::ValueDomain,
21};
22pub use attributes::{
23    AttributeOperand, AttributesOperand, BareAttributeOperand, BareAttributesOperand,
24    DefiniteAttributeOperand, DefiniteBareAttributeOperand,
25};
26pub use bool::{
27    BareBoolMaskOperand, BareBoolOperand, BoolMaskOperand, BoolOperand, DefiniteBareBoolOperand,
28    DefiniteBoolOperand,
29};
30pub use context::{EvaluateContext, OperandContext};
31pub use edges::{AllEdges, DefiniteEdgeOperand, EdgeOperand, EdgesOperand};
32pub use elements::{DefiniteElementOperand, ElementOperand, ElementsOperand};
33pub use errors::{
34    BareFailureKindOperand, BareFailureKindsOperand, BareFailureOperand, BareFailuresOperand,
35    DefiniteBareFailureKindOperand, DefiniteBareFailureOperand, DefiniteFailureKindOperand,
36    DefiniteFailureOperand, FailureKindOperand, FailureKindsOperand, FailureOperand,
37    FailuresOperand,
38};
39use graphrecords_core::GraphRecord;
40use graphrecords_utils::aliases::GrHashSet;
41pub use group::{
42    Bucket, BucketChange, BucketOwned, GroupOperand, KeyFailure, KeyFailureChange, KeyFailureOwned,
43    Partition, PartitionArity, PartitionBucketParts, PartitionBuilder, PartitionClassification,
44    PartitionKeyFailureParts, PartitionOwned, PartitionOwnedParts, PartitionParts, PartitionShape,
45    ReturnBucket, ReturnKeyFailure, ReturnPartition, ReturnPartitionParts,
46};
47pub use indices::{
48    BareIndexOperand, BareIndicesOperand, DefiniteBareIndexOperand, DefiniteIndexOperand,
49    IndexOperand, IndicesOperand,
50};
51pub use nodes::{AllNodes, DefiniteNodeOperand, NodeOperand, NodesOperand};
52pub use references::{
53    BareReferenceOperand, BareReferencesOperand, DefiniteBareReferenceOperand,
54    DefiniteReferenceIndexOperand, DefiniteReferenceOperand, ReferenceIndexOperand,
55    ReferenceIndicesOperand, ReferenceOperand, ReferencesOperand,
56};
57use std::sync::Arc;
58pub use values::{
59    BareValueOperand, BareValuesOperand, DefiniteBareValueOperand, DefiniteValueOperand,
60    ValueOperand, ValuesOperand,
61};
62
63pub trait EvaluateOperand {
64    type ReturnValue<'a>: 'a
65    where
66        Self: 'a;
67
68    fn evaluate<'a>(
69        &'a self,
70        graphrecord: &'a GraphRecord,
71        cache: &'a EvaluationCache<'a>,
72    ) -> QueryResult<Self::ReturnValue<'a>>;
73}
74
75pub trait Operand: 'static + Sized + Clone + EvaluateOperand + Send + Sync {
76    fn context(&self) -> &dyn OperandContext<Self>;
77
78    fn as_plan_node(&self) -> &dyn PlanNode;
79
80    fn from_context(context: Arc<dyn OperandContext<Self>>) -> Self;
81
82    #[must_use]
83    fn new<C: OperandContext<Self>>(context: C) -> Self {
84        Self::from_context(Arc::new(context))
85    }
86
87    fn explain(&self) -> Explanation<'_> {
88        Explanation::new(self)
89    }
90}
91
92pub struct OperandHandle<S: ElementShape, C: Arity> {
93    context: Arc<dyn OperandContext<Self>>,
94}
95
96impl<S: ElementShape, C: Arity> Clone for OperandHandle<S, C> {
97    fn clone(&self) -> Self {
98        Self {
99            context: Arc::clone(&self.context),
100        }
101    }
102}
103
104impl<S: ElementShape, C: Arity> EvaluateOperand for OperandHandle<S, C> {
105    type ReturnValue<'a> = Return<'a, S, C>;
106
107    fn evaluate<'a>(
108        &'a self,
109        graphrecord: &'a GraphRecord,
110        cache: &'a EvaluationCache<'a>,
111    ) -> QueryResult<Self::ReturnValue<'a>> {
112        self.context.evaluate(graphrecord, cache)
113    }
114}
115
116impl<S: ElementShape, C: Arity> Estimated for OperandHandle<S, C> {
117    fn estimate(&self, stats: &Stats) -> Estimate {
118        self.context().estimate(stats)
119    }
120}
121
122impl<S: ElementShape, C: Arity> Operand for OperandHandle<S, C> {
123    fn context(&self) -> &dyn OperandContext<Self> {
124        self.context.as_ref()
125    }
126
127    fn as_plan_node(&self) -> &dyn PlanNode {
128        self.context.as_ref()
129    }
130
131    fn from_context(context: Arc<dyn OperandContext<Self>>) -> Self {
132        Self { context }
133    }
134}
135
136pub struct CheckedIndexedLaneBuilder<'a, I: IndexDomain, V: ValueDomain> {
137    seen: GrHashSet<I::Owned>,
138    elements: Vec<(I::Index<'a>, QueryResult<V::Value<'a>>)>,
139}
140
141impl<'a, I: IndexDomain, V: ValueDomain> CheckedIndexedLaneBuilder<'a, I, V> {
142    #[must_use]
143    pub fn new() -> Self {
144        Self {
145            seen: GrHashSet::default(),
146            elements: Vec::new(),
147        }
148    }
149
150    pub fn push(
151        &mut self,
152        index: I::Index<'a>,
153        outcome: QueryResult<V::Value<'a>>,
154    ) -> QueryResult<()> {
155        if !self.seen.insert(I::to_owned(&index)) {
156            return Err(Failure::new_at::<I, _>(
157                "indexed lane construction",
158                DuplicateIndex::<I>::new(I::to_owned(&index)),
159                &index,
160            ));
161        }
162
163        self.elements.push((index, outcome));
164
165        Ok(())
166    }
167
168    #[must_use]
169    pub fn finish(self) -> BoxedIterator<'a, (I::Index<'a>, QueryResult<V::Value<'a>>)> {
170        Box::new(self.elements.into_iter())
171    }
172}
173
174impl<I: IndexDomain, V: ValueDomain> Default for CheckedIndexedLaneBuilder<'_, I, V> {
175    fn default() -> Self {
176        Self::new()
177    }
178}