mirror of
https://github.com/salsa-rs/salsa.git
synced 2025-01-22 12:56:33 +00:00
Merge pull request #636 from Veykril/veykril/push-accumulated
Shrink `QueryRevisions` size by 3 words
This commit is contained in:
commit
e4d65a656f
15 changed files with 71 additions and 98 deletions
|
@ -8,7 +8,6 @@ use std::{
|
||||||
|
|
||||||
use accumulated::Accumulated;
|
use accumulated::Accumulated;
|
||||||
use accumulated::AnyAccumulated;
|
use accumulated::AnyAccumulated;
|
||||||
use accumulated_map::AccumulatedMap;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
cycle::CycleRecoveryStrategy,
|
cycle::CycleRecoveryStrategy,
|
||||||
|
@ -144,10 +143,6 @@ impl<A: Accumulator> Ingredient for IngredientImpl<A> {
|
||||||
fn debug_name(&self) -> &'static str {
|
fn debug_name(&self) -> &'static str {
|
||||||
A::DEBUG_NAME
|
A::DEBUG_NAME
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accumulated(&self, _db: &dyn Database, _key_index: Id) -> Option<&AccumulatedMap> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A> std::fmt::Debug for IngredientImpl<A>
|
impl<A> std::fmt::Debug for IngredientImpl<A>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::ops;
|
||||||
|
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use crate::IngredientIndex;
|
use crate::IngredientIndex;
|
||||||
|
@ -7,10 +9,6 @@ use super::{accumulated::Accumulated, Accumulator, AnyAccumulated};
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct AccumulatedMap {
|
pub struct AccumulatedMap {
|
||||||
map: FxHashMap<IngredientIndex, Box<dyn AnyAccumulated>>,
|
map: FxHashMap<IngredientIndex, Box<dyn AnyAccumulated>>,
|
||||||
|
|
||||||
/// [`InputAccumulatedValues::Empty`] if any input read during the query's execution
|
|
||||||
/// has any direct or indirect accumulated values.
|
|
||||||
inputs: InputAccumulatedValues,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AccumulatedMap {
|
impl AccumulatedMap {
|
||||||
|
@ -21,21 +19,6 @@ impl AccumulatedMap {
|
||||||
.accumulate(value);
|
.accumulate(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds the accumulated state of an input to this accumulated map.
|
|
||||||
pub(crate) fn add_input(&mut self, input: InputAccumulatedValues) {
|
|
||||||
if input.is_any() {
|
|
||||||
self.inputs = InputAccumulatedValues::Any;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns whether an input of the associated query has any accumulated values.
|
|
||||||
///
|
|
||||||
/// Note: Use [`InputAccumulatedValues::from_map`] to check if the associated query itself
|
|
||||||
/// or any of its inputs has accumulated values.
|
|
||||||
pub(crate) fn inputs(&self) -> InputAccumulatedValues {
|
|
||||||
self.inputs
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn extend_with_accumulated<A: Accumulator>(
|
pub fn extend_with_accumulated<A: Accumulator>(
|
||||||
&self,
|
&self,
|
||||||
index: IngredientIndex,
|
index: IngredientIndex,
|
||||||
|
@ -50,6 +33,10 @@ impl AccumulatedMap {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.extend_with_accumulated(output);
|
.extend_with_accumulated(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.map.is_empty()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for AccumulatedMap {
|
impl Clone for AccumulatedMap {
|
||||||
|
@ -60,7 +47,6 @@ impl Clone for AccumulatedMap {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(&key, value)| (key, value.cloned()))
|
.map(|(&key, value)| (key, value.cloned()))
|
||||||
.collect(),
|
.collect(),
|
||||||
inputs: self.inputs,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,7 +56,7 @@ impl Clone for AccumulatedMap {
|
||||||
/// Knowning whether any input has accumulated values makes aggregating the accumulated values
|
/// Knowning whether any input has accumulated values makes aggregating the accumulated values
|
||||||
/// cheaper because we can skip over entire subtrees.
|
/// cheaper because we can skip over entire subtrees.
|
||||||
#[derive(Copy, Clone, Debug, Default)]
|
#[derive(Copy, Clone, Debug, Default)]
|
||||||
pub(crate) enum InputAccumulatedValues {
|
pub enum InputAccumulatedValues {
|
||||||
/// The query nor any of its inputs have any accumulated values.
|
/// The query nor any of its inputs have any accumulated values.
|
||||||
#[default]
|
#[default]
|
||||||
Empty,
|
Empty,
|
||||||
|
@ -80,14 +66,6 @@ pub(crate) enum InputAccumulatedValues {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputAccumulatedValues {
|
impl InputAccumulatedValues {
|
||||||
pub(crate) fn from_map(accumulated: &AccumulatedMap) -> Self {
|
|
||||||
if accumulated.map.is_empty() {
|
|
||||||
accumulated.inputs
|
|
||||||
} else {
|
|
||||||
Self::Any
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) const fn is_any(self) -> bool {
|
pub(crate) const fn is_any(self) -> bool {
|
||||||
matches!(self, Self::Any)
|
matches!(self, Self::Any)
|
||||||
}
|
}
|
||||||
|
@ -96,3 +74,11 @@ impl InputAccumulatedValues {
|
||||||
matches!(self, Self::Empty)
|
matches!(self, Self::Empty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ops::BitOrAssign for InputAccumulatedValues {
|
||||||
|
fn bitor_assign(&mut self, rhs: Self) {
|
||||||
|
if rhs.is_any() {
|
||||||
|
*self = Self::Any;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::ops::Not;
|
||||||
|
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use super::zalsa_local::{QueryEdges, QueryOrigin, QueryRevisions};
|
use super::zalsa_local::{QueryEdges, QueryOrigin, QueryRevisions};
|
||||||
|
@ -55,6 +57,10 @@ pub(crate) struct ActiveQuery {
|
||||||
/// Stores the values accumulated to the given ingredient.
|
/// Stores the values accumulated to the given ingredient.
|
||||||
/// The type of accumulated value is erased but known to the ingredient.
|
/// The type of accumulated value is erased but known to the ingredient.
|
||||||
pub(crate) accumulated: AccumulatedMap,
|
pub(crate) accumulated: AccumulatedMap,
|
||||||
|
|
||||||
|
/// [`InputAccumulatedValues::Empty`] if any input read during the query's execution
|
||||||
|
/// has any accumulated values.
|
||||||
|
pub(super) accumulated_inputs: InputAccumulatedValues,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ActiveQuery {
|
impl ActiveQuery {
|
||||||
|
@ -69,6 +75,7 @@ impl ActiveQuery {
|
||||||
disambiguator_map: Default::default(),
|
disambiguator_map: Default::default(),
|
||||||
tracked_struct_ids: Default::default(),
|
tracked_struct_ids: Default::default(),
|
||||||
accumulated: Default::default(),
|
accumulated: Default::default(),
|
||||||
|
accumulated_inputs: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +89,7 @@ impl ActiveQuery {
|
||||||
self.input_outputs.insert(QueryEdge::Input(input));
|
self.input_outputs.insert(QueryEdge::Input(input));
|
||||||
self.durability = self.durability.min(durability);
|
self.durability = self.durability.min(durability);
|
||||||
self.changed_at = self.changed_at.max(revision);
|
self.changed_at = self.changed_at.max(revision);
|
||||||
self.accumulated.add_input(accumulated);
|
self.accumulated_inputs |= accumulated;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn add_untracked_read(&mut self, changed_at: Revision) {
|
pub(super) fn add_untracked_read(&mut self, changed_at: Revision) {
|
||||||
|
@ -114,13 +121,21 @@ impl ActiveQuery {
|
||||||
} else {
|
} else {
|
||||||
QueryOrigin::Derived(edges)
|
QueryOrigin::Derived(edges)
|
||||||
};
|
};
|
||||||
|
let accumulated = self
|
||||||
|
.accumulated
|
||||||
|
.is_empty()
|
||||||
|
.not()
|
||||||
|
.then(|| Box::new(self.accumulated));
|
||||||
QueryRevisions {
|
QueryRevisions {
|
||||||
changed_at: self.changed_at,
|
changed_at: self.changed_at,
|
||||||
origin,
|
origin,
|
||||||
durability: self.durability,
|
durability: self.durability,
|
||||||
tracked_struct_ids: self.tracked_struct_ids,
|
tracked_struct_ids: self.tracked_struct_ids,
|
||||||
accumulated: self.accumulated,
|
accumulated_inputs: match &accumulated {
|
||||||
|
Some(_) => InputAccumulatedValues::Any,
|
||||||
|
None => self.accumulated_inputs,
|
||||||
|
},
|
||||||
|
accumulated,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::{any::Any, fmt, sync::Arc};
|
use std::{any::Any, fmt, sync::Arc};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
accumulator::accumulated_map::AccumulatedMap,
|
accumulator::accumulated_map::{AccumulatedMap, InputAccumulatedValues},
|
||||||
cycle::CycleRecoveryStrategy,
|
cycle::CycleRecoveryStrategy,
|
||||||
ingredient::fmt_index,
|
ingredient::fmt_index,
|
||||||
key::DatabaseKeyIndex,
|
key::DatabaseKeyIndex,
|
||||||
|
@ -242,7 +242,7 @@ where
|
||||||
&'db self,
|
&'db self,
|
||||||
db: &'db dyn Database,
|
db: &'db dyn Database,
|
||||||
key_index: Id,
|
key_index: Id,
|
||||||
) -> Option<&'db AccumulatedMap> {
|
) -> (Option<&'db AccumulatedMap>, InputAccumulatedValues) {
|
||||||
let db = db.as_view::<C::DbView>();
|
let db = db.as_view::<C::DbView>();
|
||||||
self.accumulated_map(db, key_index)
|
self.accumulated_map(db, key_index)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use super::{Configuration, IngredientImpl};
|
use super::{Configuration, IngredientImpl};
|
||||||
|
use crate::accumulator::accumulated_map::InputAccumulatedValues;
|
||||||
use crate::zalsa_local::QueryOrigin;
|
use crate::zalsa_local::QueryOrigin;
|
||||||
use crate::{
|
use crate::{
|
||||||
accumulator::{self, accumulated_map::AccumulatedMap},
|
accumulator::{self, accumulated_map::AccumulatedMap},
|
||||||
|
@ -55,13 +56,13 @@ where
|
||||||
|
|
||||||
let ingredient = zalsa.lookup_ingredient(k.ingredient_index);
|
let ingredient = zalsa.lookup_ingredient(k.ingredient_index);
|
||||||
// Extend `output` with any values accumulated by `k`.
|
// Extend `output` with any values accumulated by `k`.
|
||||||
if let Some(accumulated_map) = ingredient.accumulated(db, k.key_index) {
|
let (accumulated_map, input) = ingredient.accumulated(db, k.key_index);
|
||||||
|
if let Some(accumulated_map) = accumulated_map {
|
||||||
accumulated_map.extend_with_accumulated(accumulator.index(), &mut output);
|
accumulated_map.extend_with_accumulated(accumulator.index(), &mut output);
|
||||||
|
|
||||||
// Skip over the inputs because we know that the entire sub-graph has no accumulated values
|
|
||||||
if accumulated_map.inputs().is_empty() {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
// Skip over the inputs because we know that the entire sub-graph has no accumulated values
|
||||||
|
if input.is_empty() {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the inputs of `k` and push them onto the stack.
|
// Find the inputs of `k` and push them onto the stack.
|
||||||
|
@ -95,9 +96,12 @@ where
|
||||||
&'db self,
|
&'db self,
|
||||||
db: &'db C::DbView,
|
db: &'db C::DbView,
|
||||||
key: Id,
|
key: Id,
|
||||||
) -> Option<&'db AccumulatedMap> {
|
) -> (Option<&'db AccumulatedMap>, InputAccumulatedValues) {
|
||||||
// NEXT STEP: stash and refactor `fetch` to return an `&Memo` so we can make this work
|
// NEXT STEP: stash and refactor `fetch` to return an `&Memo` so we can make this work
|
||||||
let memo = self.refresh_memo(db, key);
|
let memo = self.refresh_memo(db, key);
|
||||||
Some(&memo.revisions.accumulated)
|
(
|
||||||
|
memo.revisions.accumulated.as_deref(),
|
||||||
|
memo.revisions.accumulated_inputs,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use super::{memo::Memo, Configuration, IngredientImpl};
|
use super::{memo::Memo, Configuration, IngredientImpl};
|
||||||
use crate::accumulator::accumulated_map::InputAccumulatedValues;
|
|
||||||
use crate::{runtime::StampedValue, zalsa::ZalsaDatabase, AsDynDatabase as _, Id};
|
use crate::{runtime::StampedValue, zalsa::ZalsaDatabase, AsDynDatabase as _, Id};
|
||||||
|
|
||||||
impl<C> IngredientImpl<C>
|
impl<C> IngredientImpl<C>
|
||||||
|
@ -25,7 +24,7 @@ where
|
||||||
self.database_key_index(id).into(),
|
self.database_key_index(id).into(),
|
||||||
durability,
|
durability,
|
||||||
changed_at,
|
changed_at,
|
||||||
InputAccumulatedValues::from_map(&memo.revisions.accumulated),
|
memo.revisions.accumulated_inputs,
|
||||||
);
|
);
|
||||||
|
|
||||||
value
|
value
|
||||||
|
|
|
@ -76,23 +76,25 @@ impl<C: Configuration> IngredientImpl<C> {
|
||||||
}
|
}
|
||||||
QueryOrigin::Derived(_) => {
|
QueryOrigin::Derived(_) => {
|
||||||
// QueryRevisions: !Clone to discourage cloning, we need it here though
|
// QueryRevisions: !Clone to discourage cloning, we need it here though
|
||||||
let QueryRevisions {
|
let &QueryRevisions {
|
||||||
changed_at,
|
changed_at,
|
||||||
durability,
|
durability,
|
||||||
origin,
|
ref origin,
|
||||||
tracked_struct_ids,
|
ref tracked_struct_ids,
|
||||||
accumulated,
|
ref accumulated,
|
||||||
|
accumulated_inputs,
|
||||||
} = &memo.revisions;
|
} = &memo.revisions;
|
||||||
// Re-assemble the memo but with the value set to `None`
|
// Re-assemble the memo but with the value set to `None`
|
||||||
Arc::new(Memo::new(
|
Arc::new(Memo::new(
|
||||||
None,
|
None,
|
||||||
memo.verified_at.load(),
|
memo.verified_at.load(),
|
||||||
QueryRevisions {
|
QueryRevisions {
|
||||||
changed_at: *changed_at,
|
changed_at,
|
||||||
durability: *durability,
|
durability,
|
||||||
origin: origin.clone(),
|
origin: origin.clone(),
|
||||||
tracked_struct_ids: tracked_struct_ids.clone(),
|
tracked_struct_ids: tracked_struct_ids.clone(),
|
||||||
accumulated: accumulated.clone(),
|
accumulated: accumulated.clone(),
|
||||||
|
accumulated_inputs,
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -115,6 +117,11 @@ pub(super) struct Memo<V> {
|
||||||
pub(super) revisions: QueryRevisions,
|
pub(super) revisions: QueryRevisions,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Memo's are stored a lot, make sure their size is doesn't randomly increase.
|
||||||
|
// #[cfg(test)]
|
||||||
|
const _: [(); std::mem::size_of::<Memo<std::num::NonZeroUsize>>()] =
|
||||||
|
[(); std::mem::size_of::<[usize; 12]>()];
|
||||||
|
|
||||||
impl<V> Memo<V> {
|
impl<V> Memo<V> {
|
||||||
pub(super) fn new(value: Option<V>, revision_now: Revision, revisions: QueryRevisions) -> Self {
|
pub(super) fn new(value: Option<V>, revision_now: Revision, revisions: QueryRevisions) -> Self {
|
||||||
Memo {
|
Memo {
|
||||||
|
|
|
@ -70,6 +70,7 @@ where
|
||||||
origin: QueryOrigin::Assigned(active_query_key),
|
origin: QueryOrigin::Assigned(active_query_key),
|
||||||
tracked_struct_ids: Default::default(),
|
tracked_struct_ids: Default::default(),
|
||||||
accumulated: Default::default(),
|
accumulated: Default::default(),
|
||||||
|
accumulated_inputs: Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(old_memo) = self.get_memo_from_table_for(zalsa, key) {
|
if let Some(old_memo) = self.get_memo_from_table_for(zalsa, key) {
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
accumulator::accumulated_map::AccumulatedMap,
|
accumulator::accumulated_map::{AccumulatedMap, InputAccumulatedValues},
|
||||||
cycle::CycleRecoveryStrategy,
|
cycle::CycleRecoveryStrategy,
|
||||||
zalsa::{IngredientIndex, MemoIngredientIndex},
|
zalsa::{IngredientIndex, MemoIngredientIndex},
|
||||||
zalsa_local::QueryOrigin,
|
zalsa_local::QueryOrigin,
|
||||||
|
@ -74,7 +74,10 @@ pub trait Ingredient: Any + std::fmt::Debug + Send + Sync {
|
||||||
&'db self,
|
&'db self,
|
||||||
db: &'db dyn Database,
|
db: &'db dyn Database,
|
||||||
key_index: Id,
|
key_index: Id,
|
||||||
) -> Option<&'db AccumulatedMap>;
|
) -> (Option<&'db AccumulatedMap>, InputAccumulatedValues) {
|
||||||
|
_ = (db, key_index);
|
||||||
|
(None, InputAccumulatedValues::Any)
|
||||||
|
}
|
||||||
|
|
||||||
/// Invoked when the value `output_key` should be marked as valid in the current revision.
|
/// Invoked when the value `output_key` should be marked as valid in the current revision.
|
||||||
/// This occurs because the value for `executor`, which generated it, was marked as valid
|
/// This occurs because the value for `executor`, which generated it, was marked as valid
|
||||||
|
|
|
@ -267,14 +267,6 @@ impl<C: Configuration> Ingredient for IngredientImpl<C> {
|
||||||
fn debug_name(&self) -> &'static str {
|
fn debug_name(&self) -> &'static str {
|
||||||
C::DEBUG_NAME
|
C::DEBUG_NAME
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accumulated<'db>(
|
|
||||||
&'db self,
|
|
||||||
_db: &'db dyn Database,
|
|
||||||
_key_index: Id,
|
|
||||||
) -> Option<&'db crate::accumulator::accumulated_map::AccumulatedMap> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: Configuration> std::fmt::Debug for IngredientImpl<C> {
|
impl<C: Configuration> std::fmt::Debug for IngredientImpl<C> {
|
||||||
|
|
|
@ -90,14 +90,6 @@ where
|
||||||
fn debug_name(&self) -> &'static str {
|
fn debug_name(&self) -> &'static str {
|
||||||
C::FIELD_DEBUG_NAMES[self.field_index]
|
C::FIELD_DEBUG_NAMES[self.field_index]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accumulated<'db>(
|
|
||||||
&'db self,
|
|
||||||
_db: &'db dyn Database,
|
|
||||||
_key_index: Id,
|
|
||||||
) -> Option<&'db crate::accumulator::accumulated_map::AccumulatedMap> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C> std::fmt::Debug for FieldIngredientImpl<C>
|
impl<C> std::fmt::Debug for FieldIngredientImpl<C>
|
||||||
|
|
|
@ -308,14 +308,6 @@ where
|
||||||
fn debug_name(&self) -> &'static str {
|
fn debug_name(&self) -> &'static str {
|
||||||
C::DEBUG_NAME
|
C::DEBUG_NAME
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accumulated<'db>(
|
|
||||||
&'db self,
|
|
||||||
_db: &'db dyn Database,
|
|
||||||
_key_index: Id,
|
|
||||||
) -> Option<&'db crate::accumulator::accumulated_map::AccumulatedMap> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C> std::fmt::Debug for IngredientImpl<C>
|
impl<C> std::fmt::Debug for IngredientImpl<C>
|
||||||
|
|
|
@ -622,14 +622,6 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_for_new_revision(&mut self) {}
|
fn reset_for_new_revision(&mut self) {}
|
||||||
|
|
||||||
fn accumulated<'db>(
|
|
||||||
&'db self,
|
|
||||||
_db: &'db dyn Database,
|
|
||||||
_key_index: Id,
|
|
||||||
) -> Option<&'db crate::accumulator::accumulated_map::AccumulatedMap> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C> std::fmt::Debug for IngredientImpl<C>
|
impl<C> std::fmt::Debug for IngredientImpl<C>
|
||||||
|
|
|
@ -111,14 +111,6 @@ where
|
||||||
fn debug_name(&self) -> &'static str {
|
fn debug_name(&self) -> &'static str {
|
||||||
C::FIELD_DEBUG_NAMES[self.field_index]
|
C::FIELD_DEBUG_NAMES[self.field_index]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accumulated<'db>(
|
|
||||||
&'db self,
|
|
||||||
_db: &'db dyn Database,
|
|
||||||
_key_index: Id,
|
|
||||||
) -> Option<&'db crate::accumulator::accumulated_map::AccumulatedMap> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C> std::fmt::Debug for FieldIngredientImpl<C>
|
impl<C> std::fmt::Debug for FieldIngredientImpl<C>
|
||||||
|
|
|
@ -337,7 +337,10 @@ pub(crate) struct QueryRevisions {
|
||||||
/// only entries that appeared in the new revision.
|
/// only entries that appeared in the new revision.
|
||||||
pub(super) tracked_struct_ids: FxHashMap<Identity, Id>,
|
pub(super) tracked_struct_ids: FxHashMap<Identity, Id>,
|
||||||
|
|
||||||
pub(super) accumulated: AccumulatedMap,
|
pub(super) accumulated: Option<Box<AccumulatedMap>>,
|
||||||
|
/// [`InputAccumulatedValues::Empty`] if any input read during the query's execution
|
||||||
|
/// has any direct or indirect accumulated values.
|
||||||
|
pub(super) accumulated_inputs: InputAccumulatedValues,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl QueryRevisions {
|
impl QueryRevisions {
|
||||||
|
|
Loading…
Reference in a new issue