Open meebey opened 11 years ago
Technically you can still provide a stream around what LevelDB gives us (either char *
or slice), namely UnmanagedMemoryStream
. The data would still be copied to RAM, but you don't have to convert it all to a string. And since the key and value don't have to be a C-style string anyway, this would prove useful to people using blobs as either.
Implementing some equivalent of Slice
would be good, and we already have the same effect when iterating. LevelDB is currently doing extra work to do the copy assuming we'll want it that way. Getting this to work well might include making changes to the underlying LevelDB code, or using an iterator every time so we can get at the non-remalloc'ed data.
@carlosmn streams don't make sense when all values ARE already in memory btw ;) It's just an API gimmick but no performance gain at all. The idea of streams is to do chunk processing through a number of different layers. If one layer copies all data already and then returns a stream on that, the gain is already lost...
LevelDB C++ would need to provide a stream, then LevelDB C expose that properly and then we could wrap it. That is what RavenDB guys basically want (from what I get from their blog post)
/cc @robashton
Correct, we'd need to write C in order to get what we want, one way or another :)
You can try this implementation, A leveldb implementation in C# https://github.com/tg123/IronLeveldb
leveldb-sharp currently copies the values returned from LevelDB using Marshal.PtrToStringAnsi() as the memory was allocated by LevelDB. The issue is that the CLR can not use memory owned / allocated by someone else it can't know when it needs to be released or if it was already released. The simple but not effective solution is to copy the memory to have it CLR owned. To make the situation even worse, the C binding of LevelDB also copies the values returned by LevelDB, see: http://codeofrob.com/entries/the-price-of-abstraction---using-leveldb-in-ravendb.html
After looking into this issue I came up these possible solutions how passing values can work:
Quoting from Rob's blog:
"Where that stream reads from the start of an unmanaged array to the end of that unmanaged array and then disposes it."
This wouldn't work for us, as LevelDB reads the whole value into memory and returns that, instead of a stream...