Closed NicolasT closed 9 years ago
Thinking about it, not all changes from ad4deef are safe: notably the ones on iter aren't (keys & values yielded by an iter are only safe until the next iter modification). For get
, things should still be OK thought. For comparators and alike, I assume one isn't supposed to keep given strings across invocations.
Somehow I switched to 'unsafeUseAsCStringLen' for writes and then forgot about this PR.
I did not add zero-copy ByteString
s when handing out values, as this seems unsafe. You think this PR can be closed, then?
Closing due to bitrot. @NicolasT feel free to reopen
Hi,
This is mainly a request-for-comments & check whether there's any interest in this, not a real pull request (for now).
Currently the library uses
packCStringLen
to turn strings returned from the LevelDB API intoByteString
. This is an O(n) operation in the length of the string (it results in amemcpy
of the string from C heap into Haskell's GC'ed heap).This can have quite some impact when dealing with large values.
I noticed the library uses
unsafeUseAsCStringLen
to passByteString
values to the LevelDB procedures, which doesn't incur any copying, so thought it'd make sense to do the reverse as well.I think this has one drawback: the values won't show up in memory statistics & profiling, since they're outside the Haskell-managed heap.
I chose to implement the change as contained in this 69c6ff93894 instead of using
Data.ByteString.Unsafe.unsafePackCStringFinalizer
, since the latter usesForeign.Concurrent.newForeignPtr
to create aForeignPtr
, and its documentation says:(emphasis mine) which makes me kinda nervous. Might want to check with @dons, @dcoutts or someone else more knowledgeable than me :smile: