ReadBlock is inefficient when using PosixMmapReadableFile
- Dominant language
- C++
- Stars
- 39.4k
- Forks
- 8.2k
- PR merge metrics
- No merged PRs in 30d
Description
I have been working with Bitcoin's fork of LevelDB and from profiling LevelDB have noticed that the path used by Bitcoin is not handled very efficiently by LevelDB.
Some background: Bitcoin stores its UTXO database in LevelDB, where the keys and values are efficiently encoded binary values. For this reason, we always have snappy compression disabled. On 64-bit Posix hosts we will also always be using `PosixMmapReadableFile` for table handles, as we take care not to set `max_open_files` above the mmap threshold.
In this configuration the path through `ReadBlock()` is not very good because it allocates a buffer to copy results into (`char* buf = new char[n + kBlockTrailerSize]`), but there's no possibility for the buffer to be used, as the mmap file implementation returns a pointer directly to the mmap region. There's also no possibility for the block cache to be used, as it's explicitly skipped when the allocated buffer is unused and compression is disabled. So in this configuration there's an unnecessary heap alloc/free every time `ReadBlock()` is called.
It would be better if `ReadBlock()` could use some kind of runtime heuristic to detect this situation and avoid the unnecessary buffer allocation. It would be simple enough to require that implementations of `RandomAccessFile()` provide some kind of method indicating whether they have cacheable results, but this would require that users with custom environment implementations make changes to upgrade (I'm not sure how important this concern is).
Contributor guide
Assessment
This issue has not been assessed yet.