-
Notifications
You must be signed in to change notification settings - Fork 48
Improve Revs Performance by Avoiding Repeated Tree Checkouts and Adding Version Indexing #1577
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
base: master
Are you sure you want to change the base?
Improve Revs Performance by Avoiding Repeated Tree Checkouts and Adding Version Indexing #1577
Conversation
|
@smoelius, here’s a summary of the changes I made in this PR:
|
|
Thanks, @suratkhan! I'll do my best to review this this week. |
smoelius
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left some comments below. I think they may require significant changes, so I'm going to pause here and let you reflect on them.
I really appreciate you working on this.
|
hello @smoelius, I have applied the things you mentioned in the comments. Here is a summary of what I did:
|
smoelius
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You've put a lot of work into this! Thank you for that.
I hope you can forgive me, I'm going to have to look at this a few times, just because of its complexity.
Thanks a lot for working on this!
| rust_toolchain_backup | ||
| .disable() | ||
| .with_context(|| "Could not disable `Cargo.toml` backup")?; | ||
| .with_context(|| "Could not disable `rust-toolchain` backup")?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤦 Would you mind creating a separate PR with this fix?
| } | ||
| } else { | ||
| None // Cargo.toml not found | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please rewrite this using if_chain?
Here is an example:
dylint/dylint/src/package_options/revs.rs
Lines 109 to 116 in d2876b4
| if_chain! { | |
| if let Some(prev_rev) = prev_rev; | |
| if prev_rev.version != curr_rev.version; | |
| then { | |
| self.curr_rev = Some(curr_rev); | |
| return Ok(Some(prev_rev)); | |
| } | |
| } |
dylint/src/package_options/revs.rs
Outdated
| "nightly".to_string() // Blob not found, fallback | ||
| } | ||
| } else { | ||
| "nightly".to_string() // rust-toolchain not found, fallback |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is your reason for falling back to nightly? My inclination is to fail or return an error if a toolchain channel cannot be found.
dylint/src/package_options/revs.rs
Outdated
| }; | ||
|
|
||
| // Only proceed if version was found | ||
| if let Some(version_str) = version { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would probably be better to return early.
dylint/src/package_options/revs.rs
Outdated
| .context("Failed to create revision walker")?; | ||
| revwalk.push_head().context("Failed to push HEAD")?; | ||
| revwalk | ||
| .set_sorting(Sort::TIME) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| .set_sorting(Sort::TIME) | |
| .set_sorting(Sort::TOPOLOGICAL) |
dylint/src/package_options/revs.rs
Outdated
| } | ||
| })() | ||
| .transpose() | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than implement the binary search manually, would it be possible to use Vec::binary_search or one of its variants? https://doc.rust-lang.org/std/vec/struct.Vec.html#method.binary_search
dylint/src/package_options/revs.rs
Outdated
| channel: "nightly-2022-06-30".to_owned(), | ||
| oid: Oid::from_str("0cb0f7636851f9fcc57085cf80197a2ef6db098f").unwrap(), | ||
| }, | ||
| // Add more examples if needed, ensure OIDs are correct |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am fine expanding the list of Revs used for testing, but could we keep the original ones?
dylint/src/package_options/revs.rs
Outdated
|
|
||
| // The found version might be *newer* than the example if the example OID | ||
| // is not the *exact* commit the version bumped. The search finds the | ||
| // commit where the target version *became active*. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was there a bug in the existing EXAMPLES?
| }) | ||
| .unwrap() | ||
| .unwrap(); | ||
| assert_eq!(rev, *example); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than scrap this test, could it just be rewritten to use find_version?
dylint/src/package_options/revs.rs
Outdated
| let result = revs.find_version(ancient_version).unwrap(); | ||
| // Depending on history, this might find the oldest known version or None if history starts | ||
| // later. If it finds *a* version, it should be the oldest one available. | ||
| if let Some(rev) = result { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea of having a test that finds the earliest commit find_version possibly can!
But this check is kind of weird.
From what I can tell, the earliest commit in the rust-clippy repository is this one: rust-lang/rust-clippy@3722627
This appears to be the earliest commit with a rust-toolchain file: rust-lang/rust-clippy@40151d9
And this appears to be the earliest commit with a rust-toolchain file with a modern format, e.g., a channel: rust-lang/rust-clippy@f03edfd
Would it be possible to have the test find one of those commits, or some commit close thereto, and handle it appropriately?
|
Hi @smoelius, good to see you again! I hope you're doing well. Thanks for the detailed review! I worked on this about two weeks ago, so I'll need to take another look to refresh my memory on what I did and why. Hopefully, I remember everything. I'll try my best to address the feedback and get things done within this week. In the meantime, here (#1606) is the PR that fixes the error messages. |
6ce58ad to
94d9cd7
Compare
|
Hi @smoelius, Sorry I’ve been inactive for the last couple of weeks—I was on vacation. I’ve just started back this week and made the changes you requested. After rebasing onto master and committing, I’m now seeing some new CI failures. Could you take a look and let me know whether they’re related to my changes, and if so how I should address them? Thanks! |
Sorry, @suratkhan. The answer is not immediately obvious to me. I will look at this more closely later on today. |
| } else { | ||
| return Ok(None); | ||
| } | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the problem is here. It looks like this code is reading the entire rust-toolchain file and treating it as the toolchain channel. I think rust-toolchain files used to work that way, but no longer. I recommend using the toolchain_channel function to get the toolchain channel.
|
Hi @smoelius, I tried to address the issue as you mentioned, but unfortunately it didn’t work out. I'm not very familiar with the usage of the Thank you! |
|
Sorry for not being more specific. This is the function I was referring to: dylint/internal/src/clippy_utils.rs Line 68 in 56e2dcb
You call it with the path of a Here are two examples where it is used:
|
5b2c9a7 to
3ab708c
Compare
|
Hi, @suratkhan. Are you still working on this? |
This PR solves #1559 by refactoring the
Revsimplementation to improve performance by:Revstructs from commit trees.checkout_treecalls.find_versionlookups.