Skip to content

Commit

Permalink
book chapter
Browse files Browse the repository at this point in the history
  • Loading branch information
nikomatsakis committed Apr 2, 2024
1 parent 54b33c3 commit 3a15db7
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
1 change: 1 addition & 0 deletions book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
- [Plumbing](./plumbing.md)
- [Jars and ingredients](./plumbing/jars_and_ingredients.md)
- [Databases and runtime](./plumbing/database_and_runtime.md)
- [Tracked structures](./plumbing/tracked_structs.md)
- [Query operations](./plumbing/query_ops.md)
- [maybe changed after](./plumbing/maybe_changed_after.md)
- [Fetch](./plumbing/fetch.md)
Expand Down
50 changes: 50 additions & 0 deletions book/src/plumbing/tracked_structs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Tracked structs

Tracked structs are stored in a special way to reduce their costs.

Tracked structs are created via a `new` operation.

## The tracked struct and tracked field ingredients

For a single tracked struct we create multiple ingredients.
The **tracked struct ingredient** is the ingredient created first.
It offers methods to create new instances of the struct and therefore
has unique access to the interner and hashtables used to create the struct id.
It also shares access to a hashtable that stores the `TrackedStructValue` that
contains the field data.

For each field, we create a **tracked field ingredient** that moderates access
to a particular field. All of these ingredients use that same shared hashtable
to access the `TrackedStructValue` instance for a given id. The `TrackedStructValue`
contains both the field values but also the revisions when they last changed value.

## Each tracked struct has a globally unique id

This will begin by creating a *globally unique, 32-bit id* for the tracked struct. It is created by interning a combination of

* the currently executing query;
* a u64 hash of the `#[id]` fields;
* a *disambiguator* that makes this hash unique within the current query. i.e., when a query starts executing, it creates an empty map, and the first time a tracked struct with a given hash is created, it gets disambiguator 0. The next one will be given 1, etc.

## Each tracked struct has a `TrackedStructValue` storing its data

The struct and field ingredients share access to a hashmap that maps
each field id to a value struct:

```rust,ignore
{{#include ../../../components/salsa-2022/src/tracked_struct.rs:TrackedStructValue}}
```

The value struct stores the values of the fields but also the revisions when
that field last changed. Each time the struct is recreated in a new revision,
the old and new values for its fields are compared and a new revision is created.

## The macro generates the tracked struct `Configuration`

The "configuration" for a tracked struct defines not only the types of the fields,
but also various important operations such as extracting the hashable id fields
and updating the "revisions" to track when a field last changed:

```rust,ignore
{{#include ../../../components/salsa-2022/src/tracked_struct.rs:Configuration}}
```

0 comments on commit 3a15db7

Please sign in to comment.