Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix accumulator only accumulating direct children #524

Merged
merged 9 commits into from
Jul 22, 2024

Conversation

PhoebeSzmucer
Copy link
Contributor

I noticed that some of the accumulated values were getting dropped, and I traced it to the accumulated_by function only accumulating from direct children.

Let me know if this fix is any good - I'm quite new to Rust and this codebase, and I wasn't sure how to best implement this recursion.

Copy link

netlify bot commented Jul 20, 2024

Deploy Preview for salsa-rs canceled.

Name Link
🔨 Latest commit a85ac26
🔍 Latest deploy log https://app.netlify.com/sites/salsa-rs/deploys/669eaf3fc07f2c00085609da

Copy link
Member

@nikomatsakis nikomatsakis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Silly me. This looks like a good fix, but I have a suggested rewrite.

db,
&mut |query| accumulator.produced_by(runtime, query, &mut output),
&mut HashSet::new(),
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than this recursive function let's just inline a loop here...

    let db_key = self.database_key_index(key);
    let mut visited: FxHashSet<DatabaseKeyIndex> = std::iter::once(db_key).collect();
    let mut stack = vec![db_key];

    while let Some(k) = stack.pop() {
        accumulator.produced_by(runtime, k, &mut output);
        for each successor s {
            if visited.insert(s) {
                stack.push(s);
            }
        }
    }
}  

Reasons:

  • Overall simpler, less generics, etc
  • Adding public methods, particularly those that can be called from outside the crate, is something to do with caution
  • Using FxHashSet is better than just plain old HashSet if you don't need DOS protection -- more efficient
  • Using a vector to store the stack avoids risk of stack overflow

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah the pub was a mistake, I didn't mean to expose it outside of the crate. I'll rewrite this using your suggestion - it's much cleaner :)

One question though - I think stack will change the accumulated diagnostic order. Do we care? I could also use a queue.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I pushed a refactor. This did change the order of accumulated values in some tests - let me know if I should use a queue instead.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. Let's use a queue.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated. Let me know if there is another preferred queue struct.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or not, see my comment below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok one more try - thanks for being patient with me.

I pushed your suggestion of pushing children in reverse order onto a stack. This required me to change Iterator to DoubleEndedIterator in a few places - let me know if that's ok.

I can also go back to a recursion if you prefer that.

@nikomatsakis
Copy link
Member

Hmm. Ideally we would accumulate in execution order, I think. A queue won't really do it, that will give us a breadth-first search. I think what we want to do is to push the children onto the stack but in reverse order -- something like this. But you also have to remove the hashset insertion I think and instead do the insertion when you pop off the stack. Otherwise this case would print wrong:

A {
    B {
        D
    }
    C,
    D,
}

it would print like A, B, C, D instead of A, B, D, C.

Or you could go back to a recursive function (I wouldn't bother with the generic method, I'd just pull out a simple helper function). I think that would be fine, especially since the recursion depth is reflecting an execution that already took place. =)

Copy link
Member

@nikomatsakis nikomatsakis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it! Left a suggestion for a comment.

@PhoebeSzmucer
Copy link
Contributor Author

@nikomatsakis is the failure a flake?

@nikomatsakis
Copy link
Member

Yeah, the miri failure is #520

@nikomatsakis
Copy link
Member

I was thinking @PhoebeSzmucer that it'd be good to add a test for one of the more complex scenarios -- e.g. to test duplicates. Are you up to add something like that?

@PhoebeSzmucer
Copy link
Contributor Author

@nikomatsakis yes if be happy to add more tests.

I think there are accumulator tests that indirectly test for the lack of duplicates already (the accumulator-dag one, accumulator-execution-order one that I added here), but I can add some more.

@PhoebeSzmucer
Copy link
Contributor Author

@nikomatsakis I added one more complex test here a85ac26

@nikomatsakis nikomatsakis added this pull request to the merge queue Jul 22, 2024
@nikomatsakis
Copy link
Member

@PhoebeSzmucer nice! Approved.

Merged via the queue into salsa-rs:master with commit c8234e4 Jul 22, 2024
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants