From 27d51518bbc34d6fc78344a669b8c7cb2ea2185f Mon Sep 17 00:00:00 2001 From: blambov Date: Mon, 18 May 2026 12:31:01 +0300 Subject: [PATCH] Expose UnifiedCompactionStrategy.Level stats --- .../compaction/UnifiedCompactionStrategy.java | 32 +++++++++++++++++-- .../BaseCompactionStrategyTest.java | 1 + .../UnifiedCompactionStrategyTest.java | 13 ++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/java/org/apache/cassandra/db/compaction/UnifiedCompactionStrategy.java b/src/java/org/apache/cassandra/db/compaction/UnifiedCompactionStrategy.java index 5b9a67ce4112..13ff07dc6e56 100644 --- a/src/java/org/apache/cassandra/db/compaction/UnifiedCompactionStrategy.java +++ b/src/java/org/apache/cassandra/db/compaction/UnifiedCompactionStrategy.java @@ -1512,6 +1512,34 @@ public int getIndex() return index; } + // The stats below are set up by getLevels and useful for diagnostics. + public int getFanout() + { + return fanout; + } + + public int getThreshold() + { + return threshold; + } + + public double getMinDensity() + { + return min; + } + + public double getMaxDensity() + { + return max; + } + + public double getAverageSSTableSize() + { + return avg; + } + + // We don't expose max overlap as it's not valid until getCompactionAggregates gets called. + void add(CompactionSSTable sstable) { this.sstables.add(sstable); @@ -1528,8 +1556,8 @@ void complete() } private List getOversizeShardsAggregates(Arena arena, - Controller controller, - ShardManager shardManager) + Controller controller, + ShardManager shardManager) { List aggregates = new ArrayList<>(); double shardThreshold = fanout * controller.getMaxSstablesPerShardFactor(); diff --git a/test/unit/org/apache/cassandra/db/compaction/BaseCompactionStrategyTest.java b/test/unit/org/apache/cassandra/db/compaction/BaseCompactionStrategyTest.java index 8272e3455008..218137e77ca2 100644 --- a/test/unit/org/apache/cassandra/db/compaction/BaseCompactionStrategyTest.java +++ b/test/unit/org/apache/cassandra/db/compaction/BaseCompactionStrategyTest.java @@ -237,6 +237,7 @@ SSTableReader mockSSTable(int level, when(ret.isSuitableForCompaction()).thenReturn(true); when(ret.getSSTableLevel()).thenReturn(level); when(ret.onDiskLength()).thenReturn(bytesOnDisk); + when(ret.onDiskComponentsSize()).thenReturn(bytesOnDisk); when(ret.uncompressedLength()).thenReturn(bytesOnDisk); // let's assume no compression when(ret.hotness()).thenReturn(hotness); when(ret.getMaxTimestamp()).thenReturn(timestamp); diff --git a/test/unit/org/apache/cassandra/db/compaction/UnifiedCompactionStrategyTest.java b/test/unit/org/apache/cassandra/db/compaction/UnifiedCompactionStrategyTest.java index bae0828f0545..d85c2403162a 100644 --- a/test/unit/org/apache/cassandra/db/compaction/UnifiedCompactionStrategyTest.java +++ b/test/unit/org/apache/cassandra/db/compaction/UnifiedCompactionStrategyTest.java @@ -375,11 +375,24 @@ private void testGetMultipleBucketsOneArenaNonOverlappingAggregates(Map levels = entry.getValue(); assertEquals(expectedLevels, levels.size()); + double expectedMin = 0.0; for (int i = 0; i < expectedLevels; i++) { UnifiedCompactionStrategy.Level level = levels.get(i); assertEquals(i, level.getIndex()); + assertEquals(expectedMin, level.getMinDensity(), 1.0); + expectedMin = level.getMaxDensity(); + assertEquals(level.scalingParameter >= 0 ? level.scalingParameter + 2 : 2, level.getThreshold()); + assertEquals(2 + Math.abs(level.scalingParameter), level.getFanout()); + if (level.getSSTables().size() > 0) + assertEquals(level.getSSTables() + .stream() + .mapToLong(CompactionSSTable::onDiskLength) + .summaryStatistics() + .getAverage(), + level.getAverageSSTableSize(), + 1.0); Collection compactionAggregates = level.getCompactionAggregates(entry.getKey(), controller, shardManager, dataSetSizeBytes);