solverforge_scoring/stream/joiner/
plan.rs1use super::match_condition::AndJoiner;
11use super::{EqualJoiner, FilteringJoiner};
12use super::{GreaterThanJoiner, GreaterThanOrEqualJoiner, LessThanJoiner, LessThanOrEqualJoiner};
13use super::{Joiner, OverlappingJoiner};
14mod composite;
15mod conjunction;
16pub use composite::{
17 ComposePlans, CompositeEquality, EqualityKeys, EqualityKind, EqualityPlan, ResidualKind,
18};
19mod executable;
20mod hash_scan;
21mod mixed_equality;
22pub use mixed_equality::EqualityWithResidual;
23mod ordered_interval;
24pub use executable::{CompileCondition, ExecutablePlan, IndexedPlan};
25
26#[derive(Clone, Copy, Debug, PartialEq, Eq)]
28pub enum Strategy {
29 EquiHash,
31 OrderedScan,
33 IntervalNarrow,
35 Scan,
37}
38
39impl Strategy {
40 #[inline]
43 pub const fn combine(self, other: Strategy) -> Strategy {
44 match (self, other) {
45 (Strategy::EquiHash, _) | (_, Strategy::EquiHash) => Strategy::EquiHash,
46 (Strategy::OrderedScan, _) | (_, Strategy::OrderedScan) => Strategy::OrderedScan,
47 (Strategy::IntervalNarrow, _) | (_, Strategy::IntervalNarrow) => {
48 Strategy::IntervalNarrow
49 }
50 (Strategy::Scan, Strategy::Scan) => Strategy::Scan,
51 }
52 }
53}
54
55pub trait PlannedCondition<Row, C>: Send + Sync {
62 const STRATEGY: Strategy;
64
65 fn check(&self, row: &Row, c: &C) -> bool;
67}
68
69#[inline]
71pub fn plan_strategy<Row, C, P>(condition: &P) -> Strategy
72where
73 P: PlannedCondition<Row, C>,
74{
75 let _ = condition;
76 P::STRATEGY
77}
78
79impl<Row, C, Fa, Fb, T, Mode> PlannedCondition<Row, C> for EqualJoiner<Fa, Fb, T, Mode>
80where
81 T: PartialEq,
82 Fa: Fn(&Row) -> T + Send + Sync,
83 Fb: Fn(&C) -> T + Send + Sync,
84{
85 const STRATEGY: Strategy = Strategy::EquiHash;
86
87 #[inline]
88 fn check(&self, row: &Row, c: &C) -> bool {
89 self.matches(row, c)
90 }
91}
92
93impl<Row, C, Fa, Fb, T> PlannedCondition<Row, C> for LessThanJoiner<Fa, Fb, T>
94where
95 T: Ord,
96 Fa: Fn(&Row) -> T + Send + Sync,
97 Fb: Fn(&C) -> T + Send + Sync,
98{
99 const STRATEGY: Strategy = Strategy::OrderedScan;
100
101 #[inline]
102 fn check(&self, row: &Row, c: &C) -> bool {
103 self.matches(row, c)
104 }
105}
106
107impl<Row, C, Fa, Fb, T> PlannedCondition<Row, C> for LessThanOrEqualJoiner<Fa, Fb, T>
108where
109 T: Ord,
110 Fa: Fn(&Row) -> T + Send + Sync,
111 Fb: Fn(&C) -> T + Send + Sync,
112{
113 const STRATEGY: Strategy = Strategy::OrderedScan;
114
115 #[inline]
116 fn check(&self, row: &Row, c: &C) -> bool {
117 self.matches(row, c)
118 }
119}
120
121impl<Row, C, Fa, Fb, T> PlannedCondition<Row, C> for GreaterThanJoiner<Fa, Fb, T>
122where
123 T: Ord,
124 Fa: Fn(&Row) -> T + Send + Sync,
125 Fb: Fn(&C) -> T + Send + Sync,
126{
127 const STRATEGY: Strategy = Strategy::OrderedScan;
128
129 #[inline]
130 fn check(&self, row: &Row, c: &C) -> bool {
131 self.matches(row, c)
132 }
133}
134
135impl<Row, C, Fa, Fb, T> PlannedCondition<Row, C> for GreaterThanOrEqualJoiner<Fa, Fb, T>
136where
137 T: Ord,
138 Fa: Fn(&Row) -> T + Send + Sync,
139 Fb: Fn(&C) -> T + Send + Sync,
140{
141 const STRATEGY: Strategy = Strategy::OrderedScan;
142
143 #[inline]
144 fn check(&self, row: &Row, c: &C) -> bool {
145 self.matches(row, c)
146 }
147}
148
149impl<Row, C, Fsa, Fea, Fsb, Feb, T> PlannedCondition<Row, C>
150 for OverlappingJoiner<Fsa, Fea, Fsb, Feb, T>
151where
152 T: Ord,
153 Fsa: Fn(&Row) -> T + Send + Sync,
154 Fea: Fn(&Row) -> T + Send + Sync,
155 Fsb: Fn(&C) -> T + Send + Sync,
156 Feb: Fn(&C) -> T + Send + Sync,
157{
158 const STRATEGY: Strategy = Strategy::IntervalNarrow;
159
160 #[inline]
161 fn check(&self, row: &Row, c: &C) -> bool {
162 self.matches(row, c)
163 }
164}
165
166impl<Row, C, F> PlannedCondition<Row, C> for FilteringJoiner<F>
167where
168 F: Fn(&Row, &C) -> bool + Send + Sync,
169{
170 const STRATEGY: Strategy = Strategy::Scan;
171
172 #[inline]
173 fn check(&self, row: &Row, c: &C) -> bool {
174 self.matches(row, c)
175 }
176}
177
178impl<Row, C, J1, J2> PlannedCondition<Row, C> for AndJoiner<J1, J2>
179where
180 J1: PlannedCondition<Row, C> + Joiner<Row, C>,
181 J2: PlannedCondition<Row, C> + Joiner<Row, C>,
182{
183 const STRATEGY: Strategy = J1::STRATEGY.combine(J2::STRATEGY);
184
185 #[inline]
186 fn check(&self, row: &Row, c: &C) -> bool {
187 self.matches(row, c)
188 }
189}