Skip to content
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

Fix subscription benchmarks by fixing create_table_for_test_with_the_works #2027

Merged
merged 1 commit into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/bench/benches/subscription.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ fn eval(c: &mut Criterion) {
&raw.db,
&tx,
None,
Compression::Brotli,
Compression::None,
)))
})
});
Expand Down
3 changes: 2 additions & 1 deletion crates/core/src/db/relational_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -841,8 +841,9 @@ impl RelationalDB {
access: StAccess,
) -> Result<TableId, DBError> {
let mut module_def_builder = RawModuleDefV9Builder::new();

let mut table_builder = module_def_builder
.build_table_with_new_type(name, ProductType::from_iter(schema.iter().cloned()), true)
.build_table_with_new_type_for_tests(name, ProductType::from_iter(schema.iter().cloned()), true)
.with_access(access.into());

for columns in indexes {
Expand Down
50 changes: 50 additions & 0 deletions crates/lib/src/db/raw_def/v9.rs
Original file line number Diff line number Diff line change
Expand Up @@ -479,11 +479,61 @@ impl RawModuleDefV9Builder {
custom_ordering: bool,
) -> RawTableDefBuilder {
let table_name = table_name.into();

let product_type_ref = self.add_algebraic_type([], table_name.clone(), product_type.into(), custom_ordering);

self.build_table(table_name, product_type_ref)
}

/// Build a new table with a product type, for testing.
/// Adds the type to the module.
pub fn build_table_with_new_type_for_tests(
&mut self,
table_name: impl Into<RawIdentifier>,
mut product_type: spacetimedb_sats::ProductType,
custom_ordering: bool,
) -> RawTableDefBuilder {
self.add_expand_product_type_for_tests(&mut 0, &mut product_type);

self.build_table_with_new_type(table_name, product_type, custom_ordering)
}

fn add_expand_type_for_tests(&mut self, name_gen: &mut usize, ty: &mut AlgebraicType) {
if ty.is_valid_for_client_type_use() {
return;
}

match ty {
AlgebraicType::Product(prod_ty) => self.add_expand_product_type_for_tests(name_gen, prod_ty),
AlgebraicType::Sum(sum_type) => {
if let Some(wrapped) = sum_type.as_option_mut() {
self.add_expand_type_for_tests(name_gen, wrapped);
} else {
for elem in sum_type.variants.iter_mut() {
self.add_expand_type_for_tests(name_gen, &mut elem.algebraic_type);
}
}
}
AlgebraicType::Array(ty) => {
self.add_expand_type_for_tests(name_gen, &mut ty.elem_ty);
return;
}
_ => return,
}

// Make the type into a ref.
let name = *name_gen;
let add_ty = core::mem::replace(ty, AlgebraicType::U8);
*ty = AlgebraicType::Ref(self.add_algebraic_type([], format!("gen_{name}"), add_ty, true));
*name_gen += 1;
}

fn add_expand_product_type_for_tests(&mut self, name_gen: &mut usize, ty: &mut ProductType) {
for elem in ty.elements.iter_mut() {
self.add_expand_type_for_tests(name_gen, &mut elem.algebraic_type);
}
}

/// Add a type to the typespace, along with a type alias declaring its name.
/// This method should only be use for `AlgebraicType`s not corresponding to a Rust
/// type that implements `SpacetimeType`.
Expand Down
29 changes: 22 additions & 7 deletions crates/sats/src/sum_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,32 @@ impl SumType {
/// If the type does look like a structural option type, returns the type `T`.
pub fn as_option(&self) -> Option<&AlgebraicType> {
match &*self.variants {
[first, second]
if second.is_unit() // Done first to avoid pointer indirection when it doesn't matter.
&& first.has_name(OPTION_SOME_TAG)
&& second.has_name(OPTION_NONE_TAG) =>
{
Some(&first.algebraic_type)
}
[first, second] if Self::are_variants_option(first, second) => Some(&first.algebraic_type),
_ => None,
}
}

/// Check whether this sum type is a structural option type.
///
/// A structural option type has `some(T)` as its first variant and `none` as its second.
/// That is, `{ some(T), none }` or `some: T | none` depending on your notation.
/// Note that `some` and `none` are lowercase, unlike Rust's `Option`.
/// Order matters, and an option type with these variants in the opposite order will not be recognized.
///
/// If the type does look like a structural option type, returns the type `T`.
pub fn as_option_mut(&mut self) -> Option<&mut AlgebraicType> {
match &mut *self.variants {
[first, second] if Self::are_variants_option(first, second) => Some(&mut first.algebraic_type),
_ => None,
}
}

fn are_variants_option(first: &SumTypeVariant, second: &SumTypeVariant) -> bool {
second.is_unit() // Done first to avoid pointer indirection when it doesn't matter.
&& first.has_name(OPTION_SOME_TAG)
&& second.has_name(OPTION_NONE_TAG)
}

/// Check whether this sum type is a structural option type.
///
/// A structural option type has `some(T)` as its first variant and `none` as its second.
Expand Down
Loading