-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Size snapshot #46340
Size snapshot #46340
Conversation
r? @aidanhs (rust_highfive has picked a reviewer for you, use r? to override) |
As mentioned in #45928, a file could grow after its size was obtained and before the final read. |
If the file grows after its size is obtained, it's already a race whether |
r? @sfackler |
Except for slightly different implementation strategy this is mostly the same as #45928. Both should be discussed together. |
ping @sfackler for review! Also pinging on IRC |
Oh, also @sunfishcode I see there are merge conflicts to resolve. I'll keep this as to-review though since it sounds like this may be a multipart discussion. |
…apshot In the case of reading a normal file, this creates a buffer of the desired size up front so it avoids over-allocation and re-allocation. It adds an fstat syscall, but in the case of reading a normal file, this eliminates the final 0-byte read syscall at the end. This also changes the default read size pattern from 32,64,128,256,... to 32,32,64,128,... so that default allocation sizes and file reads are aligned at power-of-two boundaries.
b88c1c9
to
5123b23
Compare
Merge conflicts now resolved. |
I'm going to make an executive decision and mark this and #45928 as waiting on a team decision as it seems that they cannot both exist together. Let me know if you disagree. |
The @rust-lang/libs team talked about this and #45928 during our triage meeting and decided that we're not looking to expand the surface area of |
Pre-allocate in fs::read and fs::read_string This is a simpler alternative to rust-lang#46340 and rust-lang#45928, as requested by the libs team.
Pre-allocate in fs::read and fs::read_string This is a simpler alternative to rust-lang#46340 and rust-lang#45928, as requested by the libs team.
Pre-allocate in fs::read and fs::read_string This is a simpler alternative to rust-lang#46340 and rust-lang#45928, as requested by the libs team.
This introduces
Read::size_snapshot()
and it modifiesread_to_end
to allocate exactly the number of required bytes up front, and read exactly the number of bytes at once, when possible.size_snapshot()
is not treated as a hint. In the common case, this allows it to do a single read syscall (compared to two in #45928, with the second one to confirm that EOF is reached), which roughly makes up for doing an extra syscall to get the size, and to request exactly the right size buffer (compared to requesting the size + 1 in #45928).The main downside of this patch compared to #45928 is that it is possible to observe subtle behavior differences due to obtaining the size up front rather than waiting until read returns 0 in some specialized cases. That said, they all involve
read_to_end
racing with some independent writer, and the new consequences are just thatread_to_end
might return more of the old data than it should, or less of the new data than it should, if one knows enough about the underlying OS to reason about what "should" be possible.This patch also depends on
metadata()
being reliable and not memoized. On OS's I'm familiar with it's reliable (when the size isn't 0). And in the current codebase, it's not memoized.EDITED: #45928 now requests
size_hint + 1
bytes, fixing the main performance difference.