File: accumulate-reuse.rs

package info (click to toggle)
rust-salsa 0.23.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,424 kB
  • sloc: sh: 12; makefile: 2; javascript: 1
file content (65 lines) | stat: -rw-r--r-- 1,881 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//! Accumulator re-use test.
//!
//! Tests behavior when a query's only inputs
//! are the accumulated values from another query.

mod common;
use common::{LogDatabase, LoggerDatabase};
use expect_test::expect;
use salsa::{Accumulator, Setter};
use test_log::test;

#[salsa::input(debug)]
struct List {
    value: u32,
    next: Option<List>,
}

#[salsa::accumulator]
struct Integers(u32);

#[salsa::tracked]
fn compute(db: &dyn LogDatabase, input: List) -> u32 {
    db.push_log(format!("compute({input:?})",));

    // always pushes 0
    Integers(0).accumulate(db);

    let result = if let Some(next) = input.next(db) {
        let next_integers = compute::accumulated::<Integers>(db, next);
        let v = input.value(db) + next_integers.iter().map(|i| i.0).sum::<u32>();
        v
    } else {
        input.value(db)
    };

    // return value changes
    result
}

#[test]
fn test1() {
    let mut db = LoggerDatabase::default();

    let l1 = List::new(&db, 1, None);
    let l2 = List::new(&db, 2, Some(l1));

    assert_eq!(compute(&db, l2), 2);
    db.assert_logs(expect![[r#"
        [
            "compute(List { [salsa id]: Id(1), value: 2, next: Some(List { [salsa id]: Id(0), value: 1, next: None }) })",
            "compute(List { [salsa id]: Id(0), value: 1, next: None })",
        ]"#]]);

    // When we mutate `l1`, we should re-execute `compute` for `l1`,
    // but we should not have to re-execute `compute` for `l2`.
    // The only input for `compute(l1)` is the accumulated values from `l1`,
    // which have not changed.
    l1.set_value(&mut db).to(2);
    assert_eq!(compute(&db, l2), 2);
    db.assert_logs(expect![[r#"
        [
            "compute(List { [salsa id]: Id(1), value: 2, next: Some(List { [salsa id]: Id(0), value: 2, next: None }) })",
            "compute(List { [salsa id]: Id(0), value: 2, next: None })",
        ]"#]]);
}