-
Notifications
You must be signed in to change notification settings - Fork 28
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
Zero-copy usage #51
Comments
There is no support for this today, but it would be a nice addition. Today, BufferCursor thread local reusable buffer that will be copied by LMDB when written. I can imagine this buffer to be the MDB_RESERVE buffer instead, which would save that last copy. And yes, the the database would need to be writable. I think we can make it safe :-) |
First stab. I'll take a closer look at BufferCursor also. |
I'm a bit cautious about making MDB_RESERVE the default for all write operations on BufferCursor. Dynamic buffer expansion is handy when the size of the value is unknown, i.e. you won't waste space in the database. One way forward could be two different types of BufferCursors. Or force users to either I would like some feedback on how we should proceed. |
My use case is blocks of a known equal size - so there is no problem with allocations. |
@slaunay Do you have an opinion on this? |
I think that I am actually wondering if people using that feature would not already manage their own That being said, I'm curious to see the improvement of running zero copy write for values in my application. |
Yeah, I took a stab at making something intuitive but it felt confusing to mix BufferCursor with reserve in the end. So I agree that the complexity might not be worth it. Unless of course someone else has a good idea of how to implement it. |
Hello First more practical one - |
Have a look at this commit which returns a DirectBuffer for the reserved space in the Database. I'm not sure I follow what you're proposing? Are we still talking about BufferCursor, or MDB_RESERVE in general? Can you please elaborate? |
I'm sorry for confusing you. I had a misconception of LMDB, it's better thought out than I could imagine. All hail Howard Chu. I see confusing part of LMDB documentation "MDB_CURRENT - replace the item at the current cursor position. The key parameter must still be provided, and must match it. If using sorted duplicates (MDB_DUPSORT) the data item must still sort into the same place. This is intended to be used when the new data is the same size as the old. Otherwise it will simply perform a delete of the old record followed by an insert." I've asked Howard Chu and waiting for his answer, but currently I assume that LMDB is copy-on-write B-Tree and update-in-place cannot be enabled by any options except MDB_WRITEMAP - thus there should be no problem with updates via MDB_RESERVE. Update in place might easily cause data loss, avoiding which is one of the points of LMDB as far as I understand. My current understanding of LMDB is that every write transaction creates new ROOT_NODE that replaces old node after all the changes of this transaction were written into MMAP. So if it fails to do so - we will only see old ROOT_NODE and from that point in time pages written by failed transaction are not dirty - but free. So I think we can make every put zero copy, we don't need BufferCursor for it (But as far as I understand ordered writes/updates are better - because they require less B-Tree traversal). I've got myself local copy of lmdbjni sources - I've tried loading it with profiles win64 and full and for some reason tests cannot be initialized - "Please build lmdbjni first with a platform specific profile". Which of course I've already done. |
I'm pretty sure Howard knows what he's doing, so i'm not going to comment :-)
Great, sounds inline with our earlier conclusion.
Do we need another interface? The
Building for windows is a bit tricky. There are instructions on the wiki. Let me know if following the instruction doesn't work. |
Response from Howard - Nothing is updated in place. That reserve method is just fine 👍
|
There's already a
The disadvantage is that you must know size of value beforehand or risk wasting space in the database.
ByteBuffer is only used to allocate memory and not exposed directly in the BufferCursor API - even tough you can access it from
I'll have another look at BufferCursor. |
Hello, how do I allocate memory (DirectBuffer for example) inside of LMDB's MMap file ? Preferably safely :-) As I understand using bufferCursor implies copying data to the map. I assume this requires setting LMDB mmap as writable - is it going to make it non-reliable ?
The text was updated successfully, but these errors were encountered: