Skip to content

CNDB-18906: Implement a trie serialization format for partition updates - #2572

Open
lesnik2u wants to merge 76 commits into
CNDB-15669from
trie-commitlog
Open

CNDB-18906: Implement a trie serialization format for partition updates#2572
lesnik2u wants to merge 76 commits into
CNDB-15669from
trie-commitlog

Conversation

@lesnik2u

Copy link
Copy Markdown

What is the issue

https://github.com/riptano/cndb/issues/18906

PARTITIONUPDATE SERIALIZATION BENCHMARK SUMMARY (LEGACY VS TRIE ACROSS VERSIONS)
Benchmark                      | (format)   | (rows) | (version)       | Mode | Score    | Error   | Units 
----------------------------------------------------------------------------------------------------
deserialize                    | legacy     | 100    | VERSION_DS_10   | avgt |   61.686 |   1.586 | us/op 
deserialize                    | legacy     | 100    | VERSION_DS_20   | avgt |    3.723 |   0.550 | us/op 
deserialize                    | trie       | 100    | VERSION_DS_10   | avgt |   62.175 |   4.317 | us/op 
deserialize                    | trie       | 100    | VERSION_DS_20   | avgt |    3.633 |   0.285 | us/op 
serialize                      | legacy     | 100    | VERSION_DS_10   | avgt |   43.604 |   0.441 | us/op 
serialize                      | legacy     | 100    | VERSION_DS_20   | avgt |    3.187 |   0.084 | us/op 
serialize                      | trie       | 100    | VERSION_DS_10   | avgt |   52.827 |  55.936 | us/op 
serialize                      | trie       | 100    | VERSION_DS_20   | avgt |    3.306 |   0.657 | us/op 
   MUTATIONBENCH COMPARISON SUMMARY (SKIPLIST VS TRIE ACROSS VERSIONS)
Benchmark                    | (memtable) | (version)  | Mode | Score    | Error   | Units 
------------------------------------------------------------------------------------------
MutationBench.deserialize    | skiplist   | VERSION_DS_20 | avgt |    0.423 |   0.029 | us/op 
MutationBench.deserialize    | trie       | VERSION_DS_20 | avgt |    0.458 |   0.006 | us/op 
MutationBench.serialize      | skiplist   | VERSION_DS_20 | avgt |    0.018 |   0.001 | us/op 
MutationBench.serialize      | trie       | VERSION_DS_20 | avgt |    0.022 |   0.002 | us/op 
WRITE BENCHMARK SUMMARY (DEFAULT VS TRIE MEMTABLE ACROSS FLUSH MODES)
Benchmark            | (memtable)   | (flush)    | (count)  | Mode | Score      | Error    | Units
---------------------------------------------------------------------------------------------------------
writeTable           | default      | TRUNCATE   | 1000     | avgt |  70667.079 | 8573.028 | us/op
writeTable           | default      | TRUNCATE   | 1000     | avgt |  70280.985 | 3057.897 | us/op
writeTable           | trie         | TRUNCATE   | 1000     | avgt |  70397.928 | 5547.990 | us/op
writeTable           | trie         | TRUNCATE   | 1000     | avgt |  71305.069 | 4349.794 | us/op

What does this PR fix and why was it fixed

...

blambov and others added 30 commits August 18, 2026 10:52
Implements a row-level trie memtable that uses deletion-aware
tries to store deletions separately from live data, together
with the associated TrieBackedPartition and TriePartitionUpdate.

Refactors trie hierarchy to support multiple trie types:
- plain
- range, which stores range boundaries and is able to answer
  questions about the range that applies to every point in the
  trie
- deletion aware, which combines a data part and a deletion range
  trie

Every trie type supports suitable operations, including merging
and intersection that make sense for the type of trie. In particular,
deletion-aware tries apply range branches to delete data during
merges.

Adds a new method to UnfilteredRowIterator that is implemented
by the new trie-backed partitions to ask them to stop issuing
tombstones. This is done on filtering (i.e. conversion from
UnfilteredRowIterator to RowIterator) where tombstones have already
done their job and are no longer needed.

Adds JMH tests of tombstones that demonstrate tombstone-independent
performance on memtable queries.

# Conflicts:
#	test/burn/org/apache/cassandra/index/sai/LongVectorTest.java
in a combined `encodedState` returned by advancing methods.
This saves megamorphic calls to `incomingTransition` and can
be augmented by further information at no cost.
This functionality has two main applications:
- it allows reverse walks that present prefix content in the correct
  byte-comparable order (i.e. prefixes after children)
- it makes it possible to have full control over what is and isn't
  included in a trie ranges (e.g. making it possible to have a branch
  set and nested ranges)
…and TrieMemtable to Stage3 version

Remove duplicate configuration object and add tests for stage 3
This change extends the coverage of the memtable trie to the
cell level, defining mappings of trie branches to and from the
legacy concepts of complex columns and rows.
This makes it possible to have completely off-heap trie memtable,
where cell data is stored inside the trie structure if it is small
enough to fit, or placed in natively-allocated memory and referenced
by memory address.
Drops the mutator tail retrieval methods which are no longer necessary
- Memtable will now request a switch if columns change
- It will use the metadata state at construction to make sure
  it is not affected by breaking changes in columns
- It will use current metadata as source of dropped columns
blambov added 11 commits August 18, 2026 10:52
The main reason for this is that serialized data may be
using other columns than the ones in the metadata
(e.g. synthetic columns) and we don't yet have support
for changing column sets. We don't gain anything either
because we can't do merges by trie yet.
Because the updates are serialized (for the commitlog and
replicas) and the serialization code relies heavily
on the legacy access mechanisms in a way that cannot be
easily optimized, using trie updates causes significant
overhead.

The update is converted to trie in MemtableShard.put.

This decision will be changed when we introduce
a trie-based version of the partition serialization.
@lesnik2u
lesnik2u requested a review from blambov August 18, 2026 13:59
@lesnik2u lesnik2u self-assigned this Aug 18, 2026
@blambov

blambov commented Aug 19, 2026

Copy link
Copy Markdown

Something looks wrong in the first benchmark table. Legacy memtable partition update serialization should not be affected by the new version as they are running exactly the same code.

In the third one, did you run the benchmark with useNet=true (otherwise it won't do serialization)?

@blambov

blambov commented Aug 19, 2026

Copy link
Copy Markdown

It's an interesting approach to dump and restore the in-memory state. Does it pass most tests? If it does, I will run the fallout benchmark to see what effect it has.

Ultimately we should be using an on-disk format, non-page-packed, like the one I started developing in this commit of the trie-table branch. Give me a few days to add deletion-aware support and to make sure we can build both page-packed (for trietables) and faster non-packed (for commitlog/messaging) serializations.

@lesnik2u

Copy link
Copy Markdown
Author

@blambov The differences were because In C* 5.0 (VERSION_DS_20), Cassandra introduced major internal optimizations to standard row and cell serialization. Because of these general 5.0 protocol optimizations, all Legacy B-Tree updates are ~10x faster to serialize/deserialize under VERSION_DS_20 than VERSION_DS_10.

@blambov

blambov commented Aug 19, 2026

Copy link
Copy Markdown

Shouldn't we then use a new version, as we are changing the serialization?

@lesnik2u

Copy link
Copy Markdown
Author

@blambov yeah, I was intending to add a new one. All trie tests pass for me, and all of the commit log tests pass
BatchCommitLogTest.java:
• Tests run: 1368
• Failures: 0
• Errors: 0
• Status: PASSED
GroupCommitLogTest.java:
• Tests run: 1368
• Failures: 0
• Errors: 0
• Status: PASSED
CommitLogDescriptorTest.java:
• Tests run: 22
• Failures: 0
• Errors: 0
• Status: PASSED

@lesnik2u lesnik2u changed the title CNDB-18906: Implement a trie commit log CNDB-18906: Implement a trie serialization format for partition updates Aug 19, 2026
@blambov
blambov force-pushed the CNDB-15669 branch 4 times, most recently from 2f6bbc5 to 95fe2db Compare August 21, 2026 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants