Skip to main content

sim_incremental_core/
query.rs

1//! Query registration wrappers.
2
3use std::sync::Arc;
4
5use crate::{FingerprintValue, IncrementalError, Observation, ObservationKind, QueryFrame};
6
7/// The result type returned by query callbacks.
8pub type QueryResult<K, V> = Result<V, IncrementalError<K>>;
9
10type QueryBody<K, V> =
11    dyn for<'a> Fn(&K, &mut QueryFrame<'a, K, V>) -> QueryResult<K, V> + Send + Sync;
12
13/// A registered query callback.
14pub struct Query<K, V> {
15    body: Arc<QueryBody<K, V>>,
16}
17
18impl<K, V> Clone for Query<K, V> {
19    fn clone(&self) -> Self {
20        Self {
21            body: Arc::clone(&self.body),
22        }
23    }
24}
25
26impl<K, V> Query<K, V> {
27    /// Wraps a query callback for registration.
28    #[must_use]
29    pub fn new<F>(body: F) -> Self
30    where
31        F: for<'a> Fn(&K, &mut QueryFrame<'a, K, V>) -> QueryResult<K, V> + Send + Sync + 'static,
32    {
33        Self {
34            body: Arc::new(body),
35        }
36    }
37
38    pub(crate) fn run<'a>(&self, key: &K, frame: &mut QueryFrame<'a, K, V>) -> QueryResult<K, V> {
39        (self.body)(key, frame)
40    }
41}
42
43impl<K, V> QueryFrame<'_, K, V>
44where
45    K: Ord + Clone,
46    V: Clone + FingerprintValue,
47{
48    /// Reads another query and records a read dependency.
49    pub fn read(&mut self, key: K) -> QueryResult<K, V> {
50        let value = self.engine.evaluate(key.clone(), self.run)?;
51        let observation = self.engine.memo_observation(&key)?;
52        self.engine
53            .record_observation(self.run, self.observations, observation)?;
54        Ok(value)
55    }
56
57    /// Records an external observation with the current source revision.
58    pub fn observe(&mut self, kind: ObservationKind, key: K) -> Result<(), IncrementalError<K>> {
59        let revision = self.engine.source_revision(&key);
60        let observation = Observation::new(key, kind, revision, None);
61        self.engine
62            .record_observation(self.run, self.observations, observation)
63    }
64
65    /// Records that a name was missing.
66    pub fn observe_missing(&mut self, key: K) -> Result<(), IncrementalError<K>> {
67        self.observe(ObservationKind::Missing, key)
68    }
69
70    /// Records that a listing was inspected.
71    pub fn observe_listing(&mut self, key: K) -> Result<(), IncrementalError<K>> {
72        self.observe(ObservationKind::Listing, key)
73    }
74
75    /// Records that policy or authority state was inspected.
76    pub fn observe_policy(&mut self, key: K) -> Result<(), IncrementalError<K>> {
77        self.observe(ObservationKind::Policy, key)
78    }
79
80    /// Records that an external backend epoch was inspected.
81    pub fn observe_epoch(&mut self, key: K) -> Result<(), IncrementalError<K>> {
82        self.observe(ObservationKind::Epoch, key)
83    }
84
85    /// Charges additional user-defined work units.
86    pub fn charge_work(&mut self, units: usize) -> Result<(), IncrementalError<K>> {
87        let key = self.run.root.clone();
88        self.engine.charge_work(self.run, &key, units)
89    }
90
91    /// Charges additional user-defined output units.
92    pub fn charge_output(&mut self, units: usize) -> Result<(), IncrementalError<K>> {
93        let key = self.run.root.clone();
94        self.engine.charge_output(self.run, &key, units)
95    }
96
97    /// Requests cancellation of the current verification run.
98    pub fn cancel(&mut self) {
99        self.run.cancelled = true;
100    }
101
102    /// Returns whether cancellation has been requested.
103    #[must_use]
104    pub fn cancellation_requested(&self) -> bool {
105        self.run.cancelled
106    }
107}