Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
7ae4458
Remove duplicate Row/CellWithSourceTable
blambov Apr 27, 2026
a267a29
TrieMemtable Stage 3
blambov Mar 13, 2025
8cd9f6e
Change trie interfaces to combine depth and incoming character
blambov Nov 12, 2025
3f0a96e
Change trie interfaces to permit stopping on the return path
blambov Nov 20, 2025
79f6ef6
Test fixes
blambov Apr 7, 2026
7b5fc7b
Copy TrieBackedPartition, TriePartitionUpdate, TriePartritionUpdater …
blambov Dec 5, 2025
9349013
Implements cell-level trie
blambov Dec 10, 2025
0f5152c
Test fixes
blambov Apr 7, 2026
d9a9a9b
Permit in-memory tries to store bytes in the trie structure
blambov Jan 7, 2026
c963de8
Implement InMemoryRangeCursor.getNearestContent directly
blambov Feb 17, 2026
946e159
Provide merged rows to indexer
blambov Apr 9, 2026
10e615d
Switch to indexing by cells rather than rows
blambov Apr 9, 2026
b789f9b
Remove unused imports
blambov Apr 29, 2026
864c478
JMH test fixes
blambov Apr 30, 2026
af6b2ed
Improve column counting
blambov Apr 30, 2026
5e34e98
Store TrieBackedRow's livenessInfo and deletion for reuse
blambov May 11, 2026
3f26a00
Improve deletion branch walks for rows and partitions
blambov May 12, 2026
ea4b961
Fix CASSANDRA-21353
blambov May 12, 2026
9664a86
Fix TrieMemtable behaviour on changing schema
blambov May 15, 2026
53938cf
Address test failures
blambov May 19, 2026
01b0d49
Correct `assertRowsIgnoringOrderInternal` for nulls
blambov May 20, 2026
8a22853
Restore ProtocolVersion.V3 compatibility without V2 support
blambov May 22, 2026
e410f97
Fix QueryMetricsTest
blambov May 22, 2026
7f5550a
Fix issues in payload cell tracking
blambov May 22, 2026
126ad64
Unused imports
blambov May 26, 2026
bbdbf61
Fix score column injection
blambov May 26, 2026
f049415
Fix double partition deletion error
blambov May 26, 2026
7c8828b
Improve row and tombstone counting
blambov May 27, 2026
6cccd53
Test fixes
blambov May 29, 2026
7907f1c
Review fixes
blambov Jun 1, 2026
b44b4a6
Add subselection support in TrieBackedRow.filter
blambov May 29, 2026
5feeff6
Test fixes
blambov Jun 4, 2026
ffed3da
Improve data size tracking and fix tests
blambov Jun 5, 2026
133eff8
Test fixes
blambov Jun 8, 2026
e1c8fa8
Test and fix DeletionAwareTrie.prefixedBySeparately
blambov Jun 10, 2026
e000e3b
Implement a direct getCellForKey for SAI
blambov Jun 10, 2026
0947aa2
Improve guarding of buffers
blambov Jun 11, 2026
53e5f35
Fixups
blambov Jun 11, 2026
c3f077a
Fix concurrency issue in DeletionAwareTrie mutation
blambov Jun 11, 2026
894a4c5
Improve DeletionAwareTrie.tailTrie
blambov Jun 12, 2026
129e0eb
Review
blambov Jun 12, 2026
f50a3ad
Precalculate minLocalDeletionTime
blambov Jun 16, 2026
abb4324
Review
blambov Jun 17, 2026
f17c798
Add some in-memory trie internals tests
blambov Jun 17, 2026
6d86bce
Clear references in recycled content ids
blambov Jun 17, 2026
523556e
Explain sparse child deletion
blambov Jun 18, 2026
9a82307
Add Cursor.incomingTransitionWithOverflow for skipTo implementations
blambov Jun 18, 2026
ad1d476
Review
blambov Jun 19, 2026
7ab226d
Allow `state` and `precedingState` to be called exhausted
blambov Jun 19, 2026
94e6f46
Fix fullPartitionDelete
blambov Jun 19, 2026
47a9d12
Fix ant check
blambov Jun 22, 2026
f3f9d90
Drop the incomingPositionWithOverflow method
blambov Jun 23, 2026
2bd6899
Nits
blambov Jun 24, 2026
feefe33
CNDB-15669: Implement feature flags
lesnik2u Aug 6, 2026
527a434
Use the right row builder for partition updates
blambov Jul 8, 2026
9eeb1a4
Improve TrieBackedPartition.unfilteredIterator
blambov Jul 8, 2026
c036a7a
Do not create new trie on TrieBackedRow.reset
blambov Jul 9, 2026
b349287
Introduce and use DeletionAwareTrie.deletionAtRoot
blambov Jul 9, 2026
795811d
Use more deletionBranchAtRoot
blambov Jul 9, 2026
6810069
Rebase fixes
blambov Aug 7, 2026
9a4f049
Fix collection types issue
blambov Aug 7, 2026
6989091
Use the proper row builder
blambov Aug 7, 2026
c223287
Fixes
blambov Aug 10, 2026
0f1c6ab
Make sure deserialization uses b-tree rows
blambov Aug 10, 2026
dd22d20
Sonarcube
blambov Aug 14, 2026
c01c3bb
Remove duplication in TrieMemtableStage2/3
blambov Aug 17, 2026
9119942
Remove duplication in TrieMemtableStage1
blambov Aug 17, 2026
f662835
Cleanup/comments
blambov Aug 17, 2026
8c76a44
Test fixes
blambov Aug 18, 2026
810c60e
Switch TrieMemtable to use BTreePartitionUpdate
blambov Jul 10, 2026
8cc62a6
Trie commitlog changes
lesnik2u Aug 18, 2026
b79025c
CNDB-18906: Push things that intellij removed from added on reset
lesnik2u Aug 18, 2026
77343c9
CNDB-18906: Introduce a new version and fix issues
lesnik2u Aug 19, 2026
359e2ee
CNDB-18906: Optimize TriePartitionUpdate serialization and column lookup
lesnik2u Aug 21, 2026
80b5e67
CNDB-18951: Remove NoSpamLogger from StorageCompatibilityMode.storage…
lesnik2u Aug 21, 2026
9888166
CNDB-18906: Track cellCount for O(1) affectedColumnCount and fast-pat…
lesnik2u Aug 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions conf/cassandra.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,12 @@ memtable:
configurations:
skiplist:
class_name: SkipListMemtable
trie_stage1:
class_name: TrieMemtableStage1
trie_stage2:
class_name: TrieMemtableStage2
trie_stage3:
class_name: TrieMemtableStage3
trie:
class_name: TrieMemtable
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ public enum CassandraRelevantProperties
* @deprecated remove when cndb no longer supports bdp/6.8-cndb
*/
@Deprecated(since = "5.0")
DS_CURRENT_MESSAGING_VERSION("ds.current_messaging_version", Integer.toString(MessagingService.VERSION_DS_20)),
DS_CURRENT_MESSAGING_VERSION("ds.current_messaging_version", Integer.toString(MessagingService.VERSION_DS_21)),
DTEST_API_LOG_TOPOLOGY("cassandra.dtest.api.log.topology"),
/** This property indicates if the code is running under the in-jvm dtest framework */
DTEST_IS_IN_JVM_DTEST("org.apache.cassandra.dtest.is_in_jvm_dtest"),
Expand Down Expand Up @@ -762,10 +762,10 @@ public enum CassandraRelevantProperties

/** Class used to discover/load the proper SAI index components file for a given sstable. */
SAI_ANN_USE_SYNTHETIC_SCORE("cassandra.sai.ann_use_synthetic_score", "false"),

/** The current version of the SAI on-disk index format. */
SAI_CURRENT_VERSION("cassandra.sai.latest.version", "ec"),

SAI_CUSTOM_COMPONENTS_DISCOVERY_CLASS("cassandra.sai.custom_components_discovery_class"),
SAI_ENABLE_EDGES_CACHE("cassandra.sai.enable_edges_cache", "false"),
SAI_ENABLE_GENERAL_ORDER_BY("cassandra.sai.general_order_by", "true"),
Expand Down Expand Up @@ -907,7 +907,6 @@ public enum CassandraRelevantProperties
// NVQ number of subvectors. This isn't really expected to change much so we're only exposing
// it as a global variable in case it's needed.
SAI_VECTOR_NVQ_NUM_SUB_VECTORS("cassandra.sai.vector.nvq_num_sub_vectors", "2"),

// The allowed ratio of extra rows (that map to "holes" in the ordinal space) to total rows indexed in the graph
// Higher percentages will result in more memory utilized to store the extra postings mappings and larger graph
// file sizes to store the empty nodes.
Expand All @@ -923,7 +922,6 @@ public enum CassandraRelevantProperties
* build a potential result set for search-then-sort query execution.
*/
SAI_VECTOR_SEARCH_MAX_MATERIALIZE_KEYS("cassandra.sai.vector_search.max_materialized_keys", "16000"),

/** Controls the maximum top-k limit for vector search */
SAI_VECTOR_SEARCH_MAX_TOP_K("cassandra.sai.vector_search.max_top_k", "1000"),
SAI_VECTOR_USE_PRUNING_DEFAULT("cassandra.sai.jvector.use_pruning_default", "false"),
Expand Down Expand Up @@ -1098,6 +1096,8 @@ public enum CassandraRelevantProperties
// i.e. that all replicas except for at most one in the cluster (across all DCs) must accept the write for it to be successful.
THREE_MEANS_ALL_BUT_ONE("dse.consistency_level.three_means_all_but_one", "false"),
TOLERATE_SSTABLE_SIZE("cassandra.tolerate_sstable_size"),
/** To be used for tests: whether trie cursors should be verified for correctness. */
TRIE_DEBUG("cassandra.debug_tries"),
/**
* Allows to set custom current trie index format. This node will produce sstables in this format.
*/
Expand Down
18 changes: 9 additions & 9 deletions src/java/org/apache/cassandra/config/DatabaseDescriptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -3991,10 +3991,10 @@ public static void setFileCacheEnabled(boolean enabled)

public static int getFileCacheSizeInMiB()
{
if (conf.file_cache_size == null)
if (conf == null || conf.file_cache_size == null)
{
// In client mode the value is not set.
assert DatabaseDescriptor.isClientInitialized();
// In client mode or uninitialized unit tests the value is not set.
assert conf == null || DatabaseDescriptor.isClientInitialized();
return 0;
}

Expand All @@ -4014,21 +4014,21 @@ public static void enableChunkCache(int sizeInMB)

public static int getNetworkingCacheSizeInMiB()
{
if (conf.networking_cache_size == null)
if (conf == null || conf.networking_cache_size == null)
{
// In client mode the value is not set.
assert DatabaseDescriptor.isClientInitialized();
// In client mode or uninitialized unit tests the value is not set.
assert conf == null || DatabaseDescriptor.isClientInitialized();
return 0;
}
return conf.networking_cache_size.toMebibytes();
}

public static boolean getFileCacheRoundUp()
{
if (conf.file_cache_round_up == null)
if (conf == null || conf.file_cache_round_up == null)
{
// In client mode the value is not set.
assert DatabaseDescriptor.isClientInitialized();
// In client mode or uninitialized unit tests the value is not set.
assert conf == null || DatabaseDescriptor.isClientInitialized();
return false;
}

Expand Down
5 changes: 3 additions & 2 deletions src/java/org/apache/cassandra/cql3/UpdateParameters.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.Map;

import org.apache.cassandra.db.guardrails.Guardrails;
import org.apache.cassandra.db.partitions.PartitionUpdate;
import org.apache.cassandra.schema.ColumnMetadata;
import org.apache.cassandra.schema.TableMetadata;
import org.apache.cassandra.db.*;
Expand Down Expand Up @@ -103,13 +104,13 @@ public <V> void newRow(Clustering<V> clustering) throws InvalidRequestException
if (clustering == Clustering.STATIC_CLUSTERING)
{
if (staticBuilder == null)
staticBuilder = BTreeRow.unsortedBuilder();
staticBuilder = PartitionUpdate.rowBuilder(metadata, true, false);
builder = staticBuilder;
}
else
{
if (regularBuilder == null)
regularBuilder = BTreeRow.unsortedBuilder();
regularBuilder = PartitionUpdate.rowBuilder(metadata, false, false);
builder = regularBuilder;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ private void updatePerBatchMetrics(Collection<? extends IMutation> mutations)
for (PartitionUpdate update : mutation.getPartitionUpdates())
{
for (Row row : update.rows())
nrUpdatedColumns += row.columns().size();
nrUpdatedColumns += row.columnCount();
}
}
metrics.update(type, nrUpdatedPartitions, nrUpdatedColumns);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,8 @@ else if ("PersistentMemoryMemtable".equalsIgnoreCase(shortClassName))
builder.memtable(MemtableParams.get("persistent_memory"));
else if ("TrieMemtable".equalsIgnoreCase(shortClassName))
builder.memtable(MemtableParams.get("trie"));
else if ("TrieMemtableStage1".equalsIgnoreCase(shortClassName))
builder.memtable(MemtableParams.get("trie"));
else if (shortClassName.matches("TrieMemtableStage\\d"))
builder.memtable(MemtableParams.get(shortClassName.replaceFirst("TrieMemtableStage", "trie_stage")));
else if ("ShardedSkipListMemtable".equalsIgnoreCase(shortClassName))
builder.memtable(MemtableParams.get("skiplist_sharded"));
else
Expand Down
71 changes: 37 additions & 34 deletions src/java/org/apache/cassandra/db/ColumnFamilyStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -2919,43 +2919,46 @@ private SSTableMultiWriter writeMemtableRanges(Supplier<Collection<Range<Partiti
if (current.isClean())
return null;

List<Memtable.FlushablePartitionSet<?>> dataSets = new ArrayList<>(ranges.size());
IntervalSet.Builder<CommitLogPosition> commitLogIntervals = new IntervalSet.Builder();
long keys = 0;
for (Range<PartitionPosition> range : ranges)
try (OpOrder.Group protectData = readOrdering.start())
{
Memtable.FlushablePartitionSet<?> dataSet = current.getFlushSet(range.left, range.right);
dataSets.add(dataSet);
commitLogIntervals.add(dataSet.commitLogLowerBound(), dataSet.commitLogUpperBound());
keys += dataSet.partitionCount();
}
if (keys == 0)
return null;
List<Memtable.FlushablePartitionSet<?>> dataSets = new ArrayList<>(ranges.size());
IntervalSet.Builder<CommitLogPosition> commitLogIntervals = new IntervalSet.Builder();
long keys = 0;
for (Range<PartitionPosition> range : ranges)
{
Memtable.FlushablePartitionSet<?> dataSet = current.getFlushSet(range.left, range.right);
dataSets.add(dataSet);
commitLogIntervals.add(dataSet.commitLogLowerBound(), dataSet.commitLogUpperBound());
keys += dataSet.partitionCount();
}
if (keys == 0)
return null;

// TODO: Can we write directly to stream, skipping disk?
Memtable.FlushablePartitionSet<?> firstDataSet = dataSets.get(0);
SSTableMultiWriter writer = createSSTableMultiWriter(newSSTableDescriptor(directories.getDirectoryForNewSSTables()),
keys,
0,
repairSessionID,
false,
commitLogIntervals.build(),
new SerializationHeader(true,
firstDataSet.metadata(),
firstDataSet.columns(),
firstDataSet.encodingStats()),
DO_NOT_TRACK);
try
{
for (Memtable.FlushablePartitionSet<?> dataSet : dataSets)
new Flushing.FlushRunnable(dataSet, writer, metric, false).call(); // executes on this thread
// TODO: Can we write directly to stream, skipping disk?
Memtable.FlushablePartitionSet<?> firstDataSet = dataSets.get(0);
SSTableMultiWriter writer = createSSTableMultiWriter(newSSTableDescriptor(directories.getDirectoryForNewSSTables()),
keys,
0,
repairSessionID,
false,
commitLogIntervals.build(),
new SerializationHeader(true,
firstDataSet.metadata(),
firstDataSet.columns(),
firstDataSet.encodingStats()),
DO_NOT_TRACK);
try
{
for (Memtable.FlushablePartitionSet<?> dataSet : dataSets)
new Flushing.FlushRunnable(dataSet, writer, metric, false).call(); // executes on this thread

return writer;
}
catch (Error | RuntimeException t)
{
writer.abort(t);
throw t;
return writer;
}
catch (Error | RuntimeException t)
{
writer.abort(t);
throw t;
}
}
}

Expand Down
6 changes: 6 additions & 0 deletions src/java/org/apache/cassandra/db/CounterMutation.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
import static org.apache.cassandra.net.MessagingService.VERSION_DS_11;
import static org.apache.cassandra.net.MessagingService.VERSION_DS_12;
import static org.apache.cassandra.net.MessagingService.VERSION_DS_20;
import static org.apache.cassandra.net.MessagingService.VERSION_DS_21;
import static org.apache.cassandra.net.MessagingService.VERSION_40;
import static org.apache.cassandra.net.MessagingService.VERSION_50;
import static org.apache.cassandra.net.MessagingService.VERSION_DSE_68;
Expand Down Expand Up @@ -490,6 +491,7 @@ public long getTimeout(TimeUnit unit)
private int serializedSizeDS11;
private int serializedSizeDS12;
private int serializedSizeDS20;
private int serializedSizeDS21;
private int serializedSizeDSE68;

public int serializedSize(int version)
Expand Down Expand Up @@ -520,6 +522,10 @@ public int serializedSize(int version)
if (serializedSizeDS20 == 0)
serializedSizeDS20 = (int) serializer.serializedSize(this, VERSION_DS_20);
return serializedSizeDS20;
case VERSION_DS_21:
if (serializedSizeDS21 == 0)
serializedSizeDS21 = (int) serializer.serializedSize(this, VERSION_DS_21);
return serializedSizeDS21;
case VERSION_DSE_68:
if (serializedSizeDSE68 == 0)
serializedSizeDSE68 = (int) serializer.serializedSize(this, VERSION_DSE_68);
Expand Down
13 changes: 7 additions & 6 deletions src/java/org/apache/cassandra/db/DeletionTime.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import org.apache.cassandra.cache.IMeasurableMemory;
import org.apache.cassandra.db.rows.Cell;
import org.apache.cassandra.db.rows.CellData;
import org.apache.cassandra.io.ISerializer;
import org.apache.cassandra.io.sstable.format.Version;
import org.apache.cassandra.io.util.DataInputPlus;
Expand All @@ -36,7 +37,7 @@
/**
* Information on deletion of a storage engine object.
*/
public class DeletionTime implements Comparable<DeletionTime>, IMeasurableMemory
public class DeletionTime implements Comparable<DeletionTime>, IMeasurableMemory, IDataSize
{
public static final long EMPTY_SIZE = ObjectSizes.measure(new DeletionTime(0, 0));

Expand Down Expand Up @@ -68,9 +69,9 @@ static DeletionTime buildUnsafeWithUnsignedInteger(long markedForDeleteAt, int l
: new DeletionTime(markedForDeleteAt, localDeletionTimeUnsignedInteger);
}

private DeletionTime(long markedForDeleteAt, long localDeletionTime)
protected DeletionTime(long markedForDeleteAt, long localDeletionTime)
{
this(markedForDeleteAt, Cell.deletionTimeLongToUnsignedInteger(localDeletionTime));
this(markedForDeleteAt, CellData.deletionTimeLongToUnsignedInteger(localDeletionTime));
}

private DeletionTime(long markedForDeleteAt, int localDeletionTimeUnsignedInteger)
Expand All @@ -95,7 +96,7 @@ public long markedForDeleteAt()
*/
public long localDeletionTime()
{
return Cell.deletionTimeUnsignedIntegerToLong(localDeletionTimeUnsignedInteger);
return CellData.deletionTimeUnsignedIntegerToLong(localDeletionTimeUnsignedInteger);
}

/**
Expand Down Expand Up @@ -143,7 +144,7 @@ public final int hashCode()
@Override
public String toString()
{
return this == LIVE ? "LIVE" : String.format("deletedAt=%d, localDeletion=%d", markedForDeleteAt(), localDeletionTime());
return this.isLive() ? "LIVE" : String.format("deletedAt=%d, localDeletion=%d", markedForDeleteAt(), localDeletionTime());
}

public int compareTo(DeletionTime dt)
Expand All @@ -170,7 +171,7 @@ public boolean deletes(LivenessInfo info)
return deletes(info.timestamp());
}

public boolean deletes(Cell<?> cell)
public boolean deletes(CellData<?, ?> cell)
{
return deletes(cell.timestamp());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.apache.cassandra.config.CassandraRelevantProperties;
import org.apache.cassandra.db.rows.BufferCell;
import org.apache.cassandra.db.rows.Cell;
import org.apache.cassandra.db.rows.CellData;
import org.apache.cassandra.exceptions.InvalidRequestException;
import org.apache.cassandra.schema.TableMetadata;
import org.apache.cassandra.service.ClientWarn;
Expand Down Expand Up @@ -79,7 +80,7 @@ public static void maybeApplyExpirationDateOverflowPolicy(TableMetadata metadata

// Check for localExpirationTime overflow (CASSANDRA-14092) to apply a policy if needed
long nowInSecs = currentTimeMillis() / 1000;
if (((long) ttl + nowInSecs) > Cell.getVersionedMaxDeletiontionTime())
if (((long) ttl + nowInSecs) > CellData.getVersionedMaxDeletiontionTime())
{
switch (policy)
{
Expand Down Expand Up @@ -121,13 +122,13 @@ public static long computeLocalExpirationTime(long nowInSec, int timeToLive)
{

long localExpirationTime = (long) (nowInSec + timeToLive);
long cellMaxDeletionTime = Cell.getVersionedMaxDeletiontionTime();
long cellMaxDeletionTime = CellData.getVersionedMaxDeletiontionTime();
return localExpirationTime <= cellMaxDeletionTime ? localExpirationTime : cellMaxDeletionTime;
}

private static String getMaxExpirationDateTS()
{
return Cell.getVersionedMaxDeletiontionTime() == Cell.MAX_DELETION_TIME_2038_LEGACY_CAP ? "2038-01-19T03:14:06+00:00"
: "2106-02-07T06:28:13+00:00";
return CellData.getVersionedMaxDeletiontionTime() == CellData.MAX_DELETION_TIME_2038_LEGACY_CAP ? "2038-01-19T03:14:06+00:00"
: "2106-02-07T06:28:13+00:00";
}
}
25 changes: 25 additions & 0 deletions src/java/org/apache/cassandra/db/IDataSize.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.cassandra.db;

/// Shared interface for providing data size information
public interface IDataSize
{
int dataSize();
}
Loading
Loading