Repository: cassandra
Updated Branches:
  refs/heads/cassandra-3.0 f96a5dc58 -> e22cb278b
  refs/heads/cassandra-3.11 88fa16977 -> 5c9db9af9
  refs/heads/trunk a741efd94 -> 96899bbb6


Fix the reported number of sstable data files accessed per read

patch by Benjamin Lerer; reviewed by Stefania Alborghetti for CASSANDRA-13120


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/e22cb278
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/e22cb278
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/e22cb278

Branch: refs/heads/cassandra-3.0
Commit: e22cb278b63a6ee5f03c7213071d07fd3b198659
Parents: f96a5dc
Author: Benjamin Lerer <b.le...@gmail.com>
Authored: Thu Jun 1 10:11:59 2017 +0200
Committer: Benjamin Lerer <b.le...@gmail.com>
Committed: Thu Jun 1 10:11:59 2017 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |   1 +
 .../cassandra/db/PartitionRangeReadCommand.java |  20 ++-
 .../db/SinglePartitionReadCommand.java          |  74 +++++++---
 .../db/columniterator/SSTableIterator.java      |   9 +-
 .../columniterator/SSTableReversedIterator.java |   9 +-
 .../io/sstable/format/SSTableReader.java        |  54 ++++++--
 .../io/sstable/format/SSTableReadsListener.java |  81 +++++++++++
 .../io/sstable/format/big/BigTableReader.java   |  40 ++++--
 .../io/sstable/format/big/BigTableScanner.java  |  40 +++++-
 .../org/apache/cassandra/cql3/CQLTester.java    |  21 ++-
 .../miscellaneous/SSTablesIteratedTest.java     | 136 +++++++++++++++++++
 .../cassandra/db/compaction/TTLExpiryTest.java  |   7 +-
 .../sstable/SSTableCorruptionDetectionTest.java |   7 +-
 .../io/sstable/SSTableScannerTest.java          |   6 +-
 .../cassandra/io/sstable/SSTableWriterTest.java |   7 +-
 .../sstable/format/ClientModeSSTableTest.java   |   6 +-
 16 files changed, 456 insertions(+), 62 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/e22cb278/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index c75ca87..4232084 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 3.0.14
+ * Fix the reported number of sstable data files accessed per read 
(CASSANDRA-13120)
  * Fix schema digest mismatch during rolling upgrades from versions before 
3.0.12 (CASSANDRA-13559)
  * Upgrade JNA version to 4.4.0 (CASSANDRA-13072)
  * Interned ColumnIdentifiers should use minimal ByteBuffers (CASSANDRA-13533)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e22cb278/src/java/org/apache/cassandra/db/PartitionRangeReadCommand.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/PartitionRangeReadCommand.java 
b/src/java/org/apache/cassandra/db/PartitionRangeReadCommand.java
index 17adef0..1cf332d 100644
--- a/src/java/org/apache/cassandra/db/PartitionRangeReadCommand.java
+++ b/src/java/org/apache/cassandra/db/PartitionRangeReadCommand.java
@@ -36,6 +36,7 @@ import org.apache.cassandra.dht.AbstractBounds;
 import org.apache.cassandra.exceptions.RequestExecutionException;
 import org.apache.cassandra.index.Index;
 import org.apache.cassandra.io.sstable.format.SSTableReader;
+import org.apache.cassandra.io.sstable.format.SSTableReadsListener;
 import org.apache.cassandra.io.util.DataInputPlus;
 import org.apache.cassandra.io.util.DataOutputPlus;
 import org.apache.cassandra.metrics.TableMetrics;
@@ -191,10 +192,11 @@ public class PartitionRangeReadCommand extends ReadCommand
                 iterators.add(isForThrift() ? 
ThriftResultsMerger.maybeWrap(iter, metadata(), nowInSec()) : iter);
             }
 
+            SSTableReadsListener readCountUpdater = newReadCountUpdater();
             for (SSTableReader sstable : view.sstables)
             {
                 @SuppressWarnings("resource") // We close on exception and on 
closing the result returned by this method
-                UnfilteredPartitionIterator iter = 
sstable.getScanner(columnFilter(), dataRange(), isForThrift());
+                UnfilteredPartitionIterator iter = 
sstable.getScanner(columnFilter(), dataRange(), isForThrift(), 
readCountUpdater);
                 iterators.add(isForThrift() ? 
ThriftResultsMerger.maybeWrap(iter, metadata(), nowInSec()) : iter);
                 if (!sstable.isRepaired())
                     oldestUnrepairedTombstone = 
Math.min(oldestUnrepairedTombstone, sstable.getMinLocalDeletionTime());
@@ -217,6 +219,22 @@ public class PartitionRangeReadCommand extends ReadCommand
         }
     }
 
+    /**
+     * Creates a new {@code SSTableReadsListener} to update the SSTables read 
counts.
+     * @return a new {@code SSTableReadsListener} to update the SSTables read 
counts.
+     */
+    private static SSTableReadsListener newReadCountUpdater()
+    {
+        return new SSTableReadsListener()
+                {
+                    @Override
+                    public void onScanningStarted(SSTableReader sstable)
+                    {
+                        sstable.incrementReadCount();
+                    }
+                };
+    }
+
     @Override
     protected int oldestUnrepairedTombstone()
     {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e22cb278/src/java/org/apache/cassandra/db/SinglePartitionReadCommand.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/SinglePartitionReadCommand.java 
b/src/java/org/apache/cassandra/db/SinglePartitionReadCommand.java
index 99abd10..72b4465 100644
--- a/src/java/org/apache/cassandra/db/SinglePartitionReadCommand.java
+++ b/src/java/org/apache/cassandra/db/SinglePartitionReadCommand.java
@@ -38,6 +38,7 @@ import org.apache.cassandra.db.partitions.*;
 import org.apache.cassandra.db.rows.*;
 import org.apache.cassandra.exceptions.RequestExecutionException;
 import org.apache.cassandra.io.sstable.format.SSTableReader;
+import org.apache.cassandra.io.sstable.format.SSTableReadsListener;
 import org.apache.cassandra.io.util.DataInputPlus;
 import org.apache.cassandra.io.util.DataOutputPlus;
 import org.apache.cassandra.metrics.TableMetrics;
@@ -551,12 +552,12 @@ public class SinglePartitionReadCommand extends 
ReadCommand
              * In other words, iterating in maxTimestamp order allow to do our 
mostRecentPartitionTombstone elimination
              * in one pass, and minimize the number of sstables for which we 
read a partition tombstone.
              */
-            int sstablesIterated = 0;
             Collections.sort(view.sstables, 
SSTableReader.maxTimestampComparator);
             List<SSTableReader> skippedSSTables = null;
             long mostRecentPartitionTombstone = Long.MIN_VALUE;
             long minTimestamp = Long.MAX_VALUE;
             int nonIntersectingSSTables = 0;
+            SSTableReadMetricsCollector metricsCollector = new 
SSTableReadMetricsCollector();
 
             for (SSTableReader sstable : view.sstables)
             {
@@ -579,15 +580,17 @@ public class SinglePartitionReadCommand extends 
ReadCommand
                     continue;
                 }
 
-                sstable.incrementReadCount();
                 @SuppressWarnings("resource") // 'iter' is added to iterators 
which is closed on exception, or through the closing of the final merged 
iterator
-                UnfilteredRowIterator iter = 
filter.filter(sstable.iterator(partitionKey(), columnFilter(), 
filter.isReversed(), isForThrift()));
+                UnfilteredRowIterator iter = 
filter.filter(sstable.iterator(partitionKey(),
+                                                                            
columnFilter(),
+                                                                            
filter.isReversed(),
+                                                                            
isForThrift(),
+                                                                            
metricsCollector));
                 if (!sstable.isRepaired())
                     oldestUnrepairedTombstone = 
Math.min(oldestUnrepairedTombstone, sstable.getMinLocalDeletionTime());
 
                 iterators.add(isForThrift() ? 
ThriftResultsMerger.maybeWrap(iter, nowInSec()) : iter);
                 mostRecentPartitionTombstone = 
Math.max(mostRecentPartitionTombstone, 
iter.partitionLevelDeletion().markedForDeleteAt());
-                sstablesIterated++;
             }
 
             int includedDueToTombstones = 0;
@@ -599,16 +602,19 @@ public class SinglePartitionReadCommand extends 
ReadCommand
                     if (sstable.getMaxTimestamp() <= minTimestamp)
                         continue;
 
-                    sstable.incrementReadCount();
                     @SuppressWarnings("resource") // 'iter' is either closed 
right away, or added to iterators which is close on exception, or through the 
closing of the final merged iterator
-                    UnfilteredRowIterator iter = 
filter.filter(sstable.iterator(partitionKey(), columnFilter(), 
filter.isReversed(), isForThrift()));
+                    UnfilteredRowIterator iter = 
filter.filter(sstable.iterator(partitionKey(),
+                                                                               
 columnFilter(),
+                                                                               
 filter.isReversed(),
+                                                                               
 isForThrift(),
+                                                                               
 metricsCollector));
+
                     if (iter.partitionLevelDeletion().markedForDeleteAt() > 
minTimestamp)
                     {
                         iterators.add(iter);
                         if (!sstable.isRepaired())
                             oldestUnrepairedTombstone = 
Math.min(oldestUnrepairedTombstone, sstable.getMinLocalDeletionTime());
                         includedDueToTombstones++;
-                        sstablesIterated++;
                     }
                     else
                     {
@@ -620,12 +626,12 @@ public class SinglePartitionReadCommand extends 
ReadCommand
                 Tracing.trace("Skipped {}/{} non-slice-intersecting sstables, 
included {} due to tombstones",
                               nonIntersectingSSTables, view.sstables.size(), 
includedDueToTombstones);
 
-            cfs.metric.updateSSTableIterated(sstablesIterated);
+            
cfs.metric.updateSSTableIterated(metricsCollector.getMergedSSTables());
 
             if (iterators.isEmpty())
                 return EmptyIterators.unfilteredRow(cfs.metadata, 
partitionKey(), filter.isReversed());
 
-            Tracing.trace("Merging data from memtables and {} sstables", 
sstablesIterated);
+            Tracing.trace("Merging data from memtables and {} sstables", 
metricsCollector.getMergedSSTables());
 
             @SuppressWarnings("resource") //  Closed through the closing of 
the result of that method.
             UnfilteredRowIterator merged = 
UnfilteredRowIterators.merge(iterators, nowInSec());
@@ -709,9 +715,9 @@ public class SinglePartitionReadCommand extends ReadCommand
 
         /* add the SSTables on disk */
         Collections.sort(view.sstables, SSTableReader.maxTimestampComparator);
-        int sstablesIterated = 0;
         boolean onlyUnrepaired = true;
         // read sorted sstables
+        SSTableReadMetricsCollector metricsCollector = new 
SSTableReadMetricsCollector();
         for (SSTableReader sstable : view.sstables)
         {
             // if we've already seen a partition tombstone with a timestamp 
greater
@@ -735,10 +741,12 @@ public class SinglePartitionReadCommand extends 
ReadCommand
                     continue; // Means no tombstone at all, we can skip that 
sstable
 
                 // We need to get the partition deletion and include it if 
it's live. In any case though, we're done with that sstable.
-                sstable.incrementReadCount();
-                try (UnfilteredRowIterator iter = 
filter.filter(sstable.iterator(partitionKey(), columnFilter(), 
filter.isReversed(), isForThrift())))
+                try (UnfilteredRowIterator iter = 
filter.filter(sstable.iterator(partitionKey(),
+                                                                               
  columnFilter(),
+                                                                               
  filter.isReversed(),
+                                                                               
  isForThrift(),
+                                                                               
  metricsCollector)))
                 {
-                    sstablesIterated++;
                     if (!iter.partitionLevelDeletion().isLive())
                         result = 
add(UnfilteredRowIterators.noRowsIterator(iter.metadata(), iter.partitionKey(), 
Rows.EMPTY_STATIC_ROW, iter.partitionLevelDeletion(), filter.isReversed()), 
result, filter, sstable.isRepaired());
                     else
@@ -748,20 +756,22 @@ public class SinglePartitionReadCommand extends 
ReadCommand
             }
 
             Tracing.trace("Merging data from sstable {}", 
sstable.descriptor.generation);
-            sstable.incrementReadCount();
-            try (UnfilteredRowIterator iter = 
filter.filter(sstable.iterator(partitionKey(), columnFilter(), 
filter.isReversed(), isForThrift())))
+            try (UnfilteredRowIterator iter = 
filter.filter(sstable.iterator(partitionKey(),
+                                                                             
columnFilter(),
+                                                                             
filter.isReversed(),
+                                                                             
isForThrift(),
+                                                                             
metricsCollector)))
             {
                 if (iter.isEmpty())
                     continue;
 
                 if (sstable.isRepaired())
                     onlyUnrepaired = false;
-                sstablesIterated++;
                 result = add(isForThrift() ? 
ThriftResultsMerger.maybeWrap(iter, nowInSec()) : iter, result, filter, 
sstable.isRepaired());
             }
         }
 
-        cfs.metric.updateSSTableIterated(sstablesIterated);
+        cfs.metric.updateSSTableIterated(metricsCollector.getMergedSSTables());
 
         if (result == null || result.isEmpty())
             return EmptyIterators.unfilteredRow(metadata(), partitionKey(), 
false);
@@ -770,7 +780,7 @@ public class SinglePartitionReadCommand extends ReadCommand
         
cfs.metric.samplers.get(TableMetrics.Sampler.READS).addSample(key.getKey(), 
key.hashCode(), 1);
 
         // "hoist up" the requested data into a more recent sstable
-        if (sstablesIterated > cfs.getMinimumCompactionThreshold()
+        if (metricsCollector.getMergedSSTables() > 
cfs.getMinimumCompactionThreshold()
             && onlyUnrepaired
             && !cfs.isAutoCompactionDisabled()
             && cfs.getCompactionStrategyManager().shouldDefragment())
@@ -1022,4 +1032,32 @@ public class SinglePartitionReadCommand extends 
ReadCommand
             return new SinglePartitionReadCommand(isDigest, digestVersion, 
isForThrift, metadata, nowInSec, columnFilter, rowFilter, limits, key, filter);
         }
     }
+
+    /**
+     * {@code SSTableReaderListener} used to collect metrics about SSTable 
read access.
+     */
+    private static final class SSTableReadMetricsCollector implements 
SSTableReadsListener
+    {
+        /**
+         * The number of SSTables that need to be merged. This counter is only 
updated for single partition queries
+         * since this has been the behavior so far.
+         */
+        private int mergedSSTables;
+
+        @Override
+        public void onSSTableSelected(SSTableReader sstable, RowIndexEntry<?> 
indexEntry, SelectionReason reason)
+        {
+            sstable.incrementReadCount();
+            mergedSSTables++;
+        }
+
+        /**
+         * Returns the number of SSTables that need to be merged.
+         * @return the number of SSTables that need to be merged.
+         */
+        public int getMergedSSTables()
+        {
+            return mergedSSTables;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e22cb278/src/java/org/apache/cassandra/db/columniterator/SSTableIterator.java
----------------------------------------------------------------------
diff --git 
a/src/java/org/apache/cassandra/db/columniterator/SSTableIterator.java 
b/src/java/org/apache/cassandra/db/columniterator/SSTableIterator.java
index fa337c0..ff91871 100644
--- a/src/java/org/apache/cassandra/db/columniterator/SSTableIterator.java
+++ b/src/java/org/apache/cassandra/db/columniterator/SSTableIterator.java
@@ -24,6 +24,7 @@ import org.apache.cassandra.db.*;
 import org.apache.cassandra.db.filter.ColumnFilter;
 import org.apache.cassandra.db.rows.*;
 import org.apache.cassandra.io.sstable.format.SSTableReader;
+import org.apache.cassandra.io.sstable.format.SSTableReadsListener;
 import org.apache.cassandra.io.util.FileDataInput;
 
 /**
@@ -31,9 +32,13 @@ import org.apache.cassandra.io.util.FileDataInput;
  */
 public class SSTableIterator extends AbstractSSTableIterator
 {
-    public SSTableIterator(SSTableReader sstable, DecoratedKey key, 
ColumnFilter columns, boolean isForThrift)
+    public SSTableIterator(SSTableReader sstable,
+                           DecoratedKey key,
+                           ColumnFilter columns,
+                           boolean isForThrift,
+                           SSTableReadsListener listener)
     {
-        this(sstable, null, key, sstable.getPosition(key, 
SSTableReader.Operator.EQ), columns, isForThrift);
+        this(sstable, null, key, sstable.getPosition(key, 
SSTableReader.Operator.EQ, listener), columns, isForThrift);
     }
 
     public SSTableIterator(SSTableReader sstable,

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e22cb278/src/java/org/apache/cassandra/db/columniterator/SSTableReversedIterator.java
----------------------------------------------------------------------
diff --git 
a/src/java/org/apache/cassandra/db/columniterator/SSTableReversedIterator.java 
b/src/java/org/apache/cassandra/db/columniterator/SSTableReversedIterator.java
index 4bb7fe8..b12ed67 100644
--- 
a/src/java/org/apache/cassandra/db/columniterator/SSTableReversedIterator.java
+++ 
b/src/java/org/apache/cassandra/db/columniterator/SSTableReversedIterator.java
@@ -26,6 +26,7 @@ import org.apache.cassandra.db.filter.ColumnFilter;
 import org.apache.cassandra.db.partitions.ImmutableBTreePartition;
 import org.apache.cassandra.db.rows.*;
 import org.apache.cassandra.io.sstable.format.SSTableReader;
+import org.apache.cassandra.io.sstable.format.SSTableReadsListener;
 import org.apache.cassandra.io.util.FileDataInput;
 import org.apache.cassandra.utils.AbstractIterator;
 import org.apache.cassandra.utils.btree.BTree;
@@ -35,9 +36,13 @@ import org.apache.cassandra.utils.btree.BTree;
  */
 public class SSTableReversedIterator extends AbstractSSTableIterator
 {
-    public SSTableReversedIterator(SSTableReader sstable, DecoratedKey key, 
ColumnFilter columns, boolean isForThrift)
+    public SSTableReversedIterator(SSTableReader sstable,
+                                   DecoratedKey key,
+                                   ColumnFilter columns,
+                                   boolean isForThrift,
+                                   SSTableReadsListener listener)
     {
-        this(sstable, null, key, sstable.getPosition(key, 
SSTableReader.Operator.EQ), columns, isForThrift);
+        this(sstable, null, key, sstable.getPosition(key, 
SSTableReader.Operator.EQ, listener), columns, isForThrift);
     }
 
     public SSTableReversedIterator(SSTableReader sstable,

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e22cb278/src/java/org/apache/cassandra/io/sstable/format/SSTableReader.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/io/sstable/format/SSTableReader.java 
b/src/java/org/apache/cassandra/io/sstable/format/SSTableReader.java
index 8be1fe2..f38738d 100644
--- a/src/java/org/apache/cassandra/io/sstable/format/SSTableReader.java
+++ b/src/java/org/apache/cassandra/io/sstable/format/SSTableReader.java
@@ -1504,14 +1504,19 @@ public abstract class SSTableReader extends SSTable 
implements SelfRefCounted<SS
      * Get position updating key cache and stats.
      * @see #getPosition(PartitionPosition, SSTableReader.Operator, boolean)
      */
-    public RowIndexEntry getPosition(PartitionPosition key, Operator op)
+    public final RowIndexEntry getPosition(PartitionPosition key, Operator op)
     {
-        return getPosition(key, op, true, false);
+        return getPosition(key, op, SSTableReadsListener.NOOP_LISTENER);
     }
 
-    public RowIndexEntry getPosition(PartitionPosition key, Operator op, 
boolean updateCacheAndStats)
+    public final RowIndexEntry getPosition(PartitionPosition key, Operator op, 
SSTableReadsListener listener)
     {
-        return getPosition(key, op, updateCacheAndStats, false);
+        return getPosition(key, op, true, false, listener);
+    }
+
+    public final RowIndexEntry getPosition(PartitionPosition key, Operator op, 
boolean updateCacheAndStats)
+    {
+        return getPosition(key, op, updateCacheAndStats, false, 
SSTableReadsListener.NOOP_LISTENER);
     }
     /**
      * @param key The key to apply as the rhs to the given Operator. A 'fake' 
key is allowed to
@@ -1520,10 +1525,24 @@ public abstract class SSTableReader extends SSTable 
implements SelfRefCounted<SS
      * @param updateCacheAndStats true if updating stats and cache
      * @return The index entry corresponding to the key, or null if the key is 
not present
      */
-    protected abstract RowIndexEntry getPosition(PartitionPosition key, 
Operator op, boolean updateCacheAndStats, boolean permitMatchPastLast);
-
-    public abstract SliceableUnfilteredRowIterator iterator(DecoratedKey key, 
ColumnFilter selectedColumns, boolean reversed, boolean isForThrift);
-    public abstract SliceableUnfilteredRowIterator iterator(FileDataInput 
file, DecoratedKey key, RowIndexEntry indexEntry, ColumnFilter selectedColumns, 
boolean reversed, boolean isForThrift);
+    protected abstract RowIndexEntry getPosition(PartitionPosition key,
+                                                 Operator op,
+                                                 boolean updateCacheAndStats,
+                                                 boolean permitMatchPastLast,
+                                                 SSTableReadsListener 
listener);
+
+    public abstract SliceableUnfilteredRowIterator iterator(DecoratedKey key,
+                                                            ColumnFilter 
selectedColumns,
+                                                            boolean reversed,
+                                                            boolean 
isForThrift,
+                                                            
SSTableReadsListener listener);
+
+    public abstract SliceableUnfilteredRowIterator iterator(FileDataInput file,
+                                                            DecoratedKey key,
+                                                            RowIndexEntry 
indexEntry,
+                                                            ColumnFilter 
selectedColumns,
+                                                            boolean reversed,
+                                                            boolean 
isForThrift);
 
     /**
      * Finds and returns the first key beyond a given token in this SSTable or 
null if no such key exists.
@@ -1656,11 +1675,15 @@ public abstract class SSTableReader extends SSTable 
implements SelfRefCounted<SS
     /**
      * @param columns the columns to return.
      * @param dataRange filter to use when reading the columns
+     * @param listener a listener used to handle internal read events
      * @return A Scanner for seeking over the rows of the SSTable.
      */
-    public ISSTableScanner getScanner(ColumnFilter columns, DataRange 
dataRange, boolean isForThrift)
+    public ISSTableScanner getScanner(ColumnFilter columns,
+                                      DataRange dataRange,
+                                      boolean isForThrift,
+                                      SSTableReadsListener listener)
     {
-        return getScanner(columns, dataRange, null, isForThrift);
+        return getScanner(columns, dataRange, null, isForThrift, listener);
     }
 
     /**
@@ -1702,9 +1725,14 @@ public abstract class SSTableReader extends SSTable 
implements SelfRefCounted<SS
     /**
      * @param columns the columns to return.
      * @param dataRange filter to use when reading the columns
+     * @param listener a listener used to handle internal read events
      * @return A Scanner for seeking over the rows of the SSTable.
      */
-    public abstract ISSTableScanner getScanner(ColumnFilter columns, DataRange 
dataRange, RateLimiter limiter, boolean isForThrift);
+    public abstract ISSTableScanner getScanner(ColumnFilter columns,
+                                               DataRange dataRange,
+                                               RateLimiter limiter,
+                                               boolean isForThrift,
+                                               SSTableReadsListener listener);
 
     public FileDataInput getFileDataInput(long position)
     {
@@ -1953,8 +1981,8 @@ public abstract class SSTableReader extends SSTable 
implements SelfRefCounted<SS
     }
 
     /**
-     * Increment the total row read count and read rate for this SSTable.  
This should not be incremented for range
-     * slice queries, row cache hits, or non-query reads, like compaction.
+     * Increment the total read count and read rate for this SSTable.  This 
should not be incremented for non-query reads,
+     * like compaction.
      */
     public void incrementReadCount()
     {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e22cb278/src/java/org/apache/cassandra/io/sstable/format/SSTableReadsListener.java
----------------------------------------------------------------------
diff --git 
a/src/java/org/apache/cassandra/io/sstable/format/SSTableReadsListener.java 
b/src/java/org/apache/cassandra/io/sstable/format/SSTableReadsListener.java
new file mode 100644
index 0000000..6d384bf
--- /dev/null
+++ b/src/java/org/apache/cassandra/io/sstable/format/SSTableReadsListener.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cassandra.io.sstable.format;
+
+import org.apache.cassandra.db.RowIndexEntry;
+
+/**
+ * Listener for receiving notifications associated with reading SSTables.
+ */
+public interface SSTableReadsListener
+{
+    /**
+     * The reasons for skipping an SSTable
+     */
+    enum SkippingReason
+    {
+        BLOOM_FILTER,
+        MIN_MAX_KEYS,
+        PARTITION_INDEX_LOOKUP,
+        INDEX_ENTRY_NOT_FOUND;
+    }
+
+    /**
+     * The reasons for selecting an SSTable
+     */
+    enum SelectionReason
+    {
+        KEY_CACHE_HIT,
+        INDEX_ENTRY_FOUND;
+    }
+
+    /**
+     * Listener that does nothing.
+     */
+    static final SSTableReadsListener NOOP_LISTENER = new 
SSTableReadsListener() {};
+
+    /**
+     * Handles notification that the specified SSTable has been skipped during 
a single partition query.
+     *
+     * @param sstable the SSTable reader
+     * @param reason the reason for which the SSTable has been skipped
+     */
+    default void onSSTableSkipped(SSTableReader sstable, SkippingReason reason)
+    {
+    }
+
+    /**
+     * Handles notification that the specified SSTable has been selected 
during a single partition query.
+     *
+     * @param sstable the SSTable reader
+     * @param indexEntry the index entry
+     * @param reason the reason for which the SSTable has been selected
+     */
+    default void onSSTableSelected(SSTableReader sstable, RowIndexEntry<?> 
indexEntry, SelectionReason reason)
+    {
+    }
+
+    /**
+     * Handles notification that the specified SSTable is being scanned during 
a partition range query.
+     *
+     * @param sstable the SSTable reader of the SSTable being scanned.
+     */
+    default void onScanningStarted(SSTableReader sstable)
+    {
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e22cb278/src/java/org/apache/cassandra/io/sstable/format/big/BigTableReader.java
----------------------------------------------------------------------
diff --git 
a/src/java/org/apache/cassandra/io/sstable/format/big/BigTableReader.java 
b/src/java/org/apache/cassandra/io/sstable/format/big/BigTableReader.java
index 1fbf1f2..eeea18f 100644
--- a/src/java/org/apache/cassandra/io/sstable/format/big/BigTableReader.java
+++ b/src/java/org/apache/cassandra/io/sstable/format/big/BigTableReader.java
@@ -33,6 +33,9 @@ import 
org.apache.cassandra.io.sstable.CorruptSSTableException;
 import org.apache.cassandra.io.sstable.Descriptor;
 import org.apache.cassandra.io.sstable.ISSTableScanner;
 import org.apache.cassandra.io.sstable.format.SSTableReader;
+import org.apache.cassandra.io.sstable.format.SSTableReadsListener;
+import 
org.apache.cassandra.io.sstable.format.SSTableReadsListener.SkippingReason;
+import 
org.apache.cassandra.io.sstable.format.SSTableReadsListener.SelectionReason;
 import org.apache.cassandra.io.sstable.metadata.StatsMetadata;
 import org.apache.cassandra.io.util.FileDataInput;
 import org.apache.cassandra.tracing.Tracing;
@@ -57,11 +60,15 @@ public class BigTableReader extends SSTableReader
         super(desc, components, metadata, maxDataAge, sstableMetadata, 
openReason, header);
     }
 
-    public SliceableUnfilteredRowIterator iterator(DecoratedKey key, 
ColumnFilter selectedColumns, boolean reversed, boolean isForThrift)
+    public SliceableUnfilteredRowIterator iterator(DecoratedKey key,
+                                                   ColumnFilter 
selectedColumns,
+                                                   boolean reversed,
+                                                   boolean isForThrift,
+                                                   SSTableReadsListener 
listener)
     {
         return reversed
-             ? new SSTableReversedIterator(this, key, selectedColumns, 
isForThrift)
-             : new SSTableIterator(this, key, selectedColumns, isForThrift);
+             ? new SSTableReversedIterator(this, key, selectedColumns, 
isForThrift, listener)
+             : new SSTableIterator(this, key, selectedColumns, isForThrift, 
listener);
     }
 
     public SliceableUnfilteredRowIterator iterator(FileDataInput file, 
DecoratedKey key, RowIndexEntry indexEntry, ColumnFilter selectedColumns, 
boolean reversed, boolean isForThrift)
@@ -71,14 +78,14 @@ public class BigTableReader extends SSTableReader
              : new SSTableIterator(this, file, key, indexEntry, 
selectedColumns, isForThrift);
     }
 
-    /**
-     * @param columns the columns to return.
-     * @param dataRange filter to use when reading the columns
-     * @return A Scanner for seeking over the rows of the SSTable.
-     */
-    public ISSTableScanner getScanner(ColumnFilter columns, DataRange 
dataRange, RateLimiter limiter, boolean isForThrift)
+    @Override
+    public ISSTableScanner getScanner(ColumnFilter columns,
+                                      DataRange dataRange,
+                                      RateLimiter limiter,
+                                      boolean isForThrift,
+                                      SSTableReadsListener listener)
     {
-        return BigTableScanner.getScanner(this, columns, dataRange, limiter, 
isForThrift);
+        return BigTableScanner.getScanner(this, columns, dataRange, limiter, 
isForThrift, listener);
     }
 
     /**
@@ -122,15 +129,21 @@ public class BigTableReader extends SSTableReader
      * allow key selection by token bounds but only if op != * EQ
      * @param op The Operator defining matching keys: the nearest key to the 
target matching the operator wins.
      * @param updateCacheAndStats true if updating stats and cache
+     * @param listener a listener used to handle internal events
      * @return The index entry corresponding to the key, or null if the key is 
not present
      */
-    protected RowIndexEntry getPosition(PartitionPosition key, Operator op, 
boolean updateCacheAndStats, boolean permitMatchPastLast)
+    protected RowIndexEntry getPosition(PartitionPosition key,
+                                        Operator op,
+                                        boolean updateCacheAndStats,
+                                        boolean permitMatchPastLast,
+                                        SSTableReadsListener listener)
     {
         if (op == Operator.EQ)
         {
             assert key instanceof DecoratedKey; // EQ only make sense if the 
key is a valid row key
             if (!bf.isPresent((DecoratedKey)key))
             {
+                listener.onSSTableSkipped(this, SkippingReason.BLOOM_FILTER);
                 Tracing.trace("Bloom filter allows skipping sstable {}", 
descriptor.generation);
                 return null;
             }
@@ -144,6 +157,7 @@ public class BigTableReader extends SSTableReader
             RowIndexEntry cachedPosition = getCachedPosition(cacheKey, 
updateCacheAndStats);
             if (cachedPosition != null)
             {
+                listener.onSSTableSelected(this, cachedPosition, 
SelectionReason.KEY_CACHE_HIT);
                 Tracing.trace("Key cache hit for sstable {}", 
descriptor.generation);
                 return cachedPosition;
             }
@@ -172,6 +186,7 @@ public class BigTableReader extends SSTableReader
         {
             if (op == Operator.EQ && updateCacheAndStats)
                 bloomFilterTracker.addFalsePositive();
+            listener.onSSTableSkipped(this, SkippingReason.MIN_MAX_KEYS);
             Tracing.trace("Check against min and max keys allows skipping 
sstable {}", descriptor.generation);
             return null;
         }
@@ -219,6 +234,7 @@ public class BigTableReader extends SSTableReader
                     exactMatch = (comparison == 0);
                     if (v < 0)
                     {
+                        listener.onSSTableSkipped(this, 
SkippingReason.PARTITION_INDEX_LOOKUP);
                         Tracing.trace("Partition index lookup allows skipping 
sstable {}", descriptor.generation);
                         return null;
                     }
@@ -249,6 +265,7 @@ public class BigTableReader extends SSTableReader
                     }
                     if (op == Operator.EQ && updateCacheAndStats)
                         bloomFilterTracker.addTruePositive();
+                    listener.onSSTableSelected(this, indexEntry, 
SelectionReason.INDEX_ENTRY_FOUND);
                     Tracing.trace("Partition index with {} entries found for 
sstable {}", indexEntry.columnsIndex().size(), descriptor.generation);
                     return indexEntry;
                 }
@@ -264,6 +281,7 @@ public class BigTableReader extends SSTableReader
 
         if (op == SSTableReader.Operator.EQ && updateCacheAndStats)
             bloomFilterTracker.addFalsePositive();
+        listener.onSSTableSkipped(this, SkippingReason.INDEX_ENTRY_NOT_FOUND);
         Tracing.trace("Partition index lookup complete (bloom filter false 
positive) for sstable {}", descriptor.generation);
         return null;
     }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e22cb278/src/java/org/apache/cassandra/io/sstable/format/big/BigTableScanner.java
----------------------------------------------------------------------
diff --git 
a/src/java/org/apache/cassandra/io/sstable/format/big/BigTableScanner.java 
b/src/java/org/apache/cassandra/io/sstable/format/big/BigTableScanner.java
index a3bd442..82d8211 100644
--- a/src/java/org/apache/cassandra/io/sstable/format/big/BigTableScanner.java
+++ b/src/java/org/apache/cassandra/io/sstable/format/big/BigTableScanner.java
@@ -39,6 +39,7 @@ import 
org.apache.cassandra.io.sstable.CorruptSSTableException;
 import org.apache.cassandra.io.sstable.ISSTableScanner;
 import org.apache.cassandra.io.sstable.SSTableIdentityIterator;
 import org.apache.cassandra.io.sstable.format.SSTableReader;
+import org.apache.cassandra.io.sstable.format.SSTableReadsListener;
 import org.apache.cassandra.io.util.FileUtils;
 import org.apache.cassandra.io.util.RandomAccessReader;
 import org.apache.cassandra.utils.ByteBufferUtil;
@@ -62,18 +63,30 @@ public class BigTableScanner implements ISSTableScanner
     private final DataRange dataRange;
     private final RowIndexEntry.IndexSerializer rowIndexEntrySerializer;
     private final boolean isForThrift;
+    private final SSTableReadsListener listener;
 
     protected Iterator<UnfilteredRowIterator> iterator;
 
     // Full scan of the sstables
     public static ISSTableScanner getScanner(SSTableReader sstable, 
RateLimiter limiter)
     {
-        return new BigTableScanner(sstable, 
ColumnFilter.all(sstable.metadata), null, limiter, false, 
Iterators.singletonIterator(fullRange(sstable)));
+        return new BigTableScanner(sstable, limiter, 
Iterators.singletonIterator(fullRange(sstable)));
     }
 
-    public static ISSTableScanner getScanner(SSTableReader sstable, 
ColumnFilter columns, DataRange dataRange, RateLimiter limiter, boolean 
isForThrift)
+    public static ISSTableScanner getScanner(SSTableReader sstable,
+                                             ColumnFilter columns,
+                                             DataRange dataRange,
+                                             RateLimiter limiter,
+                                             boolean isForThrift,
+                                             SSTableReadsListener listener)
     {
-        return new BigTableScanner(sstable, columns, dataRange, limiter, 
isForThrift, makeBounds(sstable, dataRange).iterator());
+        return new BigTableScanner(sstable,
+                                   columns,
+                                   dataRange,
+                                   limiter,
+                                   isForThrift,
+                                   makeBounds(sstable, dataRange).iterator(),
+                                   listener);
     }
 
     public static ISSTableScanner getScanner(SSTableReader sstable, 
Collection<Range<Token>> tokenRanges, RateLimiter limiter)
@@ -83,15 +96,28 @@ public class BigTableScanner implements ISSTableScanner
         if (positions.isEmpty())
             return new EmptySSTableScanner(sstable);
 
-        return new BigTableScanner(sstable, 
ColumnFilter.all(sstable.metadata), null, limiter, false, makeBounds(sstable, 
tokenRanges).iterator());
+        return new BigTableScanner(sstable, limiter, makeBounds(sstable, 
tokenRanges).iterator());
     }
 
     public static ISSTableScanner getScanner(SSTableReader sstable, 
Iterator<AbstractBounds<PartitionPosition>> rangeIterator)
     {
-        return new BigTableScanner(sstable, 
ColumnFilter.all(sstable.metadata), null, null, false, rangeIterator);
+        return new BigTableScanner(sstable, null, rangeIterator);
     }
 
-    private BigTableScanner(SSTableReader sstable, ColumnFilter columns, 
DataRange dataRange, RateLimiter limiter, boolean isForThrift, 
Iterator<AbstractBounds<PartitionPosition>> rangeIterator)
+    private BigTableScanner(SSTableReader sstable,
+                            RateLimiter limiter,
+                            Iterator<AbstractBounds<PartitionPosition>> 
rangeIterator)
+    {
+        this(sstable, ColumnFilter.all(sstable.metadata), null, limiter, 
false, rangeIterator, SSTableReadsListener.NOOP_LISTENER);
+    }
+
+    private BigTableScanner(SSTableReader sstable,
+                            ColumnFilter columns,
+                            DataRange dataRange,
+                            RateLimiter limiter,
+                            boolean isForThrift,
+                            Iterator<AbstractBounds<PartitionPosition>> 
rangeIterator,
+                            SSTableReadsListener listener)
     {
         assert sstable != null;
 
@@ -105,6 +131,7 @@ public class BigTableScanner implements ISSTableScanner
                                                                                
                         sstable.header);
         this.isForThrift = isForThrift;
         this.rangeIterator = rangeIterator;
+        this.listener = listener;
     }
 
     private static List<AbstractBounds<PartitionPosition>> 
makeBounds(SSTableReader sstable, Collection<Range<Token>> tokenRanges)
@@ -259,6 +286,7 @@ public class BigTableScanner implements ISSTableScanner
 
     private Iterator<UnfilteredRowIterator> createIterator()
     {
+        listener.onScanningStarted(sstable);
         return new KeyScanningIterator();
     }
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e22cb278/test/unit/org/apache/cassandra/cql3/CQLTester.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/CQLTester.java 
b/test/unit/org/apache/cassandra/cql3/CQLTester.java
index db3652b..39278f0 100644
--- a/test/unit/org/apache/cassandra/cql3/CQLTester.java
+++ b/test/unit/org/apache/cassandra/cql3/CQLTester.java
@@ -367,21 +367,36 @@ public abstract class CQLTester
         return list.isEmpty() ? Collections.<String>emptyList() : new 
ArrayList<>(list);
     }
 
-    public ColumnFamilyStore getCurrentColumnFamilyStore()
+    public ColumnFamilyStore getCurrentColumnFamilyStore(String keyspace)
     {
         String currentTable = currentTable();
         return currentTable == null
              ? null
-             : Keyspace.open(KEYSPACE).getColumnFamilyStore(currentTable);
+             : Keyspace.open(keyspace).getColumnFamilyStore(currentTable);
+    }
+
+    public ColumnFamilyStore getCurrentColumnFamilyStore()
+    {
+        return getCurrentColumnFamilyStore(KEYSPACE);
     }
 
     public void flush()
     {
-        ColumnFamilyStore store = getCurrentColumnFamilyStore();
+        flush(KEYSPACE);
+    }
+
+    public void flush(String keyspace)
+    {
+        ColumnFamilyStore store = getCurrentColumnFamilyStore(keyspace);
         if (store != null)
             store.forceBlockingFlush();
     }
 
+    public void disableCompaction(String keyspace)
+    {
+        ColumnFamilyStore store = getCurrentColumnFamilyStore(keyspace);
+        store.disableAutoCompaction();
+    }
 
     public void flush(boolean forceFlush)
     {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e22cb278/test/unit/org/apache/cassandra/cql3/validation/miscellaneous/SSTablesIteratedTest.java
----------------------------------------------------------------------
diff --git 
a/test/unit/org/apache/cassandra/cql3/validation/miscellaneous/SSTablesIteratedTest.java
 
b/test/unit/org/apache/cassandra/cql3/validation/miscellaneous/SSTablesIteratedTest.java
new file mode 100644
index 0000000..2cf518a
--- /dev/null
+++ 
b/test/unit/org/apache/cassandra/cql3/validation/miscellaneous/SSTablesIteratedTest.java
@@ -0,0 +1,136 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.cassandra.cql3.validation.miscellaneous;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import org.apache.cassandra.cql3.CQLTester;
+import org.apache.cassandra.cql3.UntypedResultSet;
+import org.apache.cassandra.db.ColumnFamilyStore;
+import org.apache.cassandra.metrics.ClearableHistogram;
+
+/**
+ * Tests for checking how many sstables we access during cql queries.
+ */
+public class SSTablesIteratedTest extends CQLTester
+{
+    private void executeAndCheck(String query, int numSSTables, Object[]... 
rows) throws Throwable
+    {
+        ColumnFamilyStore cfs = getCurrentColumnFamilyStore(KEYSPACE_PER_TEST);
+
+        ((ClearableHistogram) cfs.metric.sstablesPerReadHistogram.cf).clear(); 
// resets counts
+
+        assertRows(execute(query), rows);
+
+        long numSSTablesIterated = 
cfs.metric.sstablesPerReadHistogram.cf.getSnapshot().getMax(); // max sstables 
read
+        assertEquals(String.format("Expected %d sstables iterated but got %d 
instead, with %d live sstables",
+                                   numSSTables, numSSTablesIterated, 
cfs.getLiveSSTables().size()),
+                     numSSTables,
+                     numSSTablesIterated);
+    }
+
+    @Override
+    protected String createTable(String query)
+    {
+        String ret = super.createTable(KEYSPACE_PER_TEST, query);
+        disableCompaction(KEYSPACE_PER_TEST);
+        return ret;
+    }
+
+    @Override
+    protected UntypedResultSet execute(String query, Object... values) throws 
Throwable
+    {
+        return executeFormattedQuery(formatQuery(KEYSPACE_PER_TEST, query), 
values);
+    }
+
+    @Override
+    public void flush()
+    {
+        super.flush(KEYSPACE_PER_TEST);
+    }
+
+    @Test
+    public void testSinglePartitionQuery() throws Throwable
+    {
+        createTable("CREATE TABLE %s (pk int, c int, v text, PRIMARY KEY (pk, 
c))");
+
+        execute("INSERT INTO %s (pk, c, v) VALUES (?, ?, ?)", 1, 40, "41");
+        execute("INSERT INTO %s (pk, c, v) VALUES (?, ?, ?)", 2, 10, "12");
+        flush();
+
+        execute("INSERT INTO %s (pk, c, v) VALUES (?, ?, ?)", 1, 10, "11");
+        execute("INSERT INTO %s (pk, c, v) VALUES (?, ?, ?)", 3, 30, "33");
+        flush();
+
+        execute("INSERT INTO %s (pk, c, v) VALUES (?, ?, ?)", 1, 20, "21");
+        execute("INSERT INTO %s (pk, c, v) VALUES (?, ?, ?)", 2, 40, "42");
+        execute("UPDATE %s SET v = '12' WHERE pk = 2 AND c = 10");
+        flush();
+
+        // Test with all the table being merged
+        executeAndCheck("SELECT * FROM %s WHERE pk = 1", 3,
+                        row(1, 10, "11"),
+                        row(1, 20, "21"),
+                        row(1, 40, "41"));
+
+        // Test with only 2 of the 3 SSTables being merged
+        executeAndCheck("SELECT * FROM %s WHERE pk = 2", 2,
+                        row(2, 10, "12"),
+                        row(2, 40, "42"));
+
+        executeAndCheck("SELECT * FROM %s WHERE pk = 2 ORDER BY c DESC", 2,
+                        row(2, 40, "42"),
+                        row(2, 10, "12"));
+
+        // Test with only 2 of the 3 SSTables being merged and a Slice filter
+        executeAndCheck("SELECT * FROM %s WHERE pk = 2 AND c > 20", 2,
+                        row(2, 40, "42"));
+
+        executeAndCheck("SELECT * FROM %s WHERE pk = 2 AND c > 20 ORDER BY c 
DESC", 2,
+                        row(2, 40, "42"));
+
+        // Test with only 2 of the 3 SSTables being merged and a Name filter
+        // This test checks the 
SinglePartitionReadCommand::queryMemtableAndSSTablesInTimestampOrder which is 
only
+        // used for ClusteringIndexNamesFilter when there are no multi-cell 
columns
+        executeAndCheck("SELECT * FROM %s WHERE pk = 2 AND c = 10", 2,
+                        row(2, 10, "12"));
+
+        // For partition range queries the metric must not be updated. The 
reason being that range queries simply
+        // scan all the SSTables containing data within the partition range. 
Due to that they might pollute the metric
+        // and give a wrong view of the system.
+        executeAndCheck("SELECT * FROM %s", 0,
+                        row(1, 10, "11"),
+                        row(1, 20, "21"),
+                        row(1, 40, "41"),
+                        row(2, 10, "12"),
+                        row(2, 40, "42"),
+                        row(3, 30, "33"));
+
+        executeAndCheck("SELECT * FROM %s WHERE token(pk) = token(1)", 0,
+                        row(1, 10, "11"),
+                        row(1, 20, "21"),
+                        row(1, 40, "41"));
+
+        assertInvalidMessage("ORDER BY is only supported when the partition 
key is restricted by an EQ or an IN",
+                             "SELECT * FROM %s WHERE token(pk) = token(1) 
ORDER BY C DESC");
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e22cb278/test/unit/org/apache/cassandra/db/compaction/TTLExpiryTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/db/compaction/TTLExpiryTest.java 
b/test/unit/org/apache/cassandra/db/compaction/TTLExpiryTest.java
index eb42865..e0378f6 100644
--- a/test/unit/org/apache/cassandra/db/compaction/TTLExpiryTest.java
+++ b/test/unit/org/apache/cassandra/db/compaction/TTLExpiryTest.java
@@ -33,12 +33,12 @@ import org.apache.cassandra.SchemaLoader;
 import org.apache.cassandra.Util;
 import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.db.*;
-import org.apache.cassandra.db.rows.BTreeRow;
 import org.apache.cassandra.db.filter.ColumnFilter;
 import org.apache.cassandra.db.lifecycle.SSTableSet;
 import org.apache.cassandra.db.rows.UnfilteredRowIterator;
 import org.apache.cassandra.db.marshal.*;
 import org.apache.cassandra.io.sstable.format.SSTableReader;
+import org.apache.cassandra.io.sstable.format.SSTableReadsListener;
 import org.apache.cassandra.exceptions.ConfigurationException;
 import org.apache.cassandra.io.sstable.ISSTableScanner;
 import org.apache.cassandra.schema.KeyspaceParams;
@@ -243,7 +243,10 @@ public class TTLExpiryTest
         cfs.enableAutoCompaction(true);
         assertEquals(1, cfs.getLiveSSTables().size());
         SSTableReader sstable = cfs.getLiveSSTables().iterator().next();
-        ISSTableScanner scanner = 
sstable.getScanner(ColumnFilter.all(sstable.metadata), 
DataRange.allData(cfs.getPartitioner()), false);
+        ISSTableScanner scanner = 
sstable.getScanner(ColumnFilter.all(sstable.metadata),
+                                                     
DataRange.allData(cfs.getPartitioner()),
+                                                     false,
+                                                     
SSTableReadsListener.NOOP_LISTENER);
         assertTrue(scanner.hasNext());
         while(scanner.hasNext())
         {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e22cb278/test/unit/org/apache/cassandra/io/sstable/SSTableCorruptionDetectionTest.java
----------------------------------------------------------------------
diff --git 
a/test/unit/org/apache/cassandra/io/sstable/SSTableCorruptionDetectionTest.java 
b/test/unit/org/apache/cassandra/io/sstable/SSTableCorruptionDetectionTest.java
index 4da8519..451af25 100644
--- 
a/test/unit/org/apache/cassandra/io/sstable/SSTableCorruptionDetectionTest.java
+++ 
b/test/unit/org/apache/cassandra/io/sstable/SSTableCorruptionDetectionTest.java
@@ -42,6 +42,7 @@ import org.apache.cassandra.db.lifecycle.LifecycleTransaction;
 import org.apache.cassandra.db.marshal.*;
 import org.apache.cassandra.db.rows.*;
 import org.apache.cassandra.io.sstable.format.SSTableReader;
+import org.apache.cassandra.io.sstable.format.SSTableReadsListener;
 import org.apache.cassandra.io.sstable.format.SSTableWriter;
 import org.apache.cassandra.io.util.*;
 import org.apache.cassandra.schema.*;
@@ -207,7 +208,11 @@ public class SSTableCorruptionDetectionTest extends 
SSTableWriterTestBase
             for (int i = 0; i < numberOfPks; i++)
             {
                 DecoratedKey dk = Util.dk(String.format("pkvalue_%07d", i));
-                try (UnfilteredRowIterator rowIter = sstable.iterator(dk, 
ColumnFilter.all(cfs.metadata), false, false))
+                try (UnfilteredRowIterator rowIter = sstable.iterator(dk,
+                                                                      
ColumnFilter.all(cfs.metadata),
+                                                                      false,
+                                                                      false,
+                                                                      
SSTableReadsListener.NOOP_LISTENER))
                 {
                     while (rowIter.hasNext())
                     {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e22cb278/test/unit/org/apache/cassandra/io/sstable/SSTableScannerTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/io/sstable/SSTableScannerTest.java 
b/test/unit/org/apache/cassandra/io/sstable/SSTableScannerTest.java
index d73c278..cf57b17 100644
--- a/test/unit/org/apache/cassandra/io/sstable/SSTableScannerTest.java
+++ b/test/unit/org/apache/cassandra/io/sstable/SSTableScannerTest.java
@@ -46,6 +46,7 @@ import org.apache.cassandra.dht.ByteOrderedPartitioner;
 import org.apache.cassandra.dht.Range;
 import org.apache.cassandra.dht.Token;
 import org.apache.cassandra.io.sstable.format.SSTableReader;
+import org.apache.cassandra.io.sstable.format.SSTableReadsListener;
 import org.apache.cassandra.schema.KeyspaceParams;
 import org.apache.cassandra.utils.ByteBufferUtil;
 
@@ -182,7 +183,10 @@ public class SSTableScannerTest
         assert boundaries.length % 2 == 0;
         for (DataRange range : dataRanges(sstable.metadata, scanStart, 
scanEnd))
         {
-            try(ISSTableScanner scanner = 
sstable.getScanner(ColumnFilter.all(sstable.metadata), range, false))
+            try(ISSTableScanner scanner = 
sstable.getScanner(ColumnFilter.all(sstable.metadata),
+                                                             range,
+                                                             false,
+                                                             
SSTableReadsListener.NOOP_LISTENER))
             {
                 for (int b = 0; b < boundaries.length; b += 2)
                     for (int i = boundaries[b]; i <= boundaries[b + 1]; i++)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e22cb278/test/unit/org/apache/cassandra/io/sstable/SSTableWriterTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/io/sstable/SSTableWriterTest.java 
b/test/unit/org/apache/cassandra/io/sstable/SSTableWriterTest.java
index 6f18461..e714c60 100644
--- a/test/unit/org/apache/cassandra/io/sstable/SSTableWriterTest.java
+++ b/test/unit/org/apache/cassandra/io/sstable/SSTableWriterTest.java
@@ -30,6 +30,7 @@ import org.apache.cassandra.db.filter.*;
 import org.apache.cassandra.db.lifecycle.LifecycleTransaction;
 import org.apache.cassandra.db.rows.*;
 import org.apache.cassandra.io.sstable.format.SSTableReader;
+import org.apache.cassandra.io.sstable.format.SSTableReadsListener;
 import org.apache.cassandra.io.sstable.format.SSTableWriter;
 import org.apache.cassandra.utils.FBUtilities;
 
@@ -223,7 +224,11 @@ public class SSTableWriterTest extends 
SSTableWriterTestBase
             try
             {
                 DecoratedKey dk = Util.dk("large_value");
-                UnfilteredRowIterator rowIter = sstable.iterator(dk, 
ColumnFilter.all(cfs.metadata), false, false);
+                UnfilteredRowIterator rowIter = sstable.iterator(dk,
+                                                                 
ColumnFilter.all(cfs.metadata),
+                                                                 false,
+                                                                 false,
+                                                                 
SSTableReadsListener.NOOP_LISTENER);
                 while (rowIter.hasNext())
                 {
                     rowIter.next();

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e22cb278/test/unit/org/apache/cassandra/io/sstable/format/ClientModeSSTableTest.java
----------------------------------------------------------------------
diff --git 
a/test/unit/org/apache/cassandra/io/sstable/format/ClientModeSSTableTest.java 
b/test/unit/org/apache/cassandra/io/sstable/format/ClientModeSSTableTest.java
index 661fcd5..48a8af5 100644
--- 
a/test/unit/org/apache/cassandra/io/sstable/format/ClientModeSSTableTest.java
+++ 
b/test/unit/org/apache/cassandra/io/sstable/format/ClientModeSSTableTest.java
@@ -107,7 +107,11 @@ public class ClientModeSSTableTest
 
             ByteBuffer key = bytes(Integer.toString(100));
 
-            try (SliceableUnfilteredRowIterator iter = 
reader.iterator(metadata.decorateKey(key), 
ColumnFilter.selection(metadata.partitionColumns()), false, false))
+            try (SliceableUnfilteredRowIterator iter = 
reader.iterator(metadata.decorateKey(key),
+                                                                       
ColumnFilter.selection(metadata.partitionColumns()),
+                                                                       false,
+                                                                       false,
+                                                                       
SSTableReadsListener.NOOP_LISTENER))
             {
                 assert iter.next().clustering().get(0).equals(key);
             }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org
For additional commands, e-mail: commits-h...@cassandra.apache.org

Reply via email to