1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
use Arc;
///////////////////////////////////////////////////////////////////////////
// Step 1. Define the query group
// A **query group** is a collection of queries (both inputs and
// functions) that are defined in one particular spot. Each query
// group is defined by a trait decorated with the
// `#[salsa::query_group]` attribute. The trait defines one method per
// query, with the arguments to the method being the query **keys** and
// the return value being the query's **value**.
//
// Along with the trait, each query group has an associated
// "storage struct". The name of this struct is specified in the `query_group`
// attribute -- for a query group `Foo`, it is conventionally `FooStorage`.
//
// When we define the final database (see below), we will list out the
// storage structs for each query group that it contains. The database
// will then automatically implement the traits.
//
// Note that one query group can "include" another by listing the
// trait for that query group as a supertrait.
// ANCHOR:trait
// ANCHOR_END:trait
///////////////////////////////////////////////////////////////////////////
// Step 2. Define the queries.
// Define the **function** for the `length` query. This function will
// be called whenever the query's value must be recomputed. After it
// is called once, its result is typically memoized, unless we think
// that one of the inputs may have changed. Its first argument (`db`)
// is the "database". This is always a `&dyn` version of the query group
// trait, so that you can invoke all the queries you know about.
// We never know the concrete type here, as the full database may contain
// methods from other query groups that we don't know about.
///////////////////////////////////////////////////////////////////////////
// Step 3. Define the database struct
// Define the actual database struct. This struct needs to be annotated with
// `#[salsa::database(..)]`. The list `..` will be the paths leading to the
// storage structs for each query group that this database supports. This
// attribute macro will generate the necessary impls so that the database
// implements the corresponding traits as well (so, here, `DatabaseStruct` will
// implement the `HelloWorld` trait).
//
// The database struct must have a field `storage: salsa::Storage<Self>`, but it
// can have any number of additional fields beyond that. The
// `#[salsa::database]` macro will generate glue code that accesses this
// `storage` field (but other fields are ignored). The `Storage<Self>` type
// contains all the actual hashtables and the like used to store query results
// and dependency information.
//
// In addition to including the `storage` field, you must also implement the
// `salsa::Database` trait (as shown below). This gives you a chance to define
// the callback methods within if you want to (in this example, we don't).
// ANCHOR:database
// ANCHOR_END:database
// This shows how to use a query.