Skip to content
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

A single lifetime parameter in BumpVec #2

Closed
CeleritasCelery opened this issue Mar 27, 2024 · 8 comments
Closed

A single lifetime parameter in BumpVec #2

CeleritasCelery opened this issue Mar 27, 2024 · 8 comments

Comments

@CeleritasCelery
Copy link

CeleritasCelery commented Mar 27, 2024

I have not delved into it too deeply, but it seems like it should be possible to only have one lifetime parameter for BumpVec (and by extension BumpString). This is similar to bumpalo Vec. The lifetime is there to ensure that it either does not outlive the Bump or the BumpScopeGuard, depending on if the scope is present. It seems like a single lifetime could serve both purposes. However just changing BumpVec to this:

    fixed: FixedBumpVec<'a, T>,
    pub(crate) bump: &'a mut BumpScope<'a, A, MIN_ALIGN, UP>,

Would make it invariant over 'a, which is probably not desirable.

@bluurryy
Copy link
Owner

I think this would prevent code like this:

let slice = bump_vec![in bump; 1, 2, 3].into_slice();
let foo = bump.alloc_str("whatever");

I we had just the one lifetime, slice would mutably borrow the bump and as such not allow allocations while it is live.

@bluurryy
Copy link
Owner

BumpVec is a bit more special than a Vec in the sense that it mutably borrows the BumpScope. This makes it so it can use the entire remaining chunk capacity as its own and not touch the bump pointer unless it is turned to a slice.

The idea is that you can push items to a BumpVec and then turn it to a slice and continue doing other bump allocations. If BumpVec were just immutably borrowed the two lifetimes would not be as useful, but would still mean that the returned slice lives as long as the BumpScopeGuard instead of just as long as the BumpScope.

@CeleritasCelery
Copy link
Author

Interesting. So if BumpVec mutably borrows the Bump is it possible to create a Vector of Strings allocated in the Bump (using this crates types that would be BumpBox<[BumpBox<str>]>)?

@bluurryy
Copy link
Owner

bluurryy commented Mar 28, 2024

Generally not with BumpVec. You can use Vec for that.

use bump_scope::{ Bump, allocator_api2::vec::Vec };

let bump: Bump = Bump::new();
let mut vec: Vec<&str, _> = Vec::new_in(&bump);

for _ in 0..10 {
    let string = bump.alloc_str("hello").into_ref();
    vec.push(string);
}

dbg!(&vec);

BumpVec is more like a niche tool when you happen to have a &mut Bump.
I feel like it should probably be named MutBumpVec or something and we should have a new type BumpVec that immutably borrows the bump (#3). A plain Vec can't be turned into a BumpBox<[T]> or &[T]. With that new type we could do so.

Edit: code example works now

@CeleritasCelery
Copy link
Author

What advantage does BumpVec provide that you wouldn’t get from just using the realloc trick? That would still let you grow to use the entire chunk capacity without copying, but doesn’t require exclusive access.

@bluurryy
Copy link
Owner

Its just that the capacity is initialized with the space left in the chunk. So you get less realloc calls.

@CeleritasCelery
Copy link
Author

CeleritasCelery commented Mar 28, 2024

Interesting. I wonder if the difference would be observable in benchmarks. I didn't realize that BumpVec and BumpString were intended to be so niche.

@CeleritasCelery
Copy link
Author

CeleritasCelery commented Mar 28, 2024

Another thing to consider is that you could get the exact same property (capacity is initialized with the space left in the chunk) like this:

use bump_scope::allocator_api2::Vec;
Vec::with_capacity_in(bump.stats().remaining()/size_of::<T>(), bump)

But without the need of a separate type that requires exclusive access.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants