Fix stale tracked struct values in later iterations#1068
Conversation
✅ Deploy Preview for salsa-rs canceled.
|
|
|
||
| let result = query_a(&db); | ||
|
|
||
| assert_eq!(result, 5); |
There was a problem hiding this comment.
This always returned 1 before
CodSpeed Performance ReportMerging this PR will degrade performance by 4.1%Comparing Summary
Performance Changes
|
96c1b3e to
679c500
Compare
ibraheemdev
left a comment
There was a problem hiding this comment.
This makes sense to me, though it makes tracked structs in fixed-point a lot less useful.
Have you considered disallowing tracked structs in fixed-point entirely?
I haven't, but I think we also reached a state where tracked struct and specify work as expected, even if the caching across revisions might not be ideal, because we delete tracked structs too early. That's why I'd prefer to keep support for now unless we discover new issues. |
This PR fixes a cycle handling-related bug where
tracked fields returned stale values from previous iterations if
they share the same hash as a tracked struct created in an earlier iteration.
The root cause of this was that TrackedStruct::update skips updating
if the tracked struct was already written in this revision (which is correct).
However, this causes issues with tracked structs with tracked fields (or hash collisions)
where the tracked struct has different values between two iterations. It's crucial
that the write happens in the later iteration.
The fix here is to not only seed the tracked struct IDs but also seed the disambiguator
map, so that the two tracked structs get different IDs. They're different tracked structs after all
(cycle handling is nothing but unrolling the query ITERATION times).
The downside of this is that using tracked structs in return positions of a cyclic query
is unlikely to ever converge because each iteration creates a new tracked struct with a separate ID.
I don't see a way around this. For those instances, use interned values which erase the identity constraint.
Extracted from #1061