inc_complete/db/
handle.rs

1use petgraph::visit::EdgeRef;
2
3use crate::{Cell, Computation, Db};
4
5/// A handle to the database during some operation.
6///
7/// This wraps calls to the Db so that any `get` calls
8/// will be automatically registered as dependencies of
9/// the current operation.
10pub struct DbHandle<'db, C: Computation> {
11    db: &'db mut Db<C>,
12    current_operation: Cell,
13}
14
15impl<'db, C: Computation> DbHandle<'db, C> {
16    pub(crate) fn new(db: &'db mut Db<C>, current_operation: Cell) -> Self {
17        // We're re-running a cell so remove any past dependencies
18        let edges = db
19            .cells
20            .edges(current_operation.index())
21            .map(|edge| edge.id())
22            .collect::<Vec<_>>();
23
24        for edge in edges {
25            db.cells.remove_edge(edge);
26        }
27        Self {
28            db,
29            current_operation,
30        }
31    }
32
33    pub fn get<Concrete: Computation>(&mut self, compute: Concrete) -> &Concrete::Output
34    where
35        C::Output: Eq,
36        C: Clone,
37    {
38        // Register the dependency
39        let dependency = self.db.get_or_insert_cell(compute);
40        self.db
41            .cells
42            .update_edge(self.current_operation.index(), dependency.index(), ());
43
44        // Fetch the current value of the dependency
45        self.db.get_with_cell::<Concrete>(dependency)
46    }
47}