-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
BufReader should provide a way to seek without dumping the buffer #31100
Comments
(I'm in the process of writing my own BufReader implementation that doesn't do this.) |
Currently BufReader saves only the offset within buffered data. Another variant is to make a separate function (e.g. |
I'm not trying to avoid seeking the underlying stream, I'm trying to avoid dumping the buffer. In my implementation, small seeks that fit in the existing buffer cause a call to self.inner.seek(SeekFrom::Current(0)). |
@taralx Could you please share your implementation? You use self.inner.seek(SeekFrom::Current(0)) to get current file offset. Am I correct? |
Not without getting source approval from my employer, sorry. Yes, I implement let p = try!(self.pos());
self.pos -= back;
return p - back; |
Some time ago I had a similiar requirement, I extracted the implementation into a own library: seek_bufread, maybe its useful for you. |
I stumbled upon this today. When decoding mp4 movies, the decoder will do small seeks forward to skip in the region of 100 bytes at a time. I used a BufReader with 65k capacity to avoid my underlying reader doing http requests for every seek, only to find that BufReader isn't helping at all. I think BufReader could be more useful if it worked from the buffer also when seek fits. |
I would like to see a PR that implements |
FWIW, this solution requires R:Seek. A |
This should not be closed, the new method is still unstable. It’s been a couple months though: @rfcbot fcp merge |
@SimonSapin to confirm, this is for the |
Yes, that is the one item with |
Hmm, maybe I needed to reopen the issue before making the command: @rfcbot fcp merge |
Team member @SimonSapin has proposed to merge this. The next step is review by the rest of the tagged teams: No concerns currently listed. Once a majority of reviewers approve (and none object), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
The final comment period is now complete. |
No, the major issue is one of compatibility guarantees. Right now, if you want to sync the BufReader's position with the underlying Reader and extract it, you |
Can't we just leave |
That already happened: https://doc.rust-lang.org/std/io/struct.BufReader.html#method.seek_relative |
I've been advocating for |
@taralx do you want to write up a pr? I doubt it would be very difficult. Just refactor |
I do find it mildly ironic that the original implementation explicitly documented that it would always flush the buffer and why. |
Life is a little busy right now, so if someone else is excited to do it, go for it. Otherwise I'll see if I can't find some time to put together a PR. |
@SimonSapin it seems that there was a final comment period for this in Mar 2018 that passed with no objections. Does that now mean there can be a stabilization PR? |
At least for my use-case of parsing media files I'm still relying on the |
One of the challenges I have been finding with BufReader is that the stream_position convenience method is implemented with Is it possible to have this case specialized so that getting the current position doesn't cause the buffer to be thrown away? |
I'm not entirely clear on the status of |
…rtodt Implement Seek::stream_position() for BufReader Optimization over `BufReader::seek()` for getting the current position without flushing the internal buffer. Related to rust-lang#31100. Based on the code in rust-lang#70577.
@alecmocatta someone still needs to open a PR to mark the method as stable. |
As someone unfamiliar with the processes of Rust development, is there a chance of getting this into one of the upcoming releases? |
The relevant PR passed FCP, has been approved to merge, and this should become stable in 1.53.0 if all goes well. |
…k-Simulacrum Add Seek::seek_relative The `BufReader` struct has a `seek_relative` method because its `Seek::seek` implementation involved dumping the internal buffer (rust-lang#31100). Unfortunately, there isn't really a good way to take advantage of that method in generic code. This PR adds the same method to the main `Seek` trait with the straightforward default method, and an override for `BufReader` that calls its implementation. _Also discussed in [this](https://internals.rust-lang.org/t/add-seek-seek-relative/19546) internals.rust-lang.org thread._
…k-Simulacrum Add Seek::seek_relative The `BufReader` struct has a `seek_relative` method because its `Seek::seek` implementation involved dumping the internal buffer (rust-lang#31100). Unfortunately, there isn't really a good way to take advantage of that method in generic code. This PR adds the same method to the main `Seek` trait with the straightforward default method, and an override for `BufReader` that calls its implementation. _Also discussed in [this](https://internals.rust-lang.org/t/add-seek-seek-relative/19546) internals.rust-lang.org thread._
…k-Simulacrum Add Seek::seek_relative The `BufReader` struct has a `seek_relative` method because its `Seek::seek` implementation involved dumping the internal buffer (rust-lang#31100). Unfortunately, there isn't really a good way to take advantage of that method in generic code. This PR adds the same method to the main `Seek` trait with the straightforward default method, and an override for `BufReader` that calls its implementation. _Also discussed in [this](https://internals.rust-lang.org/t/add-seek-seek-relative/19546) internals.rust-lang.org thread._
…k-Simulacrum Add Seek::seek_relative The `BufReader` struct has a `seek_relative` method because its `Seek::seek` implementation involved dumping the internal buffer (rust-lang#31100). Unfortunately, there isn't really a good way to take advantage of that method in generic code. This PR adds the same method to the main `Seek` trait with the straightforward default method, and an override for `BufReader` that calls its implementation. _Also discussed in [this](https://internals.rust-lang.org/t/add-seek-seek-relative/19546) internals.rust-lang.org thread._
Rollup merge of rust-lang#116750 - fintelia:seek_seek_relative, r=Mark-Simulacrum Add Seek::seek_relative The `BufReader` struct has a `seek_relative` method because its `Seek::seek` implementation involved dumping the internal buffer (rust-lang#31100). Unfortunately, there isn't really a good way to take advantage of that method in generic code. This PR adds the same method to the main `Seek` trait with the straightforward default method, and an override for `BufReader` that calls its implementation. _Also discussed in [this](https://internals.rust-lang.org/t/add-seek-seek-relative/19546) internals.rust-lang.org thread._
BufReader's seek() implementation always dumps the buffer. This is not good for performance, where users may want to skip a variable amount of buffered data -- only BufReader really knows if it's reasonable to move the pointer or not.
Additionally, only BufReader can know if the pointer can be reversed or not -- so there's absolutely no cheap way to "unget" data from BufReader, even if you know it's seekable.
I'd recommend removing this behavior and moving it to unwrap() or another method (sync?), but it's now baked into a stable API.
What are the options now?
The text was updated successfully, but these errors were encountered: