make query-descriptor-set cheaply cloneable

This commit is contained in:
Niko Matsakis 2018-10-14 20:15:27 -04:00
parent 2359d8aa0c
commit 9d60b1e1cd
2 changed files with 28 additions and 27 deletions

View file

@ -673,14 +673,16 @@ where
// to have any inputs. Using `debug_assert` because // to have any inputs. Using `debug_assert` because
// this is on the fast path. // this is on the fast path.
debug_assert!(match &self.inputs { debug_assert!(match &self.inputs {
QueryDescriptorSet::Tracked(inputs) => inputs.is_empty(), QueryDescriptorSet::Constant => true,
QueryDescriptorSet::Untracked => false, _ => false,
}); });
true true
} }
ChangedAt::Revision(revision) => match &self.inputs { ChangedAt::Revision(revision) => match &self.inputs {
QueryDescriptorSet::Constant => true,
QueryDescriptorSet::Tracked(inputs) => inputs QueryDescriptorSet::Tracked(inputs) => inputs
.iter() .iter()
.all(|old_input| !old_input.maybe_changed_since(db, revision)), .all(|old_input| !old_input.maybe_changed_since(db, revision)),

View file

@ -214,7 +214,18 @@ where
local_state.query_stack.pop().unwrap() local_state.query_stack.pop().unwrap()
}; };
(StampedValue { value, changed_at }, subqueries) let query_descriptor_set = match subqueries {
None => QueryDescriptorSet::Untracked,
Some(set) => {
if set.is_empty() {
QueryDescriptorSet::Constant
} else {
QueryDescriptorSet::Tracked(Arc::new(set))
}
}
};
(StampedValue { value, changed_at }, query_descriptor_set)
} }
/// Reports that the currently active query read the result from /// Reports that the currently active query read the result from
@ -355,7 +366,7 @@ struct ActiveQuery<DB: Database> {
changed_at: ChangedAt, changed_at: ChangedAt,
/// Each subquery /// Each subquery
subqueries: QueryDescriptorSet<DB>, subqueries: Option<FxIndexSet<DB::QueryDescriptor>>,
} }
impl<DB: Database> ActiveQuery<DB> { impl<DB: Database> ActiveQuery<DB> {
@ -363,7 +374,7 @@ impl<DB: Database> ActiveQuery<DB> {
ActiveQuery { ActiveQuery {
descriptor, descriptor,
changed_at: ChangedAt::Constant(Revision::ZERO), changed_at: ChangedAt::Constant(Revision::ZERO),
subqueries: QueryDescriptorSet::default(), subqueries: Some(FxIndexSet::default()),
} }
} }
@ -374,14 +385,16 @@ impl<DB: Database> ActiveQuery<DB> {
// track the source of the value. // track the source of the value.
} }
ChangedAt::Revision(_) => { ChangedAt::Revision(_) => {
self.subqueries.insert(subquery.clone()); if let Some(set) = &mut self.subqueries {
set.insert(subquery.clone());
}
self.changed_at = self.changed_at.max(changed_at); self.changed_at = self.changed_at.max(changed_at);
} }
} }
} }
fn add_untracked_read(&mut self, changed_at: ChangedAt) { fn add_untracked_read(&mut self, changed_at: ChangedAt) {
self.subqueries.insert_untracked(); self.subqueries = None;
self.changed_at = self.changed_at.max(changed_at); self.changed_at = self.changed_at.max(changed_at);
} }
} }
@ -442,8 +455,11 @@ impl ChangedAt {
/// An insertion-order-preserving set of queries. Used to track the /// An insertion-order-preserving set of queries. Used to track the
/// inputs accessed during query execution. /// inputs accessed during query execution.
pub(crate) enum QueryDescriptorSet<DB: Database> { pub(crate) enum QueryDescriptorSet<DB: Database> {
/// No inputs:
Constant,
/// All reads were to tracked things: /// All reads were to tracked things:
Tracked(FxIndexSet<DB::QueryDescriptor>), Tracked(Arc<FxIndexSet<DB::QueryDescriptor>>),
/// Some reads to an untracked thing: /// Some reads to an untracked thing:
Untracked, Untracked,
@ -452,6 +468,7 @@ pub(crate) enum QueryDescriptorSet<DB: Database> {
impl<DB: Database> std::fmt::Debug for QueryDescriptorSet<DB> { impl<DB: Database> std::fmt::Debug for QueryDescriptorSet<DB> {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
QueryDescriptorSet::Constant => write!(fmt, "Constant"),
QueryDescriptorSet::Tracked(set) => std::fmt::Debug::fmt(set, fmt), QueryDescriptorSet::Tracked(set) => std::fmt::Debug::fmt(set, fmt),
QueryDescriptorSet::Untracked => write!(fmt, "Untracked"), QueryDescriptorSet::Untracked => write!(fmt, "Untracked"),
} }
@ -460,25 +477,7 @@ impl<DB: Database> std::fmt::Debug for QueryDescriptorSet<DB> {
impl<DB: Database> Default for QueryDescriptorSet<DB> { impl<DB: Database> Default for QueryDescriptorSet<DB> {
fn default() -> Self { fn default() -> Self {
QueryDescriptorSet::Tracked(FxIndexSet::default()) QueryDescriptorSet::Constant
}
}
impl<DB: Database> QueryDescriptorSet<DB> {
/// Add `descriptor` to the set. Returns true if `descriptor` is
/// newly added and false if `descriptor` was already a member.
fn insert(&mut self, descriptor: DB::QueryDescriptor) {
match self {
QueryDescriptorSet::Tracked(set) => {
set.insert(descriptor);
}
QueryDescriptorSet::Untracked => {}
}
}
fn insert_untracked(&mut self) {
*self = QueryDescriptorSet::Untracked;
} }
} }