Avoid allocating SSTableBoundedScanner during repair when the range does not intersect the sstable patch by jbellis; reviewed by slebresne for CASSANDRA-5249
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/a4166496 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/a4166496 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/a4166496 Branch: refs/heads/trunk Commit: a4166496f2df6bc8072e7b30c29102937788f400 Parents: 02ea439 Author: Jonathan Ellis <jbel...@apache.org> Authored: Tue Feb 26 10:07:47 2013 -0600 Committer: Jonathan Ellis <jbel...@apache.org> Committed: Tue Feb 26 10:07:47 2013 -0600 ---------------------------------------------------------------------- CHANGES.txt | 2 + .../db/compaction/LeveledCompactionStrategy.java | 2 +- .../io/sstable/SSTableBoundedScanner.java | 16 ++--- .../apache/cassandra/io/sstable/SSTableReader.java | 54 ++++++++++++++- 4 files changed, 60 insertions(+), 14 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/a4166496/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index d4a74c0..b19b092 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,6 @@ 1.2.3 + * Avoid allocating SSTableBoundedScanner during repair when the range does + not intersect the sstable (CASSANDRA-5249) Merged from 1.1: * nodetool: ability to repair specific range (CASSANDRA-5280) * Fix possible assertion triggered in SliceFromReadCommand (CASSANDRA-5284) http://git-wip-us.apache.org/repos/asf/cassandra/blob/a4166496/src/java/org/apache/cassandra/db/compaction/LeveledCompactionStrategy.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/compaction/LeveledCompactionStrategy.java b/src/java/org/apache/cassandra/db/compaction/LeveledCompactionStrategy.java index 5b29bfc..6a1bf4b 100644 --- a/src/java/org/apache/cassandra/db/compaction/LeveledCompactionStrategy.java +++ b/src/java/org/apache/cassandra/db/compaction/LeveledCompactionStrategy.java @@ -200,7 +200,7 @@ public class LeveledCompactionStrategy extends AbstractCompactionStrategy implem private final Iterator<SSTableReader> sstableIterator; private final long totalLength; - private SSTableScanner currentScanner; + private ICompactionScanner currentScanner; private long positionOffset; public LeveledScanner(Collection<SSTableReader> sstables, Range<Token> range) http://git-wip-us.apache.org/repos/asf/cassandra/blob/a4166496/src/java/org/apache/cassandra/io/sstable/SSTableBoundedScanner.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/io/sstable/SSTableBoundedScanner.java b/src/java/org/apache/cassandra/io/sstable/SSTableBoundedScanner.java index 788f4ca..a571901 100644 --- a/src/java/org/apache/cassandra/io/sstable/SSTableBoundedScanner.java +++ b/src/java/org/apache/cassandra/io/sstable/SSTableBoundedScanner.java @@ -35,19 +35,13 @@ public class SSTableBoundedScanner extends SSTableScanner private final Iterator<Pair<Long, Long>> rangeIterator; private Pair<Long, Long> currentRange; - SSTableBoundedScanner(SSTableReader sstable, boolean skipCache, Range<Token> range) + SSTableBoundedScanner(SSTableReader sstable, boolean skipCache, Iterator<Pair<Long, Long>> rangeIterator) { super(sstable, skipCache); - this.rangeIterator = sstable.getPositionsForRanges(Collections.singletonList(range)).iterator(); - if (rangeIterator.hasNext()) - { - currentRange = rangeIterator.next(); - dfile.seek(currentRange.left); - } - else - { - exhausted = true; - } + this.rangeIterator = rangeIterator; + assert rangeIterator.hasNext(); // use EmptyCompactionScanner otherwise + currentRange = rangeIterator.next(); + dfile.seek(currentRange.left); } /* http://git-wip-us.apache.org/repos/asf/cassandra/blob/a4166496/src/java/org/apache/cassandra/io/sstable/SSTableReader.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/io/sstable/SSTableReader.java b/src/java/org/apache/cassandra/io/sstable/SSTableReader.java index d0ef5d8..51f2344 100644 --- a/src/java/org/apache/cassandra/io/sstable/SSTableReader.java +++ b/src/java/org/apache/cassandra/io/sstable/SSTableReader.java @@ -35,7 +35,9 @@ import org.apache.cassandra.config.ColumnDefinition; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.Schema; import org.apache.cassandra.db.*; +import org.apache.cassandra.db.columniterator.OnDiskAtomIterator; import org.apache.cassandra.db.commitlog.ReplayPosition; +import org.apache.cassandra.db.compaction.ICompactionScanner; import org.apache.cassandra.db.index.SecondaryIndex; import org.apache.cassandra.db.filter.QueryFilter; import org.apache.cassandra.dht.AbstractBounds; @@ -960,11 +962,15 @@ public class SSTableReader extends SSTable * @param range the range of keys to cover * @return A Scanner for seeking over the rows of the SSTable. */ - public SSTableScanner getDirectScanner(Range<Token> range) + public ICompactionScanner getDirectScanner(Range<Token> range) { if (range == null) return getDirectScanner(); - return new SSTableBoundedScanner(this, true, range); + + Iterator<Pair<Long, Long>> rangeIterator = getPositionsForRanges(Collections.singletonList(range)).iterator(); + return rangeIterator.hasNext() + ? new SSTableBoundedScanner(this, true, rangeIterator) + : new EmptyCompactionScanner(getFilename()); } public FileDataInput getFileDataInput(long position) @@ -1172,4 +1178,48 @@ public class SSTableReader extends SSTable sstable.releaseReference(); } } + + private static class EmptyCompactionScanner implements ICompactionScanner + { + private final String filename; + + private EmptyCompactionScanner(String filename) + { + this.filename = filename; + } + + public long getLengthInBytes() + { + return 0; + } + + public long getCurrentPosition() + { + return 0; + } + + public String getBackingFiles() + { + return filename; + } + + public void close() + { + } + + public boolean hasNext() + { + return false; + } + + public OnDiskAtomIterator next() + { + throw new IndexOutOfBoundsException(); + } + + public void remove() + { + throw new UnsupportedOperationException(); + } + } }