Author: slebresne Date: Fri Dec 23 16:25:19 2011 New Revision: 1222728 URL: http://svn.apache.org/viewvc?rev=1222728&view=rev Log: Optimize memtable iteration during range scan patch by slebresne; reviewed by jbellis for CASSANDRA-3638
Modified: cassandra/trunk/CHANGES.txt cassandra/trunk/src/java/org/apache/cassandra/db/Memtable.java cassandra/trunk/src/java/org/apache/cassandra/db/RowIteratorFactory.java Modified: cassandra/trunk/CHANGES.txt URL: http://svn.apache.org/viewvc/cassandra/trunk/CHANGES.txt?rev=1222728&r1=1222727&r2=1222728&view=diff ============================================================================== --- cassandra/trunk/CHANGES.txt (original) +++ cassandra/trunk/CHANGES.txt Fri Dec 23 16:25:19 2011 @@ -29,6 +29,7 @@ * fsync the directory after new sstable or commitlog segment are created (CASSANDRA-3250) * fix minor issues reported by FindBugs (CASSANDRA-3658) * global key/row caches (CASSANDRA-3143) + * optimize memtable iteration during range scan (CASSANDRA-3638) 1.0.7 * add nodetool setstreamthroughput (CASSANDRA-3571) Modified: cassandra/trunk/src/java/org/apache/cassandra/db/Memtable.java URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/Memtable.java?rev=1222728&r1=1222727&r2=1222728&view=diff ============================================================================== --- cassandra/trunk/src/java/org/apache/cassandra/db/Memtable.java (original) +++ cassandra/trunk/src/java/org/apache/cassandra/db/Memtable.java Fri Dec 23 16:25:19 2011 @@ -309,11 +309,13 @@ public class Memtable * @param startWith Include data in the result from and including this key and to the end of the memtable * @return An iterator of entries with the data from the start key */ - public Iterator<Map.Entry<DecoratedKey, ColumnFamily>> getEntryIterator(final RowPosition startWith) + public Iterator<Map.Entry<DecoratedKey, ColumnFamily>> getEntryIterator(final RowPosition startWith, final RowPosition stopAt) { return new Iterator<Map.Entry<DecoratedKey, ColumnFamily>>() { - private Iterator<Map.Entry<RowPosition, ColumnFamily>> iter = columnFamilies.tailMap(startWith).entrySet().iterator(); + private Iterator<Map.Entry<RowPosition, ColumnFamily>> iter = stopAt.isMinimum() + ? columnFamilies.tailMap(startWith).entrySet().iterator() + : columnFamilies.subMap(startWith, true, stopAt, true).entrySet().iterator(); public boolean hasNext() { Modified: cassandra/trunk/src/java/org/apache/cassandra/db/RowIteratorFactory.java URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/RowIteratorFactory.java?rev=1222728&r1=1222727&r2=1222728&view=diff ============================================================================== --- cassandra/trunk/src/java/org/apache/cassandra/db/RowIteratorFactory.java (original) +++ cassandra/trunk/src/java/org/apache/cassandra/db/RowIteratorFactory.java Fri Dec 23 16:25:19 2011 @@ -65,21 +65,11 @@ public class RowIteratorFactory { // fetch data from current memtable, historical memtables, and SSTables in the correct order. final List<CloseableIterator<IColumnIterator>> iterators = new ArrayList<CloseableIterator<IColumnIterator>>(); - // we iterate through memtables with a priority queue to avoid more sorting than necessary. - // this predicate throws out the rows before the start of our range. - Predicate<IColumnIterator> p = new Predicate<IColumnIterator>() - { - public boolean apply(IColumnIterator row) - { - return startWith.compareTo(row.getKey()) <= 0 - && (stopAt.isMinimum() || row.getKey().compareTo(stopAt) <= 0); - } - }; // memtables for (Memtable memtable : memtables) { - iterators.add(new ConvertToColumnIterator(filter, p, memtable.getEntryIterator(startWith))); + iterators.add(new ConvertToColumnIterator(filter, memtable.getEntryIterator(startWith, stopAt))); } for (SSTableReader sstable : sstables) @@ -139,24 +129,20 @@ public class RowIteratorFactory private static class ConvertToColumnIterator extends AbstractIterator<IColumnIterator> implements CloseableIterator<IColumnIterator> { private final QueryFilter filter; - private final Predicate<IColumnIterator> pred; private final Iterator<Map.Entry<DecoratedKey, ColumnFamily>> iter; - public ConvertToColumnIterator(QueryFilter filter, Predicate<IColumnIterator> pred, Iterator<Map.Entry<DecoratedKey, ColumnFamily>> iter) + public ConvertToColumnIterator(QueryFilter filter, Iterator<Map.Entry<DecoratedKey, ColumnFamily>> iter) { this.filter = filter; - this.pred = pred; this.iter = iter; } public IColumnIterator computeNext() { - while (iter.hasNext()) + if (iter.hasNext()) { Map.Entry<DecoratedKey, ColumnFamily> entry = iter.next(); - IColumnIterator ici = filter.getMemtableColumnIterator(entry.getValue(), entry.getKey()); - if (pred.apply(ici)) - return ici; + return filter.getMemtableColumnIterator(entry.getValue(), entry.getKey()); } return endOfData(); }