mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Rollup merge of #136484 - Zalathar:query-cache-notes, r=jieyouxu
Notes on types/traits used for in-memory query caching When the word "cache" appears in the context of the query system, it often isn't obvious whether that is referring to the in-memory query cache or the on-disk incremental cache. For these types, we can assure the reader that they are for in-memory caching.
This commit is contained in:
commit
d6f94a683c
@ -206,6 +206,19 @@ impl SlotIndex {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// In-memory cache for queries whose keys are densely-numbered IDs
|
||||||
|
/// (e.g `CrateNum`, `LocalDefId`), and can therefore be used as indices
|
||||||
|
/// into a dense vector of cached values.
|
||||||
|
///
|
||||||
|
/// (As of [#124780] the underlying storage is not an actual `Vec`, but rather
|
||||||
|
/// a series of increasingly-large buckets, for improved performance when the
|
||||||
|
/// parallel frontend is using multiple threads.)
|
||||||
|
///
|
||||||
|
/// Each entry in the cache stores the query's return value (`V`), and also
|
||||||
|
/// an associated index (`I`), which in practice is a `DepNodeIndex` used for
|
||||||
|
/// query dependency tracking.
|
||||||
|
///
|
||||||
|
/// [#124780]: https://github.com/rust-lang/rust/pull/124780
|
||||||
pub struct VecCache<K: Idx, V, I> {
|
pub struct VecCache<K: Idx, V, I> {
|
||||||
// Entries per bucket:
|
// Entries per bucket:
|
||||||
// Bucket 0: 4096 2^12
|
// Bucket 0: 4096 2^12
|
||||||
|
@ -20,6 +20,12 @@ pub struct LocalCrate;
|
|||||||
/// The `Key` trait controls what types can legally be used as the key
|
/// The `Key` trait controls what types can legally be used as the key
|
||||||
/// for a query.
|
/// for a query.
|
||||||
pub trait Key: Sized {
|
pub trait Key: Sized {
|
||||||
|
/// The type of in-memory cache to use for queries with this key type.
|
||||||
|
///
|
||||||
|
/// In practice the cache type must implement [`QueryCache`], though that
|
||||||
|
/// constraint is not enforced here.
|
||||||
|
///
|
||||||
|
/// [`QueryCache`]: rustc_query_system::query::QueryCache
|
||||||
// N.B. Most of the keys down below have `type Cache<V> = DefaultCache<Self, V>;`,
|
// N.B. Most of the keys down below have `type Cache<V> = DefaultCache<Self, V>;`,
|
||||||
// it would be reasonable to use associated type defaults, to remove the duplication...
|
// it would be reasonable to use associated type defaults, to remove the duplication...
|
||||||
//
|
//
|
||||||
|
@ -11,18 +11,30 @@ use rustc_span::def_id::{DefId, DefIndex};
|
|||||||
|
|
||||||
use crate::dep_graph::DepNodeIndex;
|
use crate::dep_graph::DepNodeIndex;
|
||||||
|
|
||||||
|
/// Trait for types that serve as an in-memory cache for query results,
|
||||||
|
/// for a given key (argument) type and value (return) type.
|
||||||
|
///
|
||||||
|
/// Types implementing this trait are associated with actual key/value types
|
||||||
|
/// by the `Cache` associated type of the `rustc_middle::query::Key` trait.
|
||||||
pub trait QueryCache: Sized {
|
pub trait QueryCache: Sized {
|
||||||
type Key: Hash + Eq + Copy + Debug;
|
type Key: Hash + Eq + Copy + Debug;
|
||||||
type Value: Copy;
|
type Value: Copy;
|
||||||
|
|
||||||
/// Checks if the query is already computed and in the cache.
|
/// Returns the cached value (and other information) associated with the
|
||||||
|
/// given key, if it is present in the cache.
|
||||||
fn lookup(&self, key: &Self::Key) -> Option<(Self::Value, DepNodeIndex)>;
|
fn lookup(&self, key: &Self::Key) -> Option<(Self::Value, DepNodeIndex)>;
|
||||||
|
|
||||||
|
/// Adds a key/value entry to this cache.
|
||||||
|
///
|
||||||
|
/// Called by some part of the query system, after having obtained the
|
||||||
|
/// value by executing the query or loading a cached value from disk.
|
||||||
fn complete(&self, key: Self::Key, value: Self::Value, index: DepNodeIndex);
|
fn complete(&self, key: Self::Key, value: Self::Value, index: DepNodeIndex);
|
||||||
|
|
||||||
fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex));
|
fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// In-memory cache for queries whose keys aren't suitable for any of the
|
||||||
|
/// more specialized kinds of cache. Backed by a sharded hashmap.
|
||||||
pub struct DefaultCache<K, V> {
|
pub struct DefaultCache<K, V> {
|
||||||
cache: Sharded<FxHashMap<K, (V, DepNodeIndex)>>,
|
cache: Sharded<FxHashMap<K, (V, DepNodeIndex)>>,
|
||||||
}
|
}
|
||||||
@ -67,6 +79,8 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// In-memory cache for queries whose key type only has one value (e.g. `()`).
|
||||||
|
/// The cache therefore only needs to store one query return value.
|
||||||
pub struct SingleCache<V> {
|
pub struct SingleCache<V> {
|
||||||
cache: OnceLock<(V, DepNodeIndex)>,
|
cache: OnceLock<(V, DepNodeIndex)>,
|
||||||
}
|
}
|
||||||
@ -101,6 +115,10 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// In-memory cache for queries whose key is a [`DefId`].
|
||||||
|
///
|
||||||
|
/// Selects between one of two internal caches, depending on whether the key
|
||||||
|
/// is a local ID or foreign-crate ID.
|
||||||
pub struct DefIdCache<V> {
|
pub struct DefIdCache<V> {
|
||||||
/// Stores the local DefIds in a dense map. Local queries are much more often dense, so this is
|
/// Stores the local DefIds in a dense map. Local queries are much more often dense, so this is
|
||||||
/// a win over hashing query keys at marginal memory cost (~5% at most) compared to FxHashMap.
|
/// a win over hashing query keys at marginal memory cost (~5% at most) compared to FxHashMap.
|
||||||
|
@ -222,10 +222,10 @@ pub struct CycleError {
|
|||||||
pub cycle: Vec<QueryInfo>,
|
pub cycle: Vec<QueryInfo>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if the query is already computed and in the cache.
|
/// Checks whether there is already a value for this key in the in-memory
|
||||||
/// It returns the shard index and a lock guard to the shard,
|
/// query cache, returning that value if present.
|
||||||
/// which will be used if the query is not in the cache and we need
|
///
|
||||||
/// to compute it.
|
/// (Also performs some associated bookkeeping, if a value was found.)
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn try_get_cached<Tcx, C>(tcx: Tcx, cache: &C, key: &C::Key) -> Option<C::Value>
|
pub fn try_get_cached<Tcx, C>(tcx: Tcx, cache: &C, key: &C::Key) -> Option<C::Value>
|
||||||
where
|
where
|
||||||
|
Loading…
Reference in New Issue
Block a user