- Notifications
You must be signed in to change notification settings - Fork5.2k
Improve set_position to reuse buffer.#54991
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Improve set_position to reuse buffer.#54991
Uh oh!
There was an error while loading.Please reload this page.
Conversation
ghost commentedJul 1, 2021
Tagging subscribers to this area: @dotnet/area-system-io Issue DetailsFix#54593.
|
lateapexearlyspeed commentedJul 14, 2021
This PR is ready for review now, please review, thanks. Description:
|
jeffhandley commentedJul 23, 2021
@carlossanlop This PR is assigned to you for follow-up/decision before the RC1 snap. |
jeffhandley commentedJul 27, 2021
I'm going to merge from main, resolve the conflicts, and push to this PR's branch... |
lateapexearlyspeed commentedJul 27, 2021
Okay and thanks for resolving conflict, this PR was pending long time :) |
jeffhandley 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.
LGTM; I'll push in the (preexisting) typo fix. I'd like another reviewer to take a look before we merge it though.
src/libraries/System.Private.CoreLib/src/System/IO/BufferedStream.cs OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
jeffhandley commentedJul 29, 2021
The test failure is unrelated (as noted by@karelz). We'll just wait for an approval from@adamsitnik,@carlossanlop, or@stephentoub whenever one of them is available. The target is merging this by August 15th. Thanks for your patience,@lateapexearlyspeed. |
| // If the seek destination is still within the data currently in the buffer, we want to keep the buffer data and continue using it. | ||
| // Otherwise we will throw away the buffer. This can only happen on read, as we flushed write data above. | ||
| // The offset of the new/updated seek pointer within _buffer: | ||
| _readPos=(int)(newPos-(oldPos-_readPos)); |
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 was not aware of the fact thatSeek was capable of reusing the buffer whilePosition setter was not. Since we are very close to release of .NET 6 and I don't feel comfortable introducing any non trivial changes to the buffering logic (I am speaking from experience, as I've blocked preview 4 release with a bug in buffering logic myself:#51151) I would prefer to reuse the existingSeek logic by simply callingSeek fromPosition setter.
@lateapexearlyspeed please don't get me wrong. I am not saying that your refactor and logic changes have a bug, I just don't feel 100% comfortable merging it now.
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 would prefer to reuse the existing Seek logic by simply calling Seek from Position setter
set_Position already calls Seek; it just first zeros out some state... it's not clear to me why it does that, but it would seem the right answer here would just be to delete code from the setter:
set { if (value < 0) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.value, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);- EnsureNotClosed();- EnsureCanSeek();-- if (_writePos > 0)- FlushWrite();-- _readPos = 0;- _readLen = 0; _stream!.Seek(value, SeekOrigin.Begin); }Is that sufficient to address the issue?
adamsitnikAug 10, 2021 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
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_Position already calls Seek
it calls_stream!.Seek, while it should callthis.Seek(value, SeekOrigin.Begin) which contains the logic that we care about
runtime/src/libraries/System.Private.CoreLib/src/System/IO/BufferedStream.cs
Lines 1229 to 1244 in4566436
| // If the seek destination is still within the data currently in the buffer, we want to keep the buffer data and continue using it. | |
| // Otherwise we will throw away the buffer. This can only happen on read, as we flushed write data above. | |
| // The offset of the new/updated seek pointer within _buffer: | |
| _readPos=(int)(newPos-(oldPos-_readPos)); | |
| // If the offset of the updated seek pointer in the buffer is still legal, then we can keep using the buffer: | |
| if(0<=_readPos&&_readPos<_readLen) | |
| { | |
| // Adjust the seek pointer of the underlying stream to reflect the amount of useful bytes in the read buffer: | |
| _stream.Seek(_readLen-_readPos,SeekOrigin.Current); | |
| } | |
| else | |
| {// The offset of the updated seek pointer is not a legal offset. Loose the buffer. | |
| _readPos=_readLen=0; | |
| } |
stephentoubAug 10, 2021 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
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 calls _stream!.Seek, while it should call this.Seek(value, SeekOrigin.Begin) which contains the logic that we care about
Ah, I missed the_stream. part. Then yeah, that last line should change as well.
set { if (value < 0) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.value, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);- EnsureNotClosed();- EnsureCanSeek();-- if (_writePos > 0)- FlushWrite();-- _readPos = 0;- _readLen = 0;- _stream!.Seek(value, SeekOrigin.Begin);+ Seek(value, SeekOrigin.Begin); }…issue-54593-ImproveSetPositionToReuseBuffer
adamsitnik 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've applied the suggestion I had in order to merge it before we snap for RC1. Once again thank you@lateapexearlyspeed !
ghost commentedAug 11, 2021
Hello@adamsitnik! Because this pull request has the p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me ( |
Fix#54593.
Main purpose is to try to keep buffer valid as possible so that buffer data can still be used after set_position within range [beginBufferPosMapToUnderlyingStream, underlyingStream.Position)