Skip to content

Enhance memory management (Zero-Copy API) #5

@meebey

Description

@meebey

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:

  • copy unmanaged memory and make the copy managed: Marshal.PtrToStringAnsi()
    • Pros: safe, easy to implement, easy to use
    • Cons: copy overhead
  • return the pointer everywhere, as in IntPtr instead of a string or byte[] and let the user access that doing unsafe code blocks
    • Pros: most efficient
    • Cons: unsafe and ugly to use
  • implement a Slice type that operates on IntPtr and do unsafe code access on it and release the memory when needed (GCed). This would be basically a safe proxy around the unsafe memory.
    • Pros: safe, easy to use, most efficient

Quoting from Rob's blog:

MemoryStream stream = db.Get(string key)

"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...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions