-
Notifications
You must be signed in to change notification settings - Fork 8
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
Why increase capacity to next power of 2 - 1? #5
Comments
Hi @EkardNT!
This approach was taken because it strikes a good balance between minimizing the total number of allocations required while the buffer grows to the maximum size it will assume and minimizing the amount of wasted memory. If
Admittedly this does expose implementation details to the user, and is a somewhat unsightly feature of the API. The reasoning behind not hiding this implementation detail is to reduce the memory requirements of the buffer. As far as I understand, most allocators often allocate memory in powers of 2 so if the buffer wanted to have a power of 2 capacity itself, say |
I'm not certain it's true, actually allocation require more than 1 octet of metadata, it's generally something like 24-32 octets, thus forcing a power of 2 is probably counter productive but I can't be sure. I agree double the size is a good strategy, but I don't see why force power of 2 (for example Vec doesn't do that). Having a method that allow user to only add few bytes would be a plus. Having a On a related note, the choice to have a boxed slice and a realloc feature is also counter productive this disallow any reuse of the same buffer if there was enough space available to grow the original space. |
The documentation states that the size of the circular buffer is increased to the next power of 2 above or including the provided capacity, and I've confirmed that behavior with the following test.
The test also shows the behavior of the actual available capacity being one less than the power of 2. My question is, why are both of these behaviors present?
For the first question, I thought maybe the package was using bitmasking of some form that only works on power-of-2 array lengths, but I looked through the code and wasn't able to find anything of that nature. For example,
advance_read
andadvance_write
both use modular arithmetic which would work just as well with non-power-of-2 lengths as with, as far as I can tell.For the second question, there is this explanation in the code:
[The capacity] is equal to one less than the length of the underlying buffer because we cannot let the write cursor to ever circle back to being equal with the read cursor.
That's clear enough, but I don't understand why not just increase the length of the buffer by 1 to hide this implementation detail from the user. Perhaps it is tied to the need to have power-of-2 lengths? Which leads back to the first question.The text was updated successfully, but these errors were encountered: