[][src]Trait salsa::ParallelDatabase

pub trait ParallelDatabase: Database + Send {
    fn snapshot(&self) -> Snapshot<Self>;
}

Indicates a database that also supports parallel query evaluation. All of Salsa's base query support is capable of parallel execution, but for it to work, your query key/value types must also be Send, as must any additional data in your database.

Required methods

fn snapshot(&self) -> Snapshot<Self>

Creates a second handle to the database that holds the database fixed at a particular revision. So long as this "frozen" handle exists, any attempt to set an input will block.

This is the method you are meant to use most of the time in a parallel setting where modifications may arise asynchronously (e.g., a language server). In this context, it is common to wish to "fork off" a snapshot of the database performing some series of queries in parallel and arranging the results. Using this method for that purpose ensures that those queries will see a consistent view of the database (it is also advisable for those queries to use the is_current_revision_canceled method to check for cancellation).

Panics

It is not permitted to create a snapshot from inside of a query. Attepting to do so will panic.

Deadlock warning

The intended pattern for snapshots is that, once created, they are sent to another thread and used from there. As such, the snapshot acquires a "read lock" on the database -- therefore, so long as the snapshot is not dropped, any attempt to set a value in the database will block. If the snapshot is owned by the same thread that is attempting to set, this will cause a problem.

How to implement this

Typically, this method will create a second copy of your database type (MyDatabaseType, in the example below), cloning over each of the fields from self into this new copy. For the field that stores the salsa runtime, you should use the Runtime::snapshot method to create a snapshot of the runtime. Finally, package up the result using Snapshot::new, which is a simple wrapper type that only gives &self access to the database within (thus preventing the use of methods that may mutate the inputs):

This example is not tested
impl ParallelDatabase for MyDatabaseType {
    fn snapshot(&self) -> Snapshot<Self> {
        Snapshot::new(
            MyDatabaseType {
                runtime: self.runtime.snapshot(self),
                other_field: self.other_field.clone(),
            }
        )
    }
}
Loading content...

Implementors

Loading content...