mirror of
https://github.com/salsa-rs/salsa.git
synced 2025-01-23 13:10:19 +00:00
make the dep-graph not generic
Being generic over the keys made code harder to read.
This commit is contained in:
parent
da188fe609
commit
e870d02da1
2 changed files with 60 additions and 56 deletions
|
@ -470,7 +470,7 @@ struct SharedState {
|
||||||
|
|
||||||
/// The dependency graph tracks which runtimes are blocked on one
|
/// The dependency graph tracks which runtimes are blocked on one
|
||||||
/// another, waiting for queries to terminate.
|
/// another, waiting for queries to terminate.
|
||||||
dependency_graph: Mutex<DependencyGraph<DatabaseKeyIndex>>,
|
dependency_graph: Mutex<DependencyGraph>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SharedState {
|
impl SharedState {
|
||||||
|
@ -636,34 +636,3 @@ impl Drop for RevisionGuard {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn dependency_graph_path1() {
|
|
||||||
let mut graph = DependencyGraph::default();
|
|
||||||
let a = RuntimeId { counter: 0 };
|
|
||||||
let b = RuntimeId { counter: 1 };
|
|
||||||
assert!(graph.add_edge(a, 2, b, vec![1]));
|
|
||||||
// assert!(graph.add_edge(b, &1, a, vec![3, 2]));
|
|
||||||
let mut v = vec![];
|
|
||||||
graph.push_cycle_path(1, a, vec![3, 2], &mut v);
|
|
||||||
assert_eq!(v, vec![1, 2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn dependency_graph_path2() {
|
|
||||||
let mut graph = DependencyGraph::default();
|
|
||||||
let a = RuntimeId { counter: 0 };
|
|
||||||
let b = RuntimeId { counter: 1 };
|
|
||||||
let c = RuntimeId { counter: 2 };
|
|
||||||
assert!(graph.add_edge(a, 3, b, vec![1]));
|
|
||||||
assert!(graph.add_edge(b, 4, c, vec![2, 3]));
|
|
||||||
// assert!(graph.add_edge(c, &1, a, vec![5, 6, 4, 7]));
|
|
||||||
let mut v = vec![];
|
|
||||||
graph.push_cycle_path(1, a, vec![5, 6, 4, 7], &mut v);
|
|
||||||
assert_eq!(v, vec![1, 3, 4, 7]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,28 +1,24 @@
|
||||||
use crate::RuntimeId;
|
use crate::{DatabaseKeyIndex, RuntimeId};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::hash::Hash;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(super) struct DependencyGraph<K: Hash + Eq> {
|
pub(super) struct DependencyGraph {
|
||||||
/// A `(K -> V)` pair in this map indicates that the the runtime
|
/// A `(K -> V)` pair in this map indicates that the the runtime
|
||||||
/// `K` is blocked on some query executing in the runtime `V`.
|
/// `K` is blocked on some query executing in the runtime `V`.
|
||||||
/// This encodes a graph that must be acyclic (or else deadlock
|
/// This encodes a graph that must be acyclic (or else deadlock
|
||||||
/// will result).
|
/// will result).
|
||||||
edges: FxHashMap<RuntimeId, Edge<K>>,
|
edges: FxHashMap<RuntimeId, Edge>,
|
||||||
labels: FxHashMap<K, SmallVec<[RuntimeId; 4]>>,
|
labels: FxHashMap<DatabaseKeyIndex, SmallVec<[RuntimeId; 4]>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Edge<K> {
|
struct Edge {
|
||||||
id: RuntimeId,
|
id: RuntimeId,
|
||||||
path: Vec<K>,
|
path: Vec<DatabaseKeyIndex>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K> Default for DependencyGraph<K>
|
impl Default for DependencyGraph {
|
||||||
where
|
|
||||||
K: Hash + Eq,
|
|
||||||
{
|
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
DependencyGraph {
|
DependencyGraph {
|
||||||
edges: Default::default(),
|
edges: Default::default(),
|
||||||
|
@ -31,17 +27,14 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K> DependencyGraph<K>
|
impl DependencyGraph {
|
||||||
where
|
|
||||||
K: Hash + Eq + Clone,
|
|
||||||
{
|
|
||||||
/// Attempt to add an edge `from_id -> to_id` into the result graph.
|
/// Attempt to add an edge `from_id -> to_id` into the result graph.
|
||||||
pub(super) fn add_edge(
|
pub(super) fn add_edge(
|
||||||
&mut self,
|
&mut self,
|
||||||
from_id: RuntimeId,
|
from_id: RuntimeId,
|
||||||
database_key: K,
|
database_key: DatabaseKeyIndex,
|
||||||
to_id: RuntimeId,
|
to_id: RuntimeId,
|
||||||
path: impl IntoIterator<Item = K>,
|
path: impl IntoIterator<Item = DatabaseKeyIndex>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
assert_ne!(from_id, to_id);
|
assert_ne!(from_id, to_id);
|
||||||
debug_assert!(!self.edges.contains_key(&from_id));
|
debug_assert!(!self.edges.contains_key(&from_id));
|
||||||
|
@ -71,7 +64,7 @@ where
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn remove_edge(&mut self, database_key: K, to_id: RuntimeId) {
|
pub(super) fn remove_edge(&mut self, database_key: DatabaseKeyIndex, to_id: RuntimeId) {
|
||||||
let vec = self.labels.remove(&database_key).unwrap_or_default();
|
let vec = self.labels.remove(&database_key).unwrap_or_default();
|
||||||
|
|
||||||
for from_id in &vec {
|
for from_id in &vec {
|
||||||
|
@ -82,13 +75,11 @@ where
|
||||||
|
|
||||||
pub(super) fn push_cycle_path(
|
pub(super) fn push_cycle_path(
|
||||||
&self,
|
&self,
|
||||||
database_key: K,
|
database_key: DatabaseKeyIndex,
|
||||||
to: RuntimeId,
|
to: RuntimeId,
|
||||||
local_path: impl IntoIterator<Item = K>,
|
local_path: impl IntoIterator<Item = DatabaseKeyIndex>,
|
||||||
output: &mut Vec<K>,
|
output: &mut Vec<DatabaseKeyIndex>,
|
||||||
) where
|
) {
|
||||||
K: std::fmt::Debug,
|
|
||||||
{
|
|
||||||
let mut current = Some((to, std::slice::from_ref(&database_key)));
|
let mut current = Some((to, std::slice::from_ref(&database_key)));
|
||||||
let mut last = None;
|
let mut last = None;
|
||||||
let mut local_path = Some(local_path);
|
let mut local_path = Some(local_path);
|
||||||
|
@ -123,3 +114,47 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
fn dki(n: u32) -> DatabaseKeyIndex {
|
||||||
|
DatabaseKeyIndex {
|
||||||
|
group_index: 0,
|
||||||
|
query_index: 0,
|
||||||
|
key_index: n,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! dkivec {
|
||||||
|
($($n:expr),*) => {
|
||||||
|
vec![$(dki($n)),*]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn dependency_graph_path1() {
|
||||||
|
let mut graph = DependencyGraph::default();
|
||||||
|
let a = RuntimeId { counter: 0 };
|
||||||
|
let b = RuntimeId { counter: 1 };
|
||||||
|
assert!(graph.add_edge(a, dki(2), b, dkivec![1]));
|
||||||
|
let mut v = vec![];
|
||||||
|
graph.push_cycle_path(dki(1), a, dkivec![3, 2], &mut v);
|
||||||
|
assert_eq!(v, vec![dki(1), dki(2)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn dependency_graph_path2() {
|
||||||
|
let mut graph = DependencyGraph::default();
|
||||||
|
let a = RuntimeId { counter: 0 };
|
||||||
|
let b = RuntimeId { counter: 1 };
|
||||||
|
let c = RuntimeId { counter: 2 };
|
||||||
|
assert!(graph.add_edge(a, dki(3), b, dkivec![1]));
|
||||||
|
assert!(graph.add_edge(b, dki(4), c, dkivec![2, 3]));
|
||||||
|
// assert!(graph.add_edge(c, &1, a, vec![5, 6, 4, 7]));
|
||||||
|
let mut v = vec![];
|
||||||
|
graph.push_cycle_path(dki(1), a, dkivec![5, 6, 4, 7], &mut v);
|
||||||
|
assert_eq!(v, dkivec![1, 3, 4, 7]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue