* Set `validate_final` in `execute` after removing the last cycle head
* Add runaway query repro
* Add tracing
* Fix part 1
* Fix `cycle_head_kinds` to always return provisional for memos that aren't verified final (They should be validated by `validate_same_iteration` or wait for the cycle head
* Fix cycle error
* Documentation
* Fix await for queries depending on initial value
* correctly initialize queued
* Cleanup
* Short circuit if entire query runs on single thread
* Move parallel code into its own method
* Rename method, add self_key to queued
* Revert self-key changes
* Move check *after* `deep_verify_memo`
* Add a test for a cycle with changing cycle heads
* Short circuit more often
* Consider iteration in `validate_provisional`
* Only yield if all heads result in a cycle. Retry if even just one inner cycle made progress (in which case there's a probably a new memo)
* Fix hangs
* Cargo fmt
* clippy
* Fix hang if cycle initial panics
* Rename `cycle_head_kind` enable `cycle_a_t1_b_t2_fallback` shuttle test
* Cleanup
* Docs
* bug: Fix missing cycle inputs
* Pass provisional as old memo to `execute_query` during fixpoint
* Remove `provisional` from remove stale output
* Revert debug code
* Update test
* Some documentation
* Clean up tests
* Fix for direct enclosing query
* Format
* More comment fiddling
* Revert copy only outputs change
* Revert `fixpoint_initial` start revision change (worth its own PR)
* Align fixpoint handling with Derived
* Preserve cycle heads when returning fixpoint initial
* Always return changed for `Fixpoint::Initial`
* Keep returning unchanged in some cases
* Add test for untracked read on tracked struct created in previous cycle
* Initial fix
* Restrict seeding to memos from the same revision
* Reduce changes
* seed_outputs
* Cleanup test
* Add assertion
* Try
* Try merging outputs after query executed
* Assert logs from first execution
* Enable trace level logging
* Use `FxIndexSet` in `diff_outputs`
* Log more events
* Cleanup
* Append outputs only once
That is, directly set a value for all queries that have fallbacks, and ignore all other queries in the cycle.
Unlike old Salsa, we still need all cycle heads to be marked, and we still execute the queries to completion, but we throw their result.
* test for caching provisional values
* add iteration-count to cycle heads
* CycleHeads insert/extend checks iteration count match
* update iteration count in cycle heads
* all tests passing
* remove debug prints
* just walk active query stack once
* switch to tracking active cycle iterations on ZalsaLocal
* Revert "switch to tracking active cycle iterations on ZalsaLocal"
This reverts commit 4ea3d850b53a449dda7af7ceb4cc565d3a64001c.
* Revert "just walk active query stack once"
This reverts commit 2d7948612be3f411c7787829ff2db74e3a575f0c.
* make ActiveQuery::iteration_count private with accessor
* iterate active query stack in reverse
* use tracing::trace! in hot path
* try a cold annotation on validate_same_iteration
* Revert "try a cold annotation on validate_same_iteration"
This reverts commit 49ceb84bb7.
* remove table-wide dependencies
* add plumbing to reuse interned slots
* record durabilities on interned values
* appease clippy
* remove immortal interned value logic
* pass correct revision when tracking interned reads
* force new revision when resetting interned values
* avoid unnecessary calls to `Database::zalsa`
* add log events for value internment
* Only log event kind because thread id can differ between runs/computers
* cargo fmt
---------
Co-authored-by: Micha Reiser <micha@reiser.io>
Instead pass around `&Zalsa` to callers more to reduce dynamic dispatch, in most of these cases the functions are only called once so the compiler should have enough knowledge to make the extra argument passing virtually free
Change the core operation to be `refresh_memo`.
This is a nice refactoring on its own but it
will also support the refactoring of how
we manage accumulator values.
Under this design, *all* databases are a
`DatabaseImpl<U>`, where the `U` implements
`UserData` (you can use `()` if there is none).
Code would default to `&dyn salsa::Database` but
if you want to give access to the userdata, you
can define a custom database trait
`MyDatabase: salsa::Databse` so long as you
* annotate `MyDatabase` trait definition of
impls of `MyDatabase` with `#[salsa::db]`
* implement `MyDatabase` for `DatabaseImpl<U>`
where `U` is your userdata (this could be a
blanket impl, if you don't know the precise
userdata type).
The `tests/common/mod.rs` shows the pattern.
The traits are now quite simple:
* Database is the external trait
* ZalsaDatabase is the internal one, implemented
by `#[salsa::db]`. It adds two methods,
`zalsa` and `zalsa_mut`. Those give access
to our internal methods.
For now I've hidden the methods behind
`&dyn Zalsa`. This is nice and clean but it may
be worth later refactoring to a `struct Zalsa`.