From 9bcdf5d7460e4475d1a5cbe7e547c574e00e603b Mon Sep 17 00:00:00 2001 From: Dmitry Konstantinov Date: Mon, 6 Apr 2026 21:16:25 +0100 Subject: [PATCH] Avoid Cell iterator for alive rows in MetricsRecording transformation of ReadCommand patch by Dmitry Konstantinov; reviewed by Francisco Guerrero for CASSANDRA-21288 --- CHANGES.txt | 1 + .../org/apache/cassandra/db/ReadCommand.java | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index b1451a0cdd..9be07b3a2b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 6.0-alpha2 + * Avoid Cell iterator for alive rows in MetricsRecording transformation of ReadCommand (CASSANDRA-21288) * Reuse a single TrackedDataInputPlus instance per UnfilteredSerializer (CASSANDRA-21296) * In-tree docs are included in binary artifacts (tarball, deb, rpm) as html and man pages (CASSANDRA-17260) * Add tooling to repair system peers and peers_v2 if inconsistent with cluster metadata (CASSANDRA-21187) diff --git a/src/java/org/apache/cassandra/db/ReadCommand.java b/src/java/org/apache/cassandra/db/ReadCommand.java index f5f9105602..bc918e9f3e 100644 --- a/src/java/org/apache/cassandra/db/ReadCommand.java +++ b/src/java/org/apache/cassandra/db/ReadCommand.java @@ -644,19 +644,24 @@ public abstract class ReadCommand extends AbstractReadQuery public Row applyToRow(Row row) { boolean hasTombstones = false; - for (Cell cell : row.cells()) + final long nowInSec = ReadCommand.this.nowInSec(); + final boolean rowHasDeletion = row.hasDeletion(nowInSec); + if (rowHasDeletion) // perf optimization, to avoid iteration if all cells are alive { - if (!cell.isLive(ReadCommand.this.nowInSec())) + for (Cell cell : row.cells()) { - countTombstone(row.clustering()); - hasTombstones = true; // allows to avoid counting an extra tombstone if the whole row expired + if (!cell.isLive(nowInSec)) + { + countTombstone(row.clustering()); + hasTombstones = true; // allows to avoid counting an extra tombstone if the whole row expired + } } } - if (row.hasLiveData(ReadCommand.this.nowInSec(), enforceStrictLiveness)) + if (row.hasLiveData(nowInSec, enforceStrictLiveness)) ++liveRows; - else if (!row.primaryKeyLivenessInfo().isLive(ReadCommand.this.nowInSec()) - && row.hasDeletion(ReadCommand.this.nowInSec()) + else if (!row.primaryKeyLivenessInfo().isLive(nowInSec) + && rowHasDeletion && !hasTombstones) { // We're counting primary key deletions only here.