-
Notifications
You must be signed in to change notification settings - Fork 109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cache the 'row_type' on TableSchema so is not re-build in each access #638
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please leave a comment explaining what the purpose of the new
function is (to cache the row_type
) and why it is important to cache the row_type
table_id: TableId(42), | ||
table_name: "Person".into(), | ||
columns: vec![ColumnSchema { | ||
let current = vec![Cow::Owned(TableSchema::new( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's keep this PR as minimal as possible. Please remove the changes related to this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to do this change to calculate the row_type
}) | ||
.collect(), | ||
) | ||
pub fn get_row_type(&self) -> &ProductType { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please leave a comment on this code explaining what it's purpose is and why we are caching the product_type
table_type: StTableType, | ||
table_access: StAccess, | ||
) -> Self { | ||
let row_type = ProductType::new( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, it's related to caching the row type.
benchmark please |
@@ -271,7 +271,7 @@ impl CommittedState { | |||
// Insert the columns into `st_columns` | |||
let st_columns = self.get_or_create_table(ST_COLUMNS_ID, st_columns_schema()); | |||
|
|||
for col in system_tables().into_iter().flat_map(|x| x.columns) { | |||
for col in system_tables().into_iter().flat_map(|x| x.columns.clone()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this cloning now? You already have an owned type due to into_iter
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rust complains:
error[E0507]: cannot move out of dereference of `spacetimedb_sats::db::def::TableSchema`
--> crates/core/src/db/datastore/locking_tx_datastore/mod.rs:274:61
|
274 | for col in system_tables().into_iter().flat_map(|x| x.columns) {
| ^^^^^^^^^ move occurs because value has type `std::vec::Vec<spacetimedb_sats::db::def::ColumnSchema>`, which does not implement the `Copy` trait
I think this is a consequence of the read_only
mark.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, well in that case I think the attribute should be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue is that caching the row_type
means any change to columns
invalidates that, and I need a way to protect against that scenario.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can make the columns
field non-pub
in that case and provide methods that give self
and &self
access but not &mut self
.
self.schema_for_table(table_id, database_address)?.get_row_type(), | ||
self.schema_for_table(table_id, database_address)? | ||
.get_row_type() | ||
.clone(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
schema_for_table
' Cow::Borrowed
branch should be unreachable here because the if let Some(row_type)
branch wasn't taken. At any rate, you can avoid this clone by checking if we have Cow::Owned
.
)) | ||
Ok(match self.schema_for_table(table_id, database_address)? { | ||
Cow::Borrowed(x) => Cow::Borrowed(x.get_row_type()), | ||
Cow::Owned(x) => Cow::Owned(x.get_row_type().clone()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clone shouldn't be necessary in the Owned branch either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is get_row_type(&self) -> &ProductType
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah but you have ownership of TableSchema
, so you could get out an owned ProductType
, either through adding an additional method or by making the field pub
.
5c08141
to
c1f1148
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
I'm dismissing this because the comments appear to me to have been addressed.
Description of Changes
This is a possible fix for the performance issue on BitCraft.
Now is forbidden to mutate the
columns
onTableSchema
so we can cache therow_type
.Expected complexity level and risk
1