-
Notifications
You must be signed in to change notification settings - Fork 264
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
Allow reclaiming the current allocation #686
base: master
Are you sure you want to change the base?
Conversation
This is a draft to get some comments on whether such an API addition would be acceptable |
This looks a lot like |
I think it is hard to know what the original capacity is, generally, as it could've been influenced by lots of hidden operations before. |
That's true, but presumably you know how much data you'll need to reserve regardless (otherwise dynamic allocation seems like the best strategy). So it doesn't particularly matter if you can reclaim the entire buffer, only if it can fit the data you're receiving. Or am I missing the point here?
Very cheap relative to what though? Based on your description in #680, your only other alternative would be to allocate anyway, right? And that's definitely expensive relative to moving bytes. If that's not the alternative, what is? |
My usecase is that I have a couple of |
rebased this on top of current master, to make it mergable again. But I am also not sure if it is deemed merge-worthy or not :) There is currently a test case failure because BytesMut::advance() changed from its documented behaviour, but if this is generally acceptable I would try to reconcile that. |
In my mind, reclaiming memory is always in service of then writing a specific amount of data so I would prefer a |
Wouldn't that just be |
|
Ah, I misunderstood. Yeah, that'd work as well for me! I will update the branch when I get a chance |
Naming nit: The name |
This fixes tokio-rs#680, where it was noted that it is hard to use BytesMut without additional allocations in some circumstances.
Implemented the suggestion, I kept the name |
/// Reclaiming the allocation cheaply is possible if the `BytesMut` is currently empty and | ||
/// there are no outstanding references through other `BytesMut`s or `Bytes` which point to the | ||
/// same underlying storage. | ||
/// | ||
/// A call to `try_reclaim` never copies inside the allocation nor allocates new storage. |
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's probably worth thinking about the behavior when it is non-empty. The reserve
method will copy data backwards only if the full capacity is at least twice the amount of data being copied (I think). What logic makes sense here?
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 guess it depends on usage patterns. For my use case, it is likely the buffer is either completely empty or more than one reference to the underlying storage still exists, therefore it doesn't make a big difference.
I guess it could make a bigger difference when you are reading a lot into a large buffer, start reading the second thing which also takes a while, then the first thing is handled and when you call try_reclaim
you either copy the large thing to the front of the buffer or reclaim tells you "couldn't reclaim", but I am not sure what you would want in that case
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.
Thinking about this further, it would mean try_reclaim
would become more expensive to call, because we wouldn't just check whether the BytesMut
is empty but also which kind it is and whether we can move bytes, before returning. I wonder if @braddunbar has an opinion?
This is based on #680, where it was noted that it is hard to use BytesMut without additional allocations in some circumstances.