mirror of
https://github.com/salsa-rs/salsa.git
synced 2025-02-08 21:35:47 +00:00
just cache the index
This commit is contained in:
parent
9f95b37af9
commit
bca9180e05
1 changed files with 19 additions and 16 deletions
35
src/zalsa.rs
35
src/zalsa.rs
|
@ -1,4 +1,5 @@
|
||||||
use std::any::{Any, TypeId};
|
use std::any::{Any, TypeId};
|
||||||
|
use std::marker::PhantomData;
|
||||||
use std::thread::ThreadId;
|
use std::thread::ThreadId;
|
||||||
|
|
||||||
use orx_concurrent_vec::ConcurrentVec;
|
use orx_concurrent_vec::ConcurrentVec;
|
||||||
|
@ -242,7 +243,8 @@ pub struct IngredientCache<I>
|
||||||
where
|
where
|
||||||
I: Ingredient,
|
I: Ingredient,
|
||||||
{
|
{
|
||||||
cached_data: std::sync::OnceLock<(Nonce<StorageNonce>, *const I)>,
|
cached_data: std::sync::OnceLock<(Nonce<StorageNonce>, IngredientIndex)>,
|
||||||
|
phantom: PhantomData<fn() -> I>,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<I> Sync for IngredientCache<I> where I: Ingredient + Sync {}
|
unsafe impl<I> Sync for IngredientCache<I> where I: Ingredient + Sync {}
|
||||||
|
@ -264,6 +266,7 @@ where
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
cached_data: std::sync::OnceLock::new(),
|
cached_data: std::sync::OnceLock::new(),
|
||||||
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,24 +277,24 @@ where
|
||||||
db: &'s dyn Database,
|
db: &'s dyn Database,
|
||||||
create_index: impl Fn() -> IngredientIndex,
|
create_index: impl Fn() -> IngredientIndex,
|
||||||
) -> &'s I {
|
) -> &'s I {
|
||||||
let &(nonce, ingredient) = self.cached_data.get_or_init(|| {
|
let zalsa = db.zalsa();
|
||||||
let ingredient = self.create_ingredient(db, &create_index);
|
let (nonce, index) = self.cached_data.get_or_init(|| {
|
||||||
(db.zalsa().nonce(), ingredient as *const I)
|
let index = create_index();
|
||||||
|
(zalsa.nonce(), index)
|
||||||
});
|
});
|
||||||
|
|
||||||
if db.zalsa().nonce() == nonce {
|
// FIXME: We used to cache a raw pointer to the revision but miri
|
||||||
unsafe { &*ingredient }
|
// was reporting errors because that pointer was derived from an `&`
|
||||||
|
// that is invalidated when the next revision starts with an `&mut`.
|
||||||
|
//
|
||||||
|
// We could fix it with orxfun/orx-concurrent-vec#18 or by "refreshing" the cache
|
||||||
|
// when the revision changes but just caching the index is an awful lot simpler.
|
||||||
|
|
||||||
|
if db.zalsa().nonce() == *nonce {
|
||||||
|
zalsa.lookup_ingredient(*index).assert_type::<I>()
|
||||||
} else {
|
} else {
|
||||||
self.create_ingredient(db, &create_index)
|
let index = create_index();
|
||||||
|
zalsa.lookup_ingredient(index).assert_type::<I>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_ingredient<'s>(
|
|
||||||
&self,
|
|
||||||
storage: &'s dyn Database,
|
|
||||||
create_index: &impl Fn() -> IngredientIndex,
|
|
||||||
) -> &'s I {
|
|
||||||
let index = create_index();
|
|
||||||
storage.zalsa().lookup_ingredient(index).assert_type::<I>()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue