-
Notifications
You must be signed in to change notification settings - Fork 84
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
Add compact() and optimize recreate_vacant_list() #60
Conversation
The Re: the What do you think? Maybe we should split the two features into separate PRs to avoid holding up |
An iterator that produces Supporting canceling moves with an iterator interface also isn't straightforward: You can cherry-pick the I'll change the closure to return |
Why an My first iterator attempt didn't compile because references produced by an iterator must be valid for the entire lifetime of the iterator.
Your comment gave me the idea of delaying moves until The iterator cannot use Swapping What we need is an iterator that does the opposite of When I mentioned allocating in the previous comment I was thinking that moving all values to a new vector would allow the iterator to use |
Updated documentation to reflect returning I've actually gotten an As calling this is not something one will do in many places, I don't think ergonomics is important, and I would rather have the closure version which supports more scenarios. |
@tormol Ok, thanks for doing the exploration. Your reasoning for why an iterator is not possible makes sense. I am 👍 on the change, it just needs to be rebased & the merge conflict sorted out. |
(Rebased) |
The first commit makes
shrink_to_fit()
remove any vacant entries after the last occupied one,so that the
Vec
can shrink below the maximum size of the slab.This usually requires iterating through all remaining entries afterwards to repair the vacant list, which takes O(n) time. I think this is acceptable as shrinking the allocation might involve copying all elements, so callers must already be prepared for that.
(Fixes #38)
The second commit adds a
.compact()
method which moves elements before shrinking.It takes an
|element, old_key, new_key|->Result
closure which is called before moving an element.This is designed for use with mio's
reregister()
and supports aborting if changing the key for one value.The proposed API isn't particularly ergonomic, as it requires explicitly specifying an error type for the closure if it never returns
Err
.I initially tried to implement this with an iterator interface, but that is not possible since returned references must be valid for the lifetime of the iterator.
Because
.remove()
re-inserts vacant entries before panicking, I've made sure that the vacant list is repaired if the closure unwinds. Dropping that requirement would simplify the code quite a bit though.