diff --git a/CHANGES.txt b/CHANGES.txt index 6320d4e5cb..c402eb2ea7 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -2,6 +2,7 @@ * Add Paxos v2 option and informatin in cassandra.yaml (CASSANDRA-21316) * Harden data resurrection startup check with atomic heartbeat file write with fallback (CASSANDRA-21290) Merged from 4.0: + * Consider first token of SSTable when calculating SSTable intersection in LeveledScanner (CASSANDRA-21369) * Remove inFlightEcho entry on ECHO_REQ failure (CASSANDRA-21428) * Validate snapshot names (CASSANDRA-21389) * BTree.FastBuilder.reset() fails to clear savedBuffer and savedNextKey, causing ClassCastException and SSTable header corruption during schema disagreement (CASSANDRA-21216, CASSANDRA-21260) diff --git a/src/java/org/apache/cassandra/db/compaction/LeveledCompactionStrategy.java b/src/java/org/apache/cassandra/db/compaction/LeveledCompactionStrategy.java index b2ba17a31a..b2cd3f3152 100644 --- a/src/java/org/apache/cassandra/db/compaction/LeveledCompactionStrategy.java +++ b/src/java/org/apache/cassandra/db/compaction/LeveledCompactionStrategy.java @@ -387,7 +387,7 @@ public class LeveledCompactionStrategy extends AbstractCompactionStrategy // Lazily creates SSTableBoundedScanner for sstable that are assumed to be from the // same level (e.g. non overlapping) - see #4142 - private static class LeveledScanner extends AbstractIterator implements ISSTableScanner + protected static class LeveledScanner extends AbstractIterator implements ISSTableScanner { private final TableMetadata metadata; private final Collection> ranges; @@ -442,8 +442,7 @@ public class LeveledCompactionStrategy extends AbstractCompactionStrategy { for (SSTableReader sstable : sstables) { - Range sstableRange = new Range<>(sstable.first.getToken(), sstable.last.getToken()); - if (range == null || sstableRange.intersects(range)) + if (range == null || range.intersects(sstable.getBounds())) filtered.add(sstable); } } diff --git a/test/unit/org/apache/cassandra/db/compaction/LeveledCompactionStrategyTest.java b/test/unit/org/apache/cassandra/db/compaction/LeveledCompactionStrategyTest.java index 2c27ebf52a..516732747e 100644 --- a/test/unit/org/apache/cassandra/db/compaction/LeveledCompactionStrategyTest.java +++ b/test/unit/org/apache/cassandra/db/compaction/LeveledCompactionStrategyTest.java @@ -71,6 +71,7 @@ import org.apache.cassandra.utils.TimeUUID; import org.awaitility.Awaitility; import static java.util.Collections.singleton; +import static org.apache.cassandra.schema.MockSchema.readerBounds; import static org.assertj.core.api.Assertions.assertThat; import static org.apache.cassandra.utils.TimeUUID.Generator.nextTimeUUID; import static org.junit.Assert.assertEquals; @@ -1039,6 +1040,32 @@ public class LeveledCompactionStrategyTest } } + @Test + public void testLevelScannerIntersection() + { + Collection sstable = Collections.singleton(MockSchema.sstableWithLevel(1, 10, 20, 1, cfs)); + + // SSTable range - [10, 20] + // range - (1, 9] + Range range = new Range<>(readerBounds(1).getToken(), readerBounds(9).getToken()); + assertEquals(0, LeveledCompactionStrategy.LeveledScanner.intersecting(sstable, Collections.singleton(range)).size()); + + // SSTable range - [10, 20] + // range - (1, 10] + range = new Range<>(readerBounds(1).getToken(), readerBounds(10).getToken()); + assertEquals(1, LeveledCompactionStrategy.LeveledScanner.intersecting(sstable, Collections.singleton(range)).size()); + + // SSTable range - [10, 20] + // range - (1, 15] + range = new Range<>(readerBounds(1).getToken(), readerBounds(15).getToken()); + assertEquals(1, LeveledCompactionStrategy.LeveledScanner.intersecting(sstable, Collections.singleton(range)).size()); + + // SSTable range - [10, 20] + // range - (20, 25] + range = new Range<>(readerBounds(20).getToken(), readerBounds(25).getToken()); + assertEquals(0, LeveledCompactionStrategy.LeveledScanner.intersecting(sstable, Collections.singleton(range)).size()); + } + private Pair, Set> groupByLevel(Iterable sstables) { Set l1after = new HashSet<>();