mirror of
https://github.com/salsa-rs/salsa.git
synced 2025-02-02 09:46:06 +00:00
clarify jars a bit, hopefully
Some folks were thinking that Jars were something more complex than they are.
This commit is contained in:
parent
6bd6f6ee0b
commit
8e348f0bc8
1 changed files with 23 additions and 10 deletions
|
@ -1,21 +1,23 @@
|
|||
# Jars and databases
|
||||
|
||||
Salsa programs are composed in **jars**[^jar].
|
||||
A **jar** is the salsa version of a Rust crate or module.
|
||||
It is a struct that contains the memoized results for some subset of your program.
|
||||
A jar is just a fancy name for a struct whose fields contain the hashmaps and other state required to implement salsa concepts like [memoized function](../overview.md#memoized-functions) or [entity](../overview.md#entity-values)/[interned](../overview.md#interned-values) structs.
|
||||
Typically you have one jar per crate, but that is not required.
|
||||
When you declare the salsa database, you will give it a list of all the jar structs in your program, and it will allocate one of each so as to have all the storage it needs.
|
||||
|
||||
Typically you define one jar per crate in your program, and you define it at the path `crate::Jar`.
|
||||
You don't have to do this, but it's more convenient because the various salsa macros have defaults that expect the jar to be at this location.
|
||||
Each time you declare something like a [memoized function], it is associated with some jar.
|
||||
By default, that jar is expected to be `crate::Jar`.
|
||||
You can give the jar struct another name, or put it somewhere else, but then you will have to write `jar = path::to::your::Jar` everywhere, so it's not recommended.
|
||||
|
||||
Our `calc` example has only a single crate, but we'll still put the `Jar` struct at the root of the crate:
|
||||
Our `calc` example has only a single crate. We follow the salsa convention and declare the `Jar` struct at the root of the crate:
|
||||
|
||||
```rust
|
||||
{{#include ../../../calc-example/calc/src/main.rs:jar_struct}}
|
||||
```
|
||||
|
||||
The `#[salsa::jar]` annotation indicates that this struct is a Salsa jar.
|
||||
The struct must be a tuple struct, and the fields in the struct correspond to the salsa [memoized functions], [entities], and other concepts that we are going to introduce in this tutorial.
|
||||
The idea is that the field type will contain the storage needed to implement that particular salsa-ized thing.
|
||||
You can see that a jar is just a tuple struct, but annotated with `#[salsa::Jar]`.
|
||||
The fields of the struct correspond to the various things that need state in the database.
|
||||
We're going to be introducing each of those fields through the tutorial.
|
||||
|
||||
[memoized functions]: ../reference/memoized.md
|
||||
[entities]: ../reference/entity.md
|
||||
|
@ -31,8 +33,8 @@ It identifies the **database trait** for this jar.
|
|||
|
||||
Whereas a salsa jar contains all the storage needed for a particular crate,
|
||||
the salsa **database** is a struct that contains all the storage needed for an entire program.
|
||||
Jars, however, don't refer directly to this database struct.
|
||||
Instead, each jar defines a trait, typically called `Db`, that the struct must implement.
|
||||
Typical salsa functions, however, don't refer directly to this database struct.
|
||||
Instead, they refer to a trait, typically called `crate::Db`, that the final database must implement.
|
||||
This allows for separate compilation, where you have a database that contains the data for two jars, but those jars don't depend on one another.
|
||||
|
||||
The database trait for our `calc` crate is very simple:
|
||||
|
@ -61,3 +63,14 @@ and that's what we do here:
|
|||
```rust
|
||||
{{#include ../../../calc-example/calc/src/main.rs:jar_db_impl}}
|
||||
```
|
||||
|
||||
## Summary
|
||||
|
||||
If the concept of a jar seems a bit abstract to you, don't overthink it. The TL;DR is that when you create a salsa program, you need to do:
|
||||
|
||||
- In each of your crates:
|
||||
- Define a `#[salsa::jar(db = Db)]` struct, typically at `crate::Jar`, and list each of your various salsa-annotated things inside of it.
|
||||
- Define a `Db` trait, typically at `crate::Db`, that you will use in memoized functions and elsewhere to refer to the database struct.
|
||||
- Once, typically in your final crate:
|
||||
- Define a database `D`, as described in the [next section](./db.md), that will contain a list of each of the jars for each of your crates.
|
||||
- Implement the `Db` traits for each jar for your database type `D` (often we do this through blanket impls in the jar crates).
|
||||
|
|
Loading…
Reference in a new issue