Skip to content

Commit 0f6379f

Browse files
authored
Unify Continuations (#45)
## Problem There were a lot of type aliases that looked identical, so I removed them for this: ```rust pub type Continuation<Input> = Arc<dyn Fn(Input) -> UnitFuture + Send + Sync + 'static>; ``` ## Summary of changes Removed all of the `???Continuation` type aliases I also lifted the `Generator` trait into the same module as `engine`
1 parent 6497e62 commit 0f6379f

File tree

12 files changed

+71
-83
lines changed

12 files changed

+71
-83
lines changed

optd-core/src/engine/eval/core.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use super::{
33
Engine, Evaluate, Generator,
44
};
55
use crate::capture;
6-
use crate::engine::generator::Continuation;
76
use crate::engine::utils::evaluate_sequence;
7+
use crate::engine::Continuation;
88
use optd_dsl::analyzer::hir::{CoreData, Expr, Value};
99
use std::sync::Arc;
1010
use CoreData::*;
@@ -22,7 +22,7 @@ use CoreData::*;
2222
pub(super) async fn evaluate_core_expr<G>(
2323
data: CoreData<Arc<Expr>>,
2424
engine: Engine<G>,
25-
k: Continuation,
25+
k: Continuation<Value>,
2626
) where
2727
G: Generator,
2828
{
@@ -75,7 +75,7 @@ async fn evaluate_collection<G, F>(
7575
items: Vec<Arc<Expr>>,
7676
constructor: F,
7777
engine: Engine<G>,
78-
k: Continuation,
78+
k: Continuation<Value>,
7979
) where
8080
G: Generator,
8181
F: FnOnce(Vec<Value>) -> CoreData<Value> + Clone + Send + Sync + 'static,
@@ -100,8 +100,11 @@ async fn evaluate_collection<G, F>(
100100
/// * `items` - The key-value pairs to evaluate.
101101
/// * `engine` - The evaluation engine.
102102
/// * `k` - The continuation to receive evaluation results.
103-
async fn evaluate_map<G>(items: Vec<(Arc<Expr>, Arc<Expr>)>, engine: Engine<G>, k: Continuation)
104-
where
103+
async fn evaluate_map<G>(
104+
items: Vec<(Arc<Expr>, Arc<Expr>)>,
105+
engine: Engine<G>,
106+
k: Continuation<Value>,
107+
) where
105108
G: Generator,
106109
{
107110
// Extract keys and values.
@@ -139,7 +142,7 @@ where
139142
/// * `msg` - The message expression to evaluate
140143
/// * `engine` - The evaluation engine
141144
/// * `k` - The continuation to receive evaluation results
142-
async fn evaluate_fail<G>(msg: Arc<Expr>, engine: Engine<G>, k: Continuation)
145+
async fn evaluate_fail<G>(msg: Arc<Expr>, engine: Engine<G>, k: Continuation<Value>)
143146
where
144147
G: Generator,
145148
{

optd-core/src/engine/eval/expr.rs

+10-14
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
use super::{binary::eval_binary_op, unary::eval_unary_op, Evaluate};
22
use crate::{
33
capture,
4-
engine::{
5-
generator::{Continuation, Generator},
6-
utils::evaluate_sequence,
7-
Engine,
8-
},
4+
engine::{utils::evaluate_sequence, Continuation, Engine, Generator},
95
};
106
use optd_dsl::analyzer::hir::{
117
BinOp, CoreData, Expr, FunKind, Identifier, Literal, UnaryOp, Value,
@@ -31,7 +27,7 @@ pub(super) async fn evaluate_if_then_else<G>(
3127
then_expr: Arc<Expr>,
3228
else_expr: Arc<Expr>,
3329
engine: Engine<G>,
34-
k: Continuation,
30+
k: Continuation<Value>,
3531
) where
3632
G: Generator,
3733
{
@@ -73,7 +69,7 @@ pub(super) async fn evaluate_let_binding<G>(
7369
assignee: Arc<Expr>,
7470
after: Arc<Expr>,
7571
engine: Engine<G>,
76-
k: Continuation,
72+
k: Continuation<Value>,
7773
) where
7874
G: Generator,
7975
{
@@ -111,7 +107,7 @@ pub(super) async fn evaluate_binary_expr<G>(
111107
op: BinOp,
112108
right: Arc<Expr>,
113109
engine: Engine<G>,
114-
k: Continuation,
110+
k: Continuation<Value>,
115111
) where
116112
G: Generator,
117113
{
@@ -121,7 +117,7 @@ pub(super) async fn evaluate_binary_expr<G>(
121117
right: Arc<Expr>,
122118
op: BinOp,
123119
engine: Engine<G>,
124-
k: Continuation,
120+
k: Continuation<Value>,
125121
) where
126122
G: Generator,
127123
{
@@ -165,7 +161,7 @@ pub(super) async fn evaluate_unary_expr<G>(
165161
op: UnaryOp,
166162
expr: Arc<Expr>,
167163
engine: Engine<G>,
168-
k: Continuation,
164+
k: Continuation<Value>,
169165
) where
170166
G: Generator,
171167
{
@@ -198,7 +194,7 @@ pub(super) async fn evaluate_function_call<G>(
198194
fun: Arc<Expr>,
199195
args: Vec<Arc<Expr>>,
200196
engine: Engine<G>,
201-
k: Continuation,
197+
k: Continuation<Value>,
202198
) where
203199
G: Generator,
204200
{
@@ -242,7 +238,7 @@ pub(super) async fn evaluate_closure_call<G>(
242238
body: Arc<Expr>,
243239
args: Vec<Arc<Expr>>,
244240
engine: Engine<G>,
245-
k: Continuation,
241+
k: Continuation<Value>,
246242
) where
247243
G: Generator,
248244
{
@@ -282,7 +278,7 @@ pub(super) async fn evaluate_rust_udf_call<G>(
282278
udf: fn(Vec<Value>) -> Value,
283279
args: Vec<Arc<Expr>>,
284280
engine: Engine<G>,
285-
k: Continuation,
281+
k: Continuation<Value>,
286282
) where
287283
G: Generator,
288284
{
@@ -311,7 +307,7 @@ pub(super) async fn evaluate_rust_udf_call<G>(
311307
/// * `ident` - The identifier to look up
312308
/// * `engine` - The evaluation engine
313309
/// * `k` - The continuation to receive the variable value
314-
pub(super) async fn evaluate_reference<G>(ident: String, engine: Engine<G>, k: Continuation)
310+
pub(super) async fn evaluate_reference<G>(ident: String, engine: Engine<G>, k: Continuation<Value>)
315311
where
316312
G: Generator,
317313
{

optd-core/src/engine/eval/match.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use super::{Engine, Evaluate, Generator};
2-
use crate::engine::generator::Continuation;
3-
use crate::{capture, engine::UnitFuture};
2+
use crate::{
3+
capture,
4+
engine::{Continuation, UnitFuture},
5+
};
46
use optd_dsl::analyzer::{
57
context::Context,
68
hir::{
@@ -39,7 +41,7 @@ pub(super) async fn evaluate_pattern_match<G>(
3941
expr: Arc<Expr>,
4042
match_arms: Vec<MatchArm>,
4143
engine: Engine<G>,
42-
k: Continuation,
44+
k: Continuation<Value>,
4345
) where
4446
G: Generator,
4547
{
@@ -74,7 +76,7 @@ fn try_match_arms<G>(
7476
value: Value,
7577
match_arms: Vec<MatchArm>,
7678
engine: Engine<G>,
77-
k: Continuation,
79+
k: Continuation<Value>,
7880
) -> UnitFuture
7981
where
8082
G: Generator,

optd-core/src/engine/eval/mod.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
use super::generator::{Continuation, Generator};
2-
use super::{Engine, UnitFuture};
1+
use super::{Continuation, Engine, Generator, UnitFuture};
32
use core::evaluate_core_expr;
43
use expr::{
54
evaluate_binary_expr, evaluate_function_call, evaluate_if_then_else, evaluate_let_binding,
65
evaluate_reference, evaluate_unary_expr,
76
};
8-
use optd_dsl::analyzer::hir::Expr;
7+
use optd_dsl::analyzer::hir::{Expr, Value};
98
use r#match::evaluate_pattern_match;
109
use std::sync::Arc;
1110
use Expr::*;
@@ -26,13 +25,13 @@ pub trait Evaluate {
2625
/// * `self` - The expression to evaluate
2726
/// * `engine` - The evaluation engine (owned)
2827
/// * `k` - The continuation to receive each evaluation result
29-
fn evaluate<G>(self, engine: Engine<G>, k: Continuation) -> UnitFuture
28+
fn evaluate<G>(self, engine: Engine<G>, k: Continuation<Value>) -> UnitFuture
3029
where
3130
G: Generator;
3231
}
3332

3433
impl Evaluate for Arc<Expr> {
35-
fn evaluate<G>(self, engine: Engine<G>, k: Continuation) -> UnitFuture
34+
fn evaluate<G>(self, engine: Engine<G>, k: Continuation<Value>) -> UnitFuture
3635
where
3736
G: Generator,
3837
{

optd-core/src/engine/eval/operator.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::{Engine, Generator};
2-
use crate::engine::generator::Continuation;
2+
use crate::capture;
33
use crate::engine::utils::evaluate_sequence;
4-
use crate::{capture, engine::utils::UnitFuture};
4+
use crate::engine::Continuation;
55
use optd_dsl::analyzer::hir::{
66
CoreData, Expr, LogicalOp, Materializable, Operator, PhysicalOp, Value,
77
};
@@ -10,7 +10,7 @@ use CoreData::{Logical, Physical};
1010
use Materializable::*;
1111

1212
/// Specialized continuation type for operator values
13-
type OperatorContinuation = Arc<dyn Fn(Operator<Value>) -> UnitFuture + Send + Sync + 'static>;
13+
type OperatorContinuation = Continuation<Operator<Value>>;
1414

1515
/// Evaluates a logical operator by generating all possible combinations of its components.
1616
///
@@ -22,7 +22,7 @@ type OperatorContinuation = Arc<dyn Fn(Operator<Value>) -> UnitFuture + Send + S
2222
pub(super) async fn evaluate_logical_operator<G>(
2323
op: LogicalOp<Arc<Expr>>,
2424
engine: Engine<G>,
25-
k: Continuation,
25+
k: Continuation<Value>,
2626
) where
2727
G: Generator,
2828
{
@@ -62,7 +62,7 @@ pub(super) async fn evaluate_logical_operator<G>(
6262
pub(super) async fn evaluate_physical_operator<G>(
6363
op: PhysicalOp<Arc<Expr>>,
6464
engine: Engine<G>,
65-
k: Continuation,
65+
k: Continuation<Value>,
6666
) where
6767
G: Generator,
6868
{

optd-core/src/engine/generator.rs

+3-8
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
1+
use super::Continuation;
12
use optd_dsl::analyzer::hir::{Goal, GroupId, Value};
2-
use std::sync::Arc;
3-
4-
use super::utils::UnitFuture;
5-
6-
/// A continuation function that processes a Value and returns a Future.
7-
pub type Continuation = Arc<dyn Fn(Value) -> UnitFuture + Send + Sync + 'static>;
83

94
/// Defines operations for expanding references in the query plan using CPS.
105
///
@@ -21,7 +16,7 @@ pub trait Generator: Clone + Send + Sync + 'static {
2116
/// # Parameters
2217
/// * `group_id` - The ID of the group to expand
2318
/// * `k` - The continuation to process each expression in the group
24-
async fn yield_group(&self, group_id: GroupId, k: Continuation);
19+
async fn yield_group(&self, group_id: GroupId, k: Continuation<Value>);
2520

2621
/// Expands a physical goal and passes each implementation to the continuation.
2722
///
@@ -31,5 +26,5 @@ pub trait Generator: Clone + Send + Sync + 'static {
3126
/// # Parameters
3227
/// * `physical_goal` - The goal describing required properties
3328
/// * `k` - The continuation to process each implementation
34-
async fn yield_goal(&self, physical_goal: &Goal, k: Continuation);
29+
async fn yield_goal(&self, physical_goal: &Goal, k: Continuation<Value>);
3530
}

optd-core/src/engine/mod.rs

+17-21
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ use crate::{
1111
capture,
1212
cir::{Cost, LogicalProperties, PartialLogicalPlan, PartialPhysicalPlan, PhysicalProperties},
1313
};
14-
use eval::Evaluate;
15-
use generator::Generator;
14+
1615
use optd_dsl::analyzer::{
1716
context::Context,
1817
hir::{CoreData, Expr, Literal, Value},
@@ -22,25 +21,22 @@ use utils::UnitFuture;
2221
use Expr::*;
2322

2423
mod eval;
25-
pub(crate) mod generator;
26-
#[cfg(test)]
27-
pub(super) mod test_utils;
28-
pub(crate) mod utils;
24+
use eval::Evaluate;
2925

30-
/// Type alias for a continuation that receives a PartialLogicalPlan
31-
pub(crate) type LogicalPlanContinuation =
32-
Arc<dyn Fn(PartialLogicalPlan) -> UnitFuture + Send + Sync + 'static>;
26+
mod generator;
27+
pub use generator::Generator;
3328

34-
/// Type alias for a continuation that receives a PartialPhysicalPlan
35-
pub(crate) type PhysicalPlanContinuation =
36-
Arc<dyn Fn(PartialPhysicalPlan) -> UnitFuture + Send + Sync + 'static>;
29+
pub(crate) mod utils;
3730

38-
/// Type alias for a continuation that receives a cost value
39-
pub(crate) type CostContinuation = Arc<dyn Fn(Cost) -> UnitFuture + Send + Sync + 'static>;
31+
#[cfg(test)]
32+
pub(super) mod test_utils;
4033

41-
/// Type alias for a continuation that receives LogicalProperties
42-
pub(crate) type PropertiesContinuation =
43-
Arc<dyn Fn(LogicalProperties) -> UnitFuture + Send + Sync + 'static>;
34+
/// A type alias for continuations used in the rule engine.
35+
///
36+
/// The engine uses continuation-passing-style (CPS) since it requires advanced control flow to
37+
/// expand and iterate over expressions within groups (where each expression requires
38+
/// plan-dependent state).
39+
pub type Continuation<Input> = Arc<dyn Fn(Input) -> UnitFuture + Send + Sync + 'static>;
4440

4541
/// The engine for evaluating HIR expressions and applying rules.
4642
#[derive(Debug, Clone)]
@@ -87,7 +83,7 @@ impl<G: Generator> Engine<G> {
8783
self,
8884
rule_name: String,
8985
plan: &PartialLogicalPlan,
90-
k: LogicalPlanContinuation,
86+
k: Continuation<PartialLogicalPlan>,
9187
) -> UnitFuture {
9288
let rule_call = self.create_rule_call(&rule_name, vec![partial_logical_to_value(plan)]);
9389

@@ -126,7 +122,7 @@ impl<G: Generator> Engine<G> {
126122
rule_name: String,
127123
plan: &PartialLogicalPlan,
128124
props: &PhysicalProperties,
129-
k: PhysicalPlanContinuation,
125+
k: Continuation<PartialPhysicalPlan>,
130126
) -> UnitFuture {
131127
let plan_value = partial_logical_to_value(plan);
132128
let props_value = physical_properties_to_value(props);
@@ -164,7 +160,7 @@ impl<G: Generator> Engine<G> {
164160
pub(crate) fn launch_cost_plan(
165161
self,
166162
plan: &PartialPhysicalPlan,
167-
k: CostContinuation,
163+
k: Continuation<Cost>,
168164
) -> UnitFuture {
169165
// Create a call to the reserved "cost" function
170166
let rule_call = self.create_rule_call("cost", vec![partial_physical_to_value(plan)]);
@@ -194,7 +190,7 @@ impl<G: Generator> Engine<G> {
194190
pub(crate) fn launch_derive_properties(
195191
self,
196192
plan: &PartialLogicalPlan,
197-
k: PropertiesContinuation,
193+
k: Continuation<LogicalProperties>,
198194
) -> UnitFuture {
199195
// Create a call to the reserved "derive" function
200196
let rule_call = self.create_rule_call("derive", vec![partial_logical_to_value(plan)]);

optd-core/src/engine/test_utils.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
use crate::engine::{
2-
generator::{Continuation, Generator},
3-
Engine, Evaluate,
4-
};
1+
use crate::engine::{generator::Generator, Continuation, Engine, Evaluate};
52
use optd_dsl::analyzer::hir::{
63
CoreData, Expr, Goal, GroupId, Literal, LogicalOp, MatchArm, Materializable, Operator, Pattern,
74
PhysicalOp, Value,
@@ -44,7 +41,7 @@ impl MockGenerator {
4441
}
4542

4643
impl Generator for MockGenerator {
47-
async fn yield_group(&self, group_id: GroupId, k: Continuation) {
44+
async fn yield_group(&self, group_id: GroupId, k: Continuation<Value>) {
4845
let key = format!("{:?}", group_id);
4946
let values = {
5047
let mappings = self.group_mappings.lock().unwrap();
@@ -56,7 +53,7 @@ impl Generator for MockGenerator {
5653
}
5754
}
5855

59-
async fn yield_goal(&self, physical_goal: &Goal, k: Continuation) {
56+
async fn yield_goal(&self, physical_goal: &Goal, k: Continuation<Value>) {
6057
let key = format!(
6158
"{:?}:{:?}",
6259
physical_goal.group_id, physical_goal.properties

0 commit comments

Comments
 (0)