clockworklabs / clockworklabs/SpacetimeDB

Add `AlgebraicType::Transparent { ty: Box<AlgebraicType>, name: Box<str> }`

Open
#1,287 8 comments 0 reactions 1 assignee View on GitHub

@Centril is already working on this.

Since Sep 23, 2024.

enhancement
Dominant language
Rust
Stars
25.2k
Forks
1.1k
Avg merge
2d 7h
Merged PRs (30d)
46

Description

What

The idea here is that we add a variant to AT (AlgebraicType) that looks like this:

struct TransparentType {
    ty: Box<AlgebraicType>,
    name: Box<str>,
}

pub enum AlgebraicType {
    ...
    Transparent(TransparentType),
}

This is a newtype around the ty, with a name assigned to it.

There won't however be a TransparentValue or such, as the type is representationally transparent, meaning that an AV compatible with ty is also compatible with the Transparent(...) wrapper around ty.

Why

The representational transparency aforementioned is the whole point.
Currently, our Identity and Address types are typed in the database as:

AlgebraicType::product([("__identity_bytes", AlgebraicType::bytes())]) // Identity
AlgebraicType::product([("__address_bytes", AlgebraicType::bytes())]) // Address

But this also means that the AV representation is AV::Product(vec![inner_av]) which incurs branching and an unnecessary heap allocation. This also extends to indices, which need to materialize AVs in the general case (although we could do a one-field-product optimization for indices). Currently, this also affects normal scans which also materialize AVs.

With ::Transparent, we can get rid of this wrapping layer and have the AV representation just be inner_av.
Coupled with #1097, this makes it very cheap to store an Identity.

Alternatives

  • Keep things as is.
  • Optimize indices to unwrap a single-field product value and call it a day.
  • Introduce AV/T::{Identity, Address}. Arguably these are somewhat special types, and this would be even cheaper. However, these newtypes inroduced with ::Transparent could also be useful for users to make their own specially recognized types.

Bikeshed

I chose Transparent to mirrior #[repr(transparent)] in Rust.

We might also name this NewType or some such.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.