<div dir="auto">How is your cache working? Thing is I'm optionally using mmaped segments, but I think `madvise` should be set to random file access... also, in my use cases it doesn't matter much if I'm using mmap, a FileChannel or even iouring. I think the page fragment compression/decompression with LZ4 slows everything down already (even though, now I'm compressing the data pages also in parallel during serialization). I'm using caffeine caches as the buffer managers, but also using direct references as in PageReference.setPage(page), thus that it must not read from the cache ideally (but also during evictions PageReference.setPage(null) is set).<div dir="auto"><br></div><div dir="auto">Nodes are created over here: <a href="https://github.com/sirixdb/sirix/blob/master/bundles/sirix-core/src/main/java/io/sirix/access/trx/node/json/JsonNodeFactoryImpl.java" rel="noreferrer noreferrer noreferrer" target="_blank">https://github.com/sirixdb/sirix/blob/master/bundles/sirix-core/src/main/java/io/sirix/access/trx/node/json/JsonNodeFactoryImpl.java</a></div><div dir="auto"><br></div><div dir="auto">The pages with the nodes: <a href="https://github.com/sirixdb/sirix/blob/master/bundles/sirix-core/src/main/java/io/sirix/page/KeyValueLeafPage.java" rel="noreferrer noreferrer noreferrer" target="_blank">https://github.com/sirixdb/sirix/blob/master/bundles/sirix-core/src/main/java/io/sirix/page/KeyValueLeafPage.java</a></div><div dir="auto"><br></div><div dir="auto"><div dir="auto">So, not entirely sure how to tackle this...</div><div dir="auto"><br></div><div dir="auto">Kind regards</div><div dir="auto">Johannes</div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Brian S O'Neill <<a href="mailto:bronee@gmail.com" rel="noreferrer noreferrer noreferrer" target="_blank">bronee@gmail.com</a>> schrieb am Fr., 28. Juli 2023, 15:46:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 2023-07-28 12:15 AM, Johannes Lichtenberger wrote:<br>
> Hello,<br>
> <br>
> I think I mentioned it already, but currently I'm thinking about it again.<br>
> <br>
> Regarding the index trie in my spare time project I'm thinking if it <br>
> makes sense, as currently I'm creating fine granular on heap nodes <br>
> during insertions/updates/deletes (1024 per page). Once a page is read <br>
> again from storage I'm storing these nodes in a byte array of byte <br>
> arrays until read for the first time. One thing though is, that the <br>
> nodes may store strings inline and thus are of variable size (and thus, <br>
> the pages are of variable size, too, padded to word aligned IIRC).<br>
> <br>
> I'm currently auto-committing after approx 500_000 nodes have been <br>
> created (afterwards they can be garbage collected) and in total there <br>
> are more than 320 million nodes in one test.<br>
> <br>
> I think I could store the nodes in MemorySegments instead of using on <br>
> heap classes / instances and dynamically reallocate memory if a node <br>
> value is changed.<br>
> <br>
> However, I'm not sure as it means a lot of work and maybe off heap <br>
> memory access is always slightly worse than on heap!?<br>
> <br>
<br>
I've been maintaining a (mostly) pure Java database library for several <br>
years now, and I can give you the short answer: Yes, you should consider <br>
supporting off heap memory. Now for the long answer...<br>
<br>
The Tupl database supports a cache backed by Java byte arrays or by off <br>
heap (native) memory. By design, the cache is very friendly to <br>
generational garbage collectors -- all the memory is allocated up front, <br>
and it's recycled without any GC involvement. Database pages are fixed <br>
in size (4096 bytes by default), which simplifies memory management and <br>
persistence. Under load, GC activity is very low.<br>
<br>
The off heap memory is managed by using the Unsafe class, but I'm <br>
converting it to use the Panama API. The Panama version is almost as <br>
fast as using Unsafe, and Maurizio (as he mentioned earlier) is working <br>
on closing the performance gap.<br>
<br>
For small caches (1GB), the performance of the byte[] version and the <br>
off heap version is the same. The problem is scalability. With larger <br>
caches, even generational garbage collectors slow down. With a 16GB <br>
cache, the byte[] version is about 50% slower than the off heap version. <br>
This is with the G1 collector. Generational ZGC is better, with a <br>
performance ratio of about 25%. Things get much much worse as the cache <br>
gets even larger, but I don't have numbers readily available.<br>
<br>
Note that if you're allocating and freeing MemorySegments all the time, <br>
you might not see as much of a performance improvement compared to byte <br>
arrays. A generational collector is very good at managing short lived <br>
objects. To see a huge win, you'll need to do your own memory management.<br>
<br>
</blockquote></div>