Skip to content

Commit cfa88e9

Browse files
authored
Move salsa event system into Zalsa (#849)
* Move salsa event system into `Zalsa` * Encode `None` into ShallowUpdate This shrinks the return value from 16 to 8 bytes
1 parent f78a641 commit cfa88e9

35 files changed

+421
-352
lines changed

components/salsa-macro-rules/src/setup_accumulator_impl.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,12 @@ macro_rules! setup_accumulator_impl {
2323

2424
// Suppress the lint against `cfg(loom)`.
2525
#[allow(unexpected_cfgs)]
26-
fn $ingredient(db: &dyn $zalsa::Database) -> &$zalsa_struct::IngredientImpl<$Struct> {
26+
fn $ingredient(zalsa: &$zalsa::Zalsa) -> &$zalsa_struct::IngredientImpl<$Struct> {
2727
$zalsa::__maybe_lazy_static! {
2828
static $CACHE: $zalsa::IngredientCache<$zalsa_struct::IngredientImpl<$Struct>> =
2929
$zalsa::IngredientCache::new();
3030
}
3131

32-
let zalsa = db.zalsa();
3332
$CACHE.get_or_create(zalsa, || {
3433
zalsa.add_or_lookup_jar_by_type::<$zalsa_struct::JarImpl<$Struct>>()
3534
})
@@ -42,8 +41,8 @@ macro_rules! setup_accumulator_impl {
4241
where
4342
Db: ?Sized + $zalsa::Database,
4443
{
45-
let db = db.as_dyn_database();
46-
$ingredient(db).push(db, self);
44+
let (zalsa, zalsa_local) = db.zalsas();
45+
$ingredient(zalsa).push(zalsa_local, self);
4746
}
4847
}
4948
};

components/salsa-macro-rules/src/setup_input_struct.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,18 @@ macro_rules! setup_input_struct {
9191
}
9292

9393
impl $Configuration {
94+
pub fn ingredient(db: &dyn $zalsa::Database) -> &$zalsa_struct::IngredientImpl<Self> {
95+
Self::ingredient_(db.zalsa())
96+
}
97+
9498
// Suppress the lint against `cfg(loom)`.
9599
#[allow(unexpected_cfgs)]
96-
pub fn ingredient(db: &dyn $zalsa::Database) -> &$zalsa_struct::IngredientImpl<Self> {
100+
fn ingredient_(zalsa: &$zalsa::Zalsa) -> &$zalsa_struct::IngredientImpl<Self> {
97101
zalsa_::__maybe_lazy_static! {
98102
static CACHE: $zalsa::IngredientCache<$zalsa_struct::IngredientImpl<$Configuration>> =
99103
$zalsa::IngredientCache::new();
100104
}
101105

102-
let zalsa = db.zalsa();
103106
CACHE.get_or_create(zalsa, || {
104107
zalsa.add_or_lookup_jar_by_type::<$zalsa_struct::JarImpl<$Configuration>>()
105108
})
@@ -184,7 +187,7 @@ macro_rules! setup_input_struct {
184187
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
185188
$Db: ?Sized + $zalsa::Database,
186189
{
187-
let fields = $Configuration::ingredient(db.as_dyn_database()).field(
190+
let fields = $Configuration::ingredient_(db.zalsa()).field(
188191
db.as_dyn_database(),
189192
self,
190193
$field_index,
@@ -221,7 +224,8 @@ macro_rules! setup_input_struct {
221224
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
222225
$Db: ?Sized + salsa::Database,
223226
{
224-
$Configuration::ingredient(db.as_dyn_database()).get_singleton_input(db)
227+
let zalsa = db.zalsa();
228+
$Configuration::ingredient_(zalsa).get_singleton_input(zalsa)
225229
}
226230

227231
#[track_caller]
@@ -271,8 +275,9 @@ macro_rules! setup_input_struct {
271275
// FIXME(rust-lang/rust#65991): The `db` argument *should* have the type `dyn Database`
272276
$Db: ?Sized + salsa::Database
273277
{
274-
let current_revision = $zalsa::current_revision(db);
275-
let ingredient = $Configuration::ingredient(db.as_dyn_database());
278+
let zalsa = db.zalsa();
279+
let current_revision = zalsa.current_revision();
280+
let ingredient = $Configuration::ingredient_(zalsa);
276281
let (fields, stamps) = builder::builder_into_inner(self, current_revision);
277282
ingredient.new_input(db.as_dyn_database(), fields, stamps)
278283
}

components/salsa-macro-rules/src/setup_tracked_fn.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ macro_rules! setup_tracked_fn {
213213
$inner($db, $($input_id),*)
214214
}
215215

216-
fn cycle_initial<$db_lt>(db: &$db_lt dyn $Db, ($($input_id),*): ($($input_ty),*)) -> Self::Output<$db_lt> {
216+
fn cycle_initial<$db_lt>(db: &$db_lt Self::DbView, ($($input_id),*): ($($input_ty),*)) -> Self::Output<$db_lt> {
217217
$($cycle_recovery_initial)*(db, $($input_id),*)
218218
}
219219

@@ -231,7 +231,7 @@ macro_rules! setup_tracked_fn {
231231
if $needs_interner {
232232
$Configuration::intern_ingredient(db).data(db.as_dyn_database(), key).clone()
233233
} else {
234-
$zalsa::FromIdWithDb::from_id(key, db)
234+
$zalsa::FromIdWithDb::from_id(key, db.zalsa())
235235
}
236236
}
237237
}

components/salsa-macro-rules/src/setup_tracked_struct.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,15 +169,18 @@ macro_rules! setup_tracked_struct {
169169
}
170170

171171
impl $Configuration {
172+
pub fn ingredient(db: &dyn $zalsa::Database) -> &$zalsa_struct::IngredientImpl<Self> {
173+
Self::ingredient_(db.zalsa())
174+
}
175+
172176
// Suppress the lint against `cfg(loom)`.
173177
#[allow(unexpected_cfgs)]
174-
pub fn ingredient(db: &dyn $zalsa::Database) -> &$zalsa_struct::IngredientImpl<$Configuration> {
178+
fn ingredient_(zalsa: &$zalsa::Zalsa) -> &$zalsa_struct::IngredientImpl<Self> {
175179
$zalsa::__maybe_lazy_static! {
176180
static CACHE: $zalsa::IngredientCache<$zalsa_struct::IngredientImpl<$Configuration>> =
177181
$zalsa::IngredientCache::new();
178182
}
179183

180-
let zalsa = db.zalsa();
181184
CACHE.get_or_create(zalsa, || {
182185
zalsa.add_or_lookup_jar_by_type::<$zalsa_struct::JarImpl<$Configuration>>()
183186
})
@@ -216,8 +219,8 @@ macro_rules! setup_tracked_struct {
216219
}
217220

218221
impl $zalsa::TrackedStructInDb for $Struct<'_> {
219-
fn database_key_index(db: &dyn $zalsa::Database, id: $zalsa::Id) -> $zalsa::DatabaseKeyIndex {
220-
$Configuration::ingredient(db).database_key_index(id)
222+
fn database_key_index(zalsa: &$zalsa::Zalsa, id: $zalsa::Id) -> $zalsa::DatabaseKeyIndex {
223+
$Configuration::ingredient_(zalsa).database_key_index(id)
221224
}
222225
}
223226

components/salsa-macros/src/supertype.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,8 @@ fn enum_impl(enum_item: syn::ItemEnum) -> syn::Result<TokenStream> {
5959
impl #impl_generics zalsa::FromIdWithDb for #enum_name #type_generics
6060
#where_clause {
6161
#[inline]
62-
fn from_id(__id: zalsa::Id, __db: &(impl ?Sized + zalsa::Database)) -> Self {
63-
let __zalsa = __db.zalsa();
64-
let __type_id = __zalsa.lookup_page_type_id(__id);
62+
fn from_id(__id: zalsa::Id, zalsa: &zalsa::Zalsa) -> Self {
63+
let __type_id = zalsa.lookup_page_type_id(__id);
6564
<Self as zalsa::SalsaStructInDb>::cast(__id, __type_id).expect("invalid enum variant")
6665
}
6766
}

examples/calc/db.rs

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,40 @@
1+
#[cfg(test)]
12
use std::sync::{Arc, Mutex};
23

34
// ANCHOR: db_struct
45
#[salsa::db]
5-
#[derive(Default, Clone)]
6+
#[derive(Clone)]
7+
#[cfg_attr(not(test), derive(Default))]
68
pub struct CalcDatabaseImpl {
79
storage: salsa::Storage<Self>,
810

911
// The logs are only used for testing and demonstrating reuse:
12+
#[cfg(test)]
1013
logs: Arc<Mutex<Option<Vec<String>>>>,
1114
}
15+
16+
#[cfg(test)]
17+
impl Default for CalcDatabaseImpl {
18+
fn default() -> Self {
19+
let logs = <Arc<Mutex<Option<Vec<String>>>>>::default();
20+
Self {
21+
storage: salsa::Storage::new(Some(Box::new({
22+
let logs = logs.clone();
23+
move |event| {
24+
eprintln!("Event: {event:?}");
25+
// Log interesting events, if logging is enabled
26+
if let Some(logs) = &mut *logs.lock().unwrap() {
27+
// only log interesting events
28+
if let salsa::EventKind::WillExecute { .. } = event.kind {
29+
logs.push(format!("Event: {event:?}"));
30+
}
31+
}
32+
}
33+
}))),
34+
logs,
35+
}
36+
}
37+
}
1238
// ANCHOR_END: db_struct
1339

1440
impl CalcDatabaseImpl {
@@ -34,17 +60,5 @@ impl CalcDatabaseImpl {
3460

3561
// ANCHOR: db_impl
3662
#[salsa::db]
37-
impl salsa::Database for CalcDatabaseImpl {
38-
fn salsa_event(&self, event: &dyn Fn() -> salsa::Event) {
39-
let event = event();
40-
eprintln!("Event: {event:?}");
41-
// Log interesting events, if logging is enabled
42-
if let Some(logs) = &mut *self.logs.lock().unwrap() {
43-
// only log interesting events
44-
if let salsa::EventKind::WillExecute { .. } = event.kind {
45-
logs.push(format!("Event: {event:?}"));
46-
}
47-
}
48-
}
49-
}
63+
impl salsa::Database for CalcDatabaseImpl {}
5064
// ANCHOR_END: db_impl

examples/lazy-input/main.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,18 @@ struct LazyInputDatabase {
8787

8888
impl LazyInputDatabase {
8989
fn new(tx: Sender<DebounceEventResult>) -> Self {
90+
let logs: Arc<Mutex<Vec<String>>> = Default::default();
9091
Self {
91-
storage: Default::default(),
92-
logs: Default::default(),
92+
storage: Storage::new(Some(Box::new({
93+
let logs = logs.clone();
94+
move |event| {
95+
// don't log boring events
96+
if let salsa::EventKind::WillExecute { .. } = event.kind {
97+
logs.lock().unwrap().push(format!("{event:?}"));
98+
}
99+
}
100+
}))),
101+
logs,
93102
files: DashMap::new(),
94103
file_watcher: Arc::new(Mutex::new(
95104
new_debouncer(Duration::from_secs(1), tx).unwrap(),
@@ -99,15 +108,7 @@ impl LazyInputDatabase {
99108
}
100109

101110
#[salsa::db]
102-
impl salsa::Database for LazyInputDatabase {
103-
fn salsa_event(&self, event: &dyn Fn() -> salsa::Event) {
104-
// don't log boring events
105-
let event = event();
106-
if let salsa::EventKind::WillExecute { .. } = event.kind {
107-
self.logs.lock().unwrap().push(format!("{event:?}"));
108-
}
109-
}
110-
}
111+
impl salsa::Database for LazyInputDatabase {}
111112

112113
#[salsa::db]
113114
impl Db for LazyInputDatabase {

src/accumulator.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use accumulated::{Accumulated, AnyAccumulated};
1010
use crate::function::VerifyResult;
1111
use crate::ingredient::{Ingredient, Jar};
1212
use crate::loom::sync::Arc;
13-
use crate::plumbing::IngredientIndices;
13+
use crate::plumbing::{IngredientIndices, ZalsaLocal};
1414
use crate::table::memo::MemoTableTypes;
1515
use crate::zalsa::{IngredientIndex, Zalsa};
1616
use crate::{Database, Id, Revision};
@@ -62,11 +62,7 @@ pub struct IngredientImpl<A: Accumulator> {
6262

6363
impl<A: Accumulator> IngredientImpl<A> {
6464
/// Find the accumulator ingredient for `A` in the database, if any.
65-
pub fn from_db<Db>(db: &Db) -> Option<&Self>
66-
where
67-
Db: ?Sized + Database,
68-
{
69-
let zalsa = db.zalsa();
65+
pub fn from_zalsa(zalsa: &Zalsa) -> Option<&Self> {
7066
let index = zalsa.add_or_lookup_jar_by_type::<JarImpl<A>>();
7167
let ingredient = zalsa.lookup_ingredient(index).assert_type::<Self>();
7268
Some(ingredient)
@@ -79,8 +75,7 @@ impl<A: Accumulator> IngredientImpl<A> {
7975
}
8076
}
8177

82-
pub fn push(&self, db: &dyn Database, value: A) {
83-
let zalsa_local = db.zalsa_local();
78+
pub fn push(&self, zalsa_local: &ZalsaLocal, value: A) {
8479
if let Err(()) = zalsa_local.accumulate(self.index, value) {
8580
panic!("cannot accumulate values outside of an active tracked function");
8681
}

src/database.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,11 @@ use std::any::Any;
22
use std::borrow::Cow;
33

44
use crate::zalsa::{IngredientIndex, ZalsaDatabase};
5-
use crate::{Durability, Event, Revision};
5+
use crate::{Durability, Revision};
66

77
/// The trait implemented by all Salsa databases.
88
/// You can create your own subtraits of this trait using the `#[salsa::db]`(`crate::db`) procedural macro.
99
pub trait Database: Send + AsDynDatabase + Any + ZalsaDatabase {
10-
/// This function is invoked by the salsa runtime at various points during execution.
11-
/// You can customize what happens by implementing the [`UserData`][] trait.
12-
/// By default, the event is logged at level debug using tracing facade.
13-
///
14-
/// # Parameters
15-
///
16-
/// * `event`, a fn that, if called, will create the event that occurred
17-
fn salsa_event(&self, event: &dyn Fn() -> Event);
18-
1910
/// Enforces current LRU limits, evicting entries if necessary.
2011
///
2112
/// **WARNING:** Just like an ordinary write, this method triggers
@@ -24,7 +15,6 @@ pub trait Database: Send + AsDynDatabase + Any + ZalsaDatabase {
2415
/// is owned by the current thread, this could trigger deadlock.
2516
fn trigger_lru_eviction(&mut self) {
2617
let zalsa_mut = self.zalsa_mut();
27-
zalsa_mut.runtime_mut().reset_cancellation_flag();
2818
zalsa_mut.evict_lru();
2919
}
3020

@@ -77,7 +67,8 @@ pub trait Database: Send + AsDynDatabase + Any + ZalsaDatabase {
7767
/// `salsa_event` is emitted when this method is called, so that should be
7868
/// used instead.
7969
fn unwind_if_revision_cancelled(&self) {
80-
self.zalsa().unwind_if_revision_cancelled(self);
70+
let (zalsa, zalsa_local) = self.zalsas();
71+
zalsa.unwind_if_revision_cancelled(zalsa_local);
8172
}
8273

8374
/// Execute `op` with the database in thread-local storage for debug print-outs.

src/database_impl.rs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,30 @@
1+
use tracing::Level;
2+
13
use crate::storage::HasStorage;
2-
use crate::{Database, Event, Storage};
4+
use crate::{Database, Storage};
35

46
/// Default database implementation that you can use if you don't
57
/// require any custom user data.
6-
#[derive(Default, Clone)]
8+
#[derive(Clone)]
79
pub struct DatabaseImpl {
810
storage: Storage<Self>,
911
}
1012

13+
impl Default for DatabaseImpl {
14+
fn default() -> Self {
15+
Self {
16+
// Default behavior: tracing debug log the event.
17+
storage: Storage::new(if tracing::enabled!(Level::DEBUG) {
18+
Some(Box::new(|event| {
19+
tracing::debug!("salsa_event({:?})", event)
20+
}))
21+
} else {
22+
None
23+
}),
24+
}
25+
}
26+
}
27+
1128
impl DatabaseImpl {
1229
/// Create a new database; equivalent to `Self::default`.
1330
pub fn new() -> Self {
@@ -19,13 +36,7 @@ impl DatabaseImpl {
1936
}
2037
}
2138

22-
impl Database for DatabaseImpl {
23-
/// Default behavior: tracing debug log the event.
24-
#[inline(always)]
25-
fn salsa_event(&self, event: &dyn Fn() -> Event) {
26-
tracing::debug!("salsa_event({:?})", event());
27-
}
28-
}
39+
impl Database for DatabaseImpl {}
2940

3041
// SAFETY: The `storage` and `storage_mut` fields return a reference to the same storage field owned by `self`.
3142
unsafe impl HasStorage for DatabaseImpl {

0 commit comments

Comments
 (0)