<table><tr><td style="">rjvbb created this revision.<br />rjvbb added a reviewer: brauch.<br />rjvbb added a project: KDevelop.<br />rjvbb requested review of this revision.
</td><a style="text-decoration: none; padding: 4px 8px; margin: 0 8px 8px; float: right; color: #464C5C; font-weight: bold; border-radius: 3px; background-color: #F7F7F9; background-image: linear-gradient(to bottom,#fff,#f1f0f1); display: inline-block; border: 1px solid rgba(71,87,120,.2);" href="https://phabricator.kde.org/D12746">View Revision</a></tr></table><br /><div><strong>REVISION SUMMARY</strong><div><p>This was discussed on kdevelop-devel initially.</p>

<p>In a nutshell, I am not particularly charmed by the idea that a key/value database of potentially thousands of pairs is stored using individual files in a single directory, in addition using as many mmaps. A comment in the code itself claims that this may be problematic on some platforms. On my question if there had been a recent assessment of how suitable modern simple key/value databases are as a backend for this feature, Sven said</p>

<div class="remarkup-code-block" style="margin: 12px 0;" data-code-lang="text" data-sigil="remarkup-code-block"><pre class="remarkup-code" style="font: 11px/15px "Menlo", "Consolas", "Monaco", monospace; padding: 12px; margin: 0; background: rgba(71, 87, 120, 0.08);">I think Milian investigated this once and concluded that no database on the market can do the lookups we need to do in an efficient-enough
manner. Also, this is a huge amount of work to change.

That said, if there is a solution with the same or superior performance and somebody is willing to do the porting, I'm all for it ...</pre></div>

<p>I had been looking for an excuse to get some experience with database libraries like LMDB so started to work on an approach that would hopefully not be a "huge amount of work". The result is attached, with working backend implementations for the original QFile-based approach, LMDB (with the lmdbxx C++ bindings and additional LZ4 value compression), LevelDB and (LZO-compressed) KyotoCabinet (the latter 2 deactivated).</p>

<p>The backend implementation is based on the QFile API, with a very thin wrapper around QFile or more complex classes for the 3 database backends; the desired backend is currently selected via a preprocessor token in topducontextdynamicdata_p.h (requiring a rebuild of only 2 files from KDevPlatformLanguage).</p>

<p>I've been doing extensive testing in real-life and using the test_topcontextstore unittest/benchmark, and think the patch is now at a stage where it can be presented to the world as (at least) a proof of concept.</p>

<p>In practice, the LMDB backend corresponds best to what I was hoping to achieve: minimal overhead compared to the existing implementation  (at least on Linux) with potentially an increase in disk efficiency (in addition to using a single file) and possibly a performance gain on slow media. In short, comparing to the file-based backend: writing TopContexts is slower but not noticeably so in real life; reading is comparably fast (even in the benchmark) on local storage. On slow (remote) storage, writing can be comparably fast while reading is as fast as on local storage. (I'm not really certain how to explain that, btw.)<br />
More complete benchmark results (on Mac and Linux) are included in <tt style="background: #ebebeb; font-size: 13px;">test_topcontextstore.cpp</tt>. The LZ4 compression gives up to a 2x decrease in average of the stored value sizes with a negligible impact on performance (probably because the benchmark first fills the database file with uncompressable random values).</p>

<p>Re: LMDB and NFS: there is a known issue with LMDB on NFS shares. As far as I understand, this concerns different use cases (shared databases) than the one at hand (a private databased used by a single application at a time). The unittest has not shown any problems with <tt style="background: #ebebeb; font-size: 13px;">XDG_CACHE_HOME</tt> points to a directory on an NFS share.</p>

<p>I have not tested LevelDB extensively as it can use multiple (many) files too. In addition, LevelDB builds with TCMalloc by default which can (and has) lead to issues (deadlocks).</p>

<p>I looked into KyotoCabinet because the LevelDB performance notes mention it can be faster for random read access. In my implementation it does not at all live up to that reputation.</p>

<p>For now I have been keeping those backend implementations for reference (cum potential "junk DNA").</p></div></div><br /><div><strong>TEST PLAN</strong><div><p>Tested on Mac and Linux in real-life usage as well as with the unittest/benchmark.</p>

<p>I have been using the lmdbxx C++ binding; at some point I might simply include a stripped-down/tailored version of it instead.</p></div></div><br /><div><strong>REPOSITORY</strong><div><div>R32 KDevelop</div></div></div><br /><div><strong>REVISION DETAIL</strong><div><a href="https://phabricator.kde.org/D12746">https://phabricator.kde.org/D12746</a></div></div><br /><div><strong>AFFECTED FILES</strong><div><div>kdevplatform/language/CMakeLists.txt<br />
kdevplatform/language/duchain/tests/CMakeLists.txt<br />
kdevplatform/language/duchain/tests/test_topcontextstore.cpp<br />
kdevplatform/language/duchain/tests/test_topcontextstore.h<br />
kdevplatform/language/duchain/topducontextdynamicdata.cpp<br />
kdevplatform/language/duchain/topducontextdynamicdata.h<br />
kdevplatform/language/duchain/topducontextdynamicdata_p.cpp<br />
kdevplatform/language/duchain/topducontextdynamicdata_p.h</div></div></div><br /><div><strong>To: </strong>rjvbb, brauch<br /><strong>Cc: </strong>kdevelop-devel, antismap, iodelay, vbspam, njensen, geetamc, Pilzschaf, akshaydeo, surgenight, arrowdodger<br /></div>