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

Missing support for MDB_RESERVE in lmdb::dbi::put #16

Open
Julianiolo opened this issue Nov 3, 2024 · 2 comments
Open

Missing support for MDB_RESERVE in lmdb::dbi::put #16

Julianiolo opened this issue Nov 3, 2024 · 2 comments

Comments

@Julianiolo
Copy link

mdb_put supports the MDB_RESERVE flag which allows a user to insert a value without any actual data. The function then returns the space for the user to write to via the data parameter. (see).

lmdb::dbi::put however uses a std::string_view data for its data parameter, so the allocated space cannot be handed back to the user. (so this is also an API problem)

I'm not sure on how this should be handled, as changing it to std::string_view& data would certainly break code? Maybe an extra method or overload would be good?

@hoytech
Copy link
Owner

hoytech commented Nov 4, 2024

Good point! None of my applications use MDB_RESERVE so I haven't had a need to solve this yet.

I think I would favour being explicit about this and adding a new method, but I haven't thought about it much yet. Pull requests welcome!

@jbosboom
Copy link

In my vendored copy of this library, I split put into two, one with the current code taking string_view&& and one with string_view& that fills in the view for MDB_RESERVE (and/or MDB_NOOVERWRITE). Then to reserve, you pass a view of nullptr and the desired size, cast away const from data(), and write. The cast is safe as the pointed-to memory is writable, but creating a string_view of nullptr and non-zero size is undefined behavior. I think this is the "allow library implementations to include debug code" kind of undefined behavior, not the "enables optimizations" kind, and the code does currently work, but best not to rely on it.

Given that you pretty much can't touch the database between reserving and writing, maybe put_reserve should accept a lambda/function_view that accepts a std::span<char*> pointing to the reserved space (avoiding the need to cast away const). But then put_reserve would take a key view, a requested size, a view out-param to support MDB_NOOVERWRITE when the key is present, and a callable. Maybe returning a pair<string_view, bool> like the various map insertions, where the view is always valid and the bool indicates whether it's the data we wrote or if no write took place.

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

3 participants