356: make Id::from_u32 public r=nikomatsakis a=nikomatsakis
I made it private 'just because', but it turns out that dada uses it, and it seems reasonable.
Co-authored-by: Niko Matsakis <niko@alum.mit.edu>
352: Add options to tracked funcitons for lru capacity r=nikomatsakis a=XFFXFF
fixes#344
Now we can write something like the following to set the lru capacity of tracked functions
```rust
#[salsa::tracked(lru=32)]
fn my_tracked_fn(db: &dyn crate::Db, ...) { }
```
some details:
* lru should not be combined with specify. We will report an error if people do #[salsa::tracked(lru = 32, specify)]
* set 0 as default capacity to disable LRU (Because I think doing this would make the code simpler when implementing `create_ingredients` of tracked functions).
* old salsa support to change lru capacity at runtime, [as noted here](https://salsa-rs.github.io/salsa/rfcs/RFC0004-LRU.html?highlight=change#reference-guide), but we do not support this now
Co-authored-by: XFFXFF <1247714429@qq.com>
350: Accumulators r=nikomatsakis a=nikomatsakis
This branch fixes accumulators so they have the right *behavior* -- the implementation leaves something to be desired, though, in that you don't get very good re-use if you are using accumulators from inside tracked functions. Right now that is treated as an untracked read, so if you want to get good re-use you need a workaround like this one...
```rust
#[salsa::tracked(return_ref)]
fn accumulated_values(db: &dyn Db) -> Vec<T> {
some_query::accumulated::<SomeAccumulator>(db)
}
```
...which would track and compare the new vs old vector and detect when they've changed.
Despite this limitation, this PR makes accumulators behave correctly with respect to the value taht gets returned and is good enough to Fix#313 in my opinion. I'll file an issue for the remaining improvements.
Co-authored-by: Niko Matsakis <niko@alum.mit.edu>
Accumulators don't currently work across revisions
due to a few bugs. This commit adds 2 tests to show
the problems and reworks the implementation strategy.
We keep track of when the values in an accumulator were pushed
and reset the vector to empty when the push occurs in a new
revision.
We also ignore stale values from old revisions
(but update the revision when it is marked as validated).
Finally, we treat an accumulator as an untracked read,
which is quite conservative but correct. To get better
reuse, we would need to (a) somehow determine when different
values were pushed, e.g. by hashing or tracked the old values;
and (b) have some `DatabaseKeyIndex` we can use to identify
"the values pushed by this query".
Both of these would add overhead to accumulators and I didn'τ
feel like doing it, particularly since the main use case for
them is communicating errors and things which are not typically
used from within queries.
It turns out that we have some outputs (accumulators) for which
it only makes sense to have a `DependencyIndex` (they don't have
individual keys to identify).
349: GC tracked structs r=nikomatsakis a=nikomatsakis
Extends the system to track when a tracked struct is no longer created in a new revision and eagerly delete data associated with it. It's not a *complete* answer for GC but it seems pretty useful.
Fix#315
Co-authored-by: Niko Matsakis <niko@alum.mit.edu>
We also track whether reset is required at the ingredient level.
For tracked struct fields, we were not using `push_mut`,
and I think that was an oversight.
The plan is to do a "dependent ingredient" interlinking pass
once the database is constructed.
342: Make input setters return old value r=nikomatsakis a=MihailMihov
Added an `InputFieldIngredient` which replaces the `FunctionIngredient` for inputs. The end goal is for the inputs to use an ingredient simpler than `FunctionIngredient` and that would allow us to return the old values when updating an input.
Co-authored-by: Mihail Mihov <mmihov.personal@gmail.com>
347: Track outputs and specified fields r=nikomatsakis a=nikomatsakis
This PR implements a new strategy for tracking output edges and specified fields correctly. Core ideas:
* Track the *outputs* of each query Q and not only its inputs. An output is a specified or assigned field, a created entity, or a pushed accumulator.
* When marking a query Q as validated (no need to execute) in a new revision, you mark ALL of its outputs as validated.
Fixes#338.
The PR also includes some commits that lay the groundwork for #313 and #315 (but I left those for a future PR). In particular, it includes the logic to diff outputs to find values that are no longer output by Q. This will be used to delete obsolete entities. (Originally, I was going to use this to clear outdated outputs of all kinds, but I realized that marking them as validated was a better approach.)
Co-authored-by: Niko Matsakis <niko@alum.mit.edu>
I realized I can do this better:
* require that outputs are DatabaseKeyIndex, fewer unwraps,
more clearly justified
* when we validate result of tracked fn, also validate its outputs
(this is incompletely implemented, would ideally be separated
into its own commit, but I'm short for time)
The last step will allow us to keep the memoized results for
assigned values and means we don't have to eagerly clear them.
If we see an "assigned value" that is not verified in the current
revision, it can simply be considered dirty.
We can still delete them when entities are deleted, but they're
less special.
We don't do anything with this info right now besides log it,
but the logs show we are reporting it at the right times
in the `specify_tracked_fn_in_rev_1_but_not_2` test
(also fix an oversight in the test where it was creating a new input
each time).
Rename QueryInputs to QueryEdges.
Modify its fields to track both inputs and outputs.
The size of the struct doesn't actually change,
as the separator comes out of padding.