From 48bc6d5234080b1a51b590d520526a96c886ab86 Mon Sep 17 00:00:00 2001 From: Dmitry Konstantinov Date: Mon, 4 May 2026 12:14:51 +0100 Subject: [PATCH] Reduce memory allocations in SelectStatement.getQuery SinglePartitionReadCommand.Group#create - typical single partition select, use singletonList instead of ArrayList + Object[] SelectStatement#getSliceCommands - remove unnessesary cloning of partition key, it is a part of a very old patch, now we copy all values from Netty buffers SelectStatement#getSliceCommands - typical single partition select, use singletonList instead of ArrayList + Object[] SinglePartitionReadQuery.Group#maybeValidateIndex, avoid iterators for restrictionSet if a full partition is selected patch by Dmitry Konstantinov; reviewed by Francisco Guerrero, Stefan Miklosovic for CASSANDRA-21351 --- .../ClusteringColumnRestrictions.java | 4 +++- .../cql3/statements/SelectStatement.java | 19 ++++++++++++++----- .../db/SinglePartitionReadCommand.java | 11 +++++++++++ 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/java/org/apache/cassandra/cql3/restrictions/ClusteringColumnRestrictions.java b/src/java/org/apache/cassandra/cql3/restrictions/ClusteringColumnRestrictions.java index 4d12be81589b..a2455bf14fe1 100644 --- a/src/java/org/apache/cassandra/cql3/restrictions/ClusteringColumnRestrictions.java +++ b/src/java/org/apache/cassandra/cql3/restrictions/ClusteringColumnRestrictions.java @@ -131,8 +131,10 @@ public NavigableSet> valuesAsClustering(QueryOptions options, Clie public Slices slices(QueryOptions options) throws InvalidRequestException { MultiCBuilder builder = new MultiCBuilder(comparator); - int keyPosition = 0; + if (restrictions.isEmpty()) // to avoid an iterator allocation for restrictions + return builder.buildSlices(); + int keyPosition = 0; for (SingleRestriction r : restrictions) { if (handleInFilter(r, keyPosition)) diff --git a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java index 23796b561847..c0cf9228edcc 100644 --- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java @@ -131,7 +131,6 @@ import org.apache.cassandra.transport.Dispatcher; import org.apache.cassandra.transport.ProtocolVersion; import org.apache.cassandra.transport.messages.ResultMessage; -import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.NoSpamLogger; @@ -802,7 +801,7 @@ public boolean isPartitionRangeQuery() private ReadQuery getSliceCommands(QueryOptions options, ClientState state, ColumnFilter columnFilter, RowFilter rowFilter, DataLimits limit, long nowInSec, PotentialTxnConflicts potentialTxnConflicts) { - Collection keys = restrictions.getPartitionKeys(options, state); + List keys = restrictions.getPartitionKeys(options, state); if (keys.isEmpty()) return ReadQuery.empty(table); @@ -815,11 +814,21 @@ private ReadQuery getSliceCommands(QueryOptions options, ClientState state, Colu if (filter == null || filter.isEmpty(table.comparator)) return ReadQuery.empty(table); - List decoratedKeys = new ArrayList<>(keys.size()); - for (ByteBuffer key : keys) + List decoratedKeys; + if (keys.size() == 1) // reduce allocations in collections for keys { + ByteBuffer key = keys.get(0); QueryProcessor.validateKey(key); - decoratedKeys.add(table.partitioner.decorateKey(ByteBufferUtil.clone(key))); + decoratedKeys = Collections.singletonList(table.partitioner.decorateKey(key)); + } + else + { + decoratedKeys = new ArrayList<>(keys.size()); + for (ByteBuffer key : keys) + { + QueryProcessor.validateKey(key); + decoratedKeys.add(table.partitioner.decorateKey(key)); + } } SinglePartitionReadQuery.Group group = diff --git a/src/java/org/apache/cassandra/db/SinglePartitionReadCommand.java b/src/java/org/apache/cassandra/db/SinglePartitionReadCommand.java index b487d011b2d1..28ae9b786a8b 100644 --- a/src/java/org/apache/cassandra/db/SinglePartitionReadCommand.java +++ b/src/java/org/apache/cassandra/db/SinglePartitionReadCommand.java @@ -1388,6 +1388,17 @@ public static Group create(TableMetadata metadata, ClusteringIndexFilter clusteringIndexFilter, PotentialTxnConflicts potentialTxnConflicts) { + if (partitionKeys.size() == 1) + { + return one(SinglePartitionReadCommand.create(metadata, + nowInSec, + columnFilter, + rowFilter, + limits, + partitionKeys.get(0), + clusteringIndexFilter, + potentialTxnConflicts)); + } List commands = new ArrayList<>(partitionKeys.size()); for (DecoratedKey partitionKey : partitionKeys) {