Skip to content

Commit

Permalink
fix subscription benchmarks by fixing create_table_for_test_with_the_…
Browse files Browse the repository at this point in the history
…works
  • Loading branch information
Centril committed Nov 28, 2024
1 parent 1992b8e commit 68857bc
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 8 deletions.
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

0 comments on commit 68857bc

Please sign in to comment.