Skip to content

Commit c6d3ee1

Browse files
committed
move things into memo submodule
1 parent da48cdf commit c6d3ee1

File tree

6 files changed

+178
-161
lines changed

6 files changed

+178
-161
lines changed

optd-persistent/src/expression.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::entities::*;
12
use std::hash::{DefaultHasher, Hash, Hasher};
23

34
/// All of the different types of fixed logical operators.
@@ -39,7 +40,7 @@ fn fingerprint(variant_tag: i16, data: &serde_json::Value) -> i64 {
3940
hasher.finish() as i64
4041
}
4142

42-
impl super::logical_expression::Model {
43+
impl logical_expression::Model {
4344
/// Creates a new logical expression with an unset `id` and `group_id`.
4445
pub fn new(variant_tag: LogicalOperator, data: serde_json::Value) -> Self {
4546
let tag = variant_tag as i16;
@@ -55,7 +56,7 @@ impl super::logical_expression::Model {
5556
}
5657
}
5758

58-
impl super::physical_expression::Model {
59+
impl physical_expression::Model {
5960
/// Creates a new physical expression with an unset `id` and `group_id`.
6061
pub fn new(variant_tag: PhysicalOperator, data: serde_json::Value) -> Self {
6162
let tag = variant_tag as i16;

optd-persistent/src/lib.rs

Lines changed: 2 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -5,171 +5,16 @@ mod migrator;
55
use migrator::Migrator;
66

77
mod entities;
8-
use entities::{prelude::*, *};
98

109
mod expression;
1110

1211
mod memo;
13-
pub use memo::MemoTable;
12+
pub use memo::interface::Memo;
13+
pub use memo::orm::MemoTable;
1414

1515
pub const DATABASE_URL: &str = "sqlite:./sqlite.db?mode=rwc";
1616
pub const DATABASE_FILE: &str = "./sqlite.db";
1717

1818
pub async fn migrate(db: &DatabaseConnection) -> std::result::Result<(), DbErr> {
1919
Migrator::refresh(db).await
2020
}
21-
22-
/// The different kinds of errors that might occur while running operations on a memo table.
23-
pub enum MemoError {
24-
UnknownGroup,
25-
UnknownLogicalExpression,
26-
UnknownPhysicalExpression,
27-
InvalidExpression,
28-
Database(DbErr),
29-
}
30-
31-
impl From<DbErr> for MemoError {
32-
fn from(value: DbErr) -> Self {
33-
MemoError::Database(value)
34-
}
35-
}
36-
37-
/// A type alias for a result with [`MemoError`] as the error type.
38-
type Result<T> = std::result::Result<T, MemoError>;
39-
40-
/// A trait representing an implementation of a memoization table.
41-
///
42-
/// Note that we use [`trait_variant`] here in order to add bounds on every method.
43-
/// See this [blog post](
44-
/// https://blog.rust-lang.org/2023/12/21/async-fn-rpit-in-traits.html#async-fn-in-public-traits)
45-
/// for more information.
46-
///
47-
/// TODO Figure out for each when to get the ID of a record or the entire record itself.
48-
#[trait_variant::make(Send)]
49-
pub trait Memo {
50-
/// A type representing a group in the Cascades framework.
51-
type Group;
52-
/// A type representing a unique identifier for a group.
53-
type GroupId;
54-
/// A type representing a logical expression.
55-
type LogicalExpression;
56-
/// A type representing a unique identifier for a logical expression.
57-
type LogicalExpressionId;
58-
/// A type representing a physical expression.
59-
type PhysicalExpression;
60-
/// A type representing a unique identifier for a physical expression.
61-
type PhysicalExpressionId;
62-
63-
/// Retrieves a [`Self::Group`] given a [`Self::GroupId`].
64-
///
65-
/// If the group does not exist, returns a [`MemoError::UnknownGroup`] error.
66-
async fn get_group(&self, group_id: Self::GroupId) -> Result<Self::Group>;
67-
68-
/// Retrieves all group IDs that are stored in the memo table.
69-
async fn get_all_groups(&self) -> Result<Vec<Self::Group>>;
70-
71-
/// Retrieves a [`Self::LogicalExpression`] given a [`Self::LogicalExpressionId`].
72-
///
73-
/// If the logical expression does not exist, returns a [`MemoError::UnknownLogicalExpression`]
74-
/// error.
75-
async fn get_logical_expression(
76-
&self,
77-
logical_expression_id: Self::LogicalExpressionId,
78-
) -> Result<Self::LogicalExpression>;
79-
80-
/// Retrieves a [`Self::PhysicalExpression`] given a [`Self::PhysicalExpressionId`].
81-
///
82-
/// If the physical expression does not exist, returns a
83-
/// [`MemoError::UnknownPhysicalExpression`] error.
84-
async fn get_physical_expression(
85-
&self,
86-
physical_expression_id: Self::PhysicalExpressionId,
87-
) -> Result<Self::PhysicalExpression>;
88-
89-
/// Retrieves the parent group ID of a logical expression given its expression ID.
90-
///
91-
/// If the logical expression does not exist, returns a [`MemoError::UnknownLogicalExpression`]
92-
/// error.
93-
async fn get_group_from_logical_expression(
94-
&self,
95-
logical_expression_id: Self::LogicalExpressionId,
96-
) -> Result<Self::GroupId>;
97-
98-
/// Retrieves the parent group ID of a logical expression given its expression ID.
99-
///
100-
/// If the physical expression does not exist, returns a
101-
/// [`MemoError::UnknownPhysicalExpression`] error.
102-
async fn get_group_from_physical_expression(
103-
&self,
104-
physical_expression_id: Self::PhysicalExpressionId,
105-
) -> Result<Self::GroupId>;
106-
107-
/// Retrieves all of the logical expression "children" of a group.
108-
///
109-
/// If the group does not exist, returns a [`MemoError::UnknownGroup`] error.
110-
async fn get_group_logical_expressions(
111-
&self,
112-
group_id: Self::GroupId,
113-
) -> Result<Vec<Self::LogicalExpression>>;
114-
115-
/// Retrieves all of the physical expression "children" of a group.
116-
///
117-
/// If the group does not exist, returns a [`MemoError::UnknownGroup`] error.
118-
async fn get_group_physical_expressions(
119-
&self,
120-
group_id: Self::GroupId,
121-
) -> Result<Vec<Self::PhysicalExpression>>;
122-
123-
/// Retrieves the best physical query plan (winner) for a given group.
124-
///
125-
/// If the group does not exist, returns a [`MemoError::UnknownGroup`] error.
126-
async fn get_winner(
127-
&self,
128-
group_id: Self::GroupId,
129-
) -> Result<Option<Self::PhysicalExpressionId>>;
130-
131-
/// Updates / replaces a group's best physical plan (winner). Optionally returns the previous
132-
/// winner's physical expression ID.
133-
///
134-
/// If the group does not exist, returns a [`MemoError::UnknownGroup`] error.
135-
async fn update_group_winner(
136-
&mut self,
137-
group_id: Self::GroupId,
138-
physical_expression_id: Self::PhysicalExpressionId,
139-
) -> Result<Option<Self::PhysicalExpressionId>>;
140-
141-
/// Adds a logical expression to an existing group via its [`Self::GroupId`].
142-
///
143-
/// If the group does not exist, returns a [`MemoError::UnknownGroup`] error.
144-
async fn add_logical_expression_to_group(
145-
&mut self,
146-
group_id: Self::GroupId,
147-
logical_expression: Self::LogicalExpression,
148-
) -> Result<()>;
149-
150-
/// Adds a physical expression to an existing group via its [`Self::GroupId`].
151-
///
152-
/// If the group does not exist, returns a [`MemoError::UnknownGroup`] error.
153-
async fn add_physical_expression_to_group(
154-
&mut self,
155-
group_id: Self::GroupId,
156-
physical_expression: Self::PhysicalExpression,
157-
) -> Result<()>;
158-
159-
/// Adds a new logical expression into the memo table, creating a new group if the expression
160-
/// does not already exist.
161-
///
162-
/// The [`Self::LogicalExpression`] type should have some sort of mechanism for checking if
163-
/// the expression has been seen before, and if it has already been created, then the parent
164-
/// group ID should also be retrievable.
165-
///
166-
/// If the expression already exists, then this function will return the [`Self::GroupId`] of
167-
/// the parent group and the corresponding (already existing) [`Self::LogicalExpressionId`].
168-
///
169-
/// If the expression does not exist, this function will create a new group and a new
170-
/// expression, returning brand new IDs for both.
171-
async fn add_logical_expression(
172-
&mut self,
173-
expression: Self::LogicalExpression,
174-
) -> Result<(Self::GroupId, Self::LogicalExpressionId)>;
175-
}

optd-persistent/src/main.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,14 @@ use optd_persistent::DATABASE_URL;
1717

1818
#[tokio::main]
1919
async fn main() {
20-
basic_demo().await
20+
basic_demo().await;
21+
memo_demo().await;
22+
}
23+
24+
async fn memo_demo() {
25+
let _db = Database::connect(DATABASE_URL).await.unwrap();
26+
27+
todo!()
2128
}
2229

2330
async fn basic_demo() {
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
use sea_orm::*;
2+
3+
/// The different kinds of errors that might occur while running operations on a memo table.
4+
pub enum MemoError {
5+
UnknownGroup,
6+
UnknownLogicalExpression,
7+
UnknownPhysicalExpression,
8+
InvalidExpression,
9+
Database(DbErr),
10+
}
11+
12+
impl From<DbErr> for MemoError {
13+
fn from(value: DbErr) -> Self {
14+
MemoError::Database(value)
15+
}
16+
}
17+
18+
/// A type alias for a result with [`MemoError`] as the error type.
19+
pub type Result<T> = std::result::Result<T, MemoError>;
20+
21+
/// A trait representing an implementation of a memoization table.
22+
///
23+
/// Note that we use [`trait_variant`] here in order to add bounds on every method.
24+
/// See this [blog post](
25+
/// https://blog.rust-lang.org/2023/12/21/async-fn-rpit-in-traits.html#async-fn-in-public-traits)
26+
/// for more information.
27+
///
28+
/// TODO Figure out for each when to get the ID of a record or the entire record itself.
29+
#[trait_variant::make(Send)]
30+
pub trait Memo {
31+
/// A type representing a group in the Cascades framework.
32+
type Group;
33+
/// A type representing a unique identifier for a group.
34+
type GroupId;
35+
/// A type representing a logical expression.
36+
type LogicalExpression;
37+
/// A type representing a unique identifier for a logical expression.
38+
type LogicalExpressionId;
39+
/// A type representing a physical expression.
40+
type PhysicalExpression;
41+
/// A type representing a unique identifier for a physical expression.
42+
type PhysicalExpressionId;
43+
44+
/// Retrieves a [`Self::Group`] given a [`Self::GroupId`].
45+
///
46+
/// If the group does not exist, returns a [`MemoError::UnknownGroup`] error.
47+
async fn get_group(&self, group_id: Self::GroupId) -> Result<Self::Group>;
48+
49+
/// Retrieves all group IDs that are stored in the memo table.
50+
async fn get_all_groups(&self) -> Result<Vec<Self::Group>>;
51+
52+
/// Retrieves a [`Self::LogicalExpression`] given a [`Self::LogicalExpressionId`].
53+
///
54+
/// If the logical expression does not exist, returns a [`MemoError::UnknownLogicalExpression`]
55+
/// error.
56+
async fn get_logical_expression(
57+
&self,
58+
logical_expression_id: Self::LogicalExpressionId,
59+
) -> Result<Self::LogicalExpression>;
60+
61+
/// Retrieves a [`Self::PhysicalExpression`] given a [`Self::PhysicalExpressionId`].
62+
///
63+
/// If the physical expression does not exist, returns a
64+
/// [`MemoError::UnknownPhysicalExpression`] error.
65+
async fn get_physical_expression(
66+
&self,
67+
physical_expression_id: Self::PhysicalExpressionId,
68+
) -> Result<Self::PhysicalExpression>;
69+
70+
/// Retrieves the parent group ID of a logical expression given its expression ID.
71+
///
72+
/// If the logical expression does not exist, returns a [`MemoError::UnknownLogicalExpression`]
73+
/// error.
74+
async fn get_group_from_logical_expression(
75+
&self,
76+
logical_expression_id: Self::LogicalExpressionId,
77+
) -> Result<Self::GroupId>;
78+
79+
/// Retrieves the parent group ID of a logical expression given its expression ID.
80+
///
81+
/// If the physical expression does not exist, returns a
82+
/// [`MemoError::UnknownPhysicalExpression`] error.
83+
async fn get_group_from_physical_expression(
84+
&self,
85+
physical_expression_id: Self::PhysicalExpressionId,
86+
) -> Result<Self::GroupId>;
87+
88+
/// Retrieves all of the logical expression "children" of a group.
89+
///
90+
/// If the group does not exist, returns a [`MemoError::UnknownGroup`] error.
91+
async fn get_group_logical_expressions(
92+
&self,
93+
group_id: Self::GroupId,
94+
) -> Result<Vec<Self::LogicalExpression>>;
95+
96+
/// Retrieves all of the physical expression "children" of a group.
97+
///
98+
/// If the group does not exist, returns a [`MemoError::UnknownGroup`] error.
99+
async fn get_group_physical_expressions(
100+
&self,
101+
group_id: Self::GroupId,
102+
) -> Result<Vec<Self::PhysicalExpression>>;
103+
104+
/// Retrieves the best physical query plan (winner) for a given group.
105+
///
106+
/// If the group does not exist, returns a [`MemoError::UnknownGroup`] error.
107+
async fn get_winner(
108+
&self,
109+
group_id: Self::GroupId,
110+
) -> Result<Option<Self::PhysicalExpressionId>>;
111+
112+
/// Updates / replaces a group's best physical plan (winner). Optionally returns the previous
113+
/// winner's physical expression ID.
114+
///
115+
/// If the group does not exist, returns a [`MemoError::UnknownGroup`] error.
116+
async fn update_group_winner(
117+
&mut self,
118+
group_id: Self::GroupId,
119+
physical_expression_id: Self::PhysicalExpressionId,
120+
) -> Result<Option<Self::PhysicalExpressionId>>;
121+
122+
/// Adds a logical expression to an existing group via its [`Self::GroupId`].
123+
///
124+
/// If the group does not exist, returns a [`MemoError::UnknownGroup`] error.
125+
async fn add_logical_expression_to_group(
126+
&mut self,
127+
group_id: Self::GroupId,
128+
logical_expression: Self::LogicalExpression,
129+
) -> Result<()>;
130+
131+
/// Adds a physical expression to an existing group via its [`Self::GroupId`].
132+
///
133+
/// If the group does not exist, returns a [`MemoError::UnknownGroup`] error.
134+
async fn add_physical_expression_to_group(
135+
&mut self,
136+
group_id: Self::GroupId,
137+
physical_expression: Self::PhysicalExpression,
138+
) -> Result<()>;
139+
140+
/// Adds a new logical expression into the memo table, creating a new group if the expression
141+
/// does not already exist.
142+
///
143+
/// The [`Self::LogicalExpression`] type should have some sort of mechanism for checking if
144+
/// the expression has been seen before, and if it has already been created, then the parent
145+
/// group ID should also be retrievable.
146+
///
147+
/// If the expression already exists, then this function will return the [`Self::GroupId`] of
148+
/// the parent group and the corresponding (already existing) [`Self::LogicalExpressionId`].
149+
///
150+
/// If the expression does not exist, this function will create a new group and a new
151+
/// expression, returning brand new IDs for both.
152+
async fn add_logical_expression(
153+
&mut self,
154+
expression: Self::LogicalExpression,
155+
) -> Result<(Self::GroupId, Self::LogicalExpressionId)>;
156+
}

optd-persistent/src/memo/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pub mod interface;
2+
pub mod orm;

optd-persistent/src/memo.rs renamed to optd-persistent/src/memo/orm.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
use super::*;
1+
use crate::{
2+
entities::{prelude::*, *},
3+
DATABASE_URL,
4+
};
5+
use sea_orm::*;
6+
7+
use super::interface::{Memo, MemoError, Result};
28

39
pub struct MemoTable {
410
db: DatabaseConnection,

0 commit comments

Comments
 (0)