Author: stack
Date: Tue Jul 28 12:51:36 2009
New Revision: 798510
URL: http://svn.apache.org/viewvc?rev=798510&view=rev
Log:
HBASE-1647 Filter#filterRow is called too often, filters rows it shouldn't have
-- reversed it for a moment; it may have broken things -- not sure yet
Modified:
hadoop/hbase/trunk/CHANGES.txt
hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HRegion.java
hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/QueryMatcher.java
hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java
hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java
hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/regionserver/TestScanner.java
hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/regionserver/TestStoreScanner.java
Modified: hadoop/hbase/trunk/CHANGES.txt
URL:
http://svn.apache.org/viewvc/hadoop/hbase/trunk/CHANGES.txt?rev=798510&r1=798509&r2=798510&view=diff
==============================================================================
--- hadoop/hbase/trunk/CHANGES.txt (original)
+++ hadoop/hbase/trunk/CHANGES.txt Tue Jul 28 12:51:36 2009
@@ -295,8 +295,6 @@
(Tim Sell and Ryan Rawson via Stack)
HBASE-1703 ICVs across /during a flush can cause multiple keys with the
same TS (bad)
- HBASE-1647 Filter#filterRow is called too often, filters rows it
- shouldn't have (DoÄacan Güney via Ryan Rawson and Stack)
IMPROVEMENTS
HBASE-1089 Add count of regions on filesystem to master UI; add percentage
Modified:
hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HRegion.java
URL:
http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HRegion.java?rev=798510&r1=798509&r2=798510&view=diff
==============================================================================
---
hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HRegion.java
(original)
+++
hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HRegion.java
Tue Jul 28 12:51:36 2009
@@ -53,8 +53,6 @@
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.Scan;
-import org.apache.hadoop.hbase.filter.Filter;
-import org.apache.hadoop.hbase.filter.RowFilterInterface;
import org.apache.hadoop.hbase.io.HeapSize;
import org.apache.hadoop.hbase.io.Reference.Range;
import org.apache.hadoop.hbase.io.hfile.BlockCache;
@@ -1683,13 +1681,8 @@
class RegionScanner implements InternalScanner {
private final KeyValueHeap storeHeap;
private final byte [] stopRow;
- private Filter filter;
- private RowFilterInterface oldFilter;
- private List<KeyValue> results = new ArrayList<KeyValue>();
RegionScanner(Scan scan, List<KeyValueScanner> additionalScanners) {
- this.filter = scan.getFilter();
- this.oldFilter = scan.getOldFilter();
if (Bytes.equals(scan.getStopRow(), HConstants.EMPTY_END_ROW)) {
this.stopRow = null;
} else {
@@ -1713,74 +1706,46 @@
this(scan, null);
}
- private void resetFilters() {
- if (filter != null) {
- filter.reset();
- }
- if (oldFilter != null) {
- oldFilter.reset();
- }
- }
-
/**
* Get the next row of results from this region.
* @param results list to append results to
* @return true if there are more rows, false if scanner is done
*/
- @Override
- public boolean next(List<KeyValue> outResults) throws IOException {
- results.clear();
- boolean returnResult = nextInternal();
- if (!returnResult && filter != null && filter.filterRow()) {
- results.clear();
- }
- outResults.addAll(results);
- resetFilters();
- return returnResult;
- }
-
- private boolean nextInternal() throws IOException {
+ public boolean next(List<KeyValue> results)
+ throws IOException {
// This method should probably be reorganized a bit... has gotten messy
- KeyValue kv;
- byte[] currentRow = null;
- boolean filterCurrentRow = false;
+ KeyValue kv = this.storeHeap.peek();
+ if (kv == null) {
+ return false;
+ }
+ byte [] currentRow = kv.getRow();
+ // See if we passed stopRow
+ if (stopRow != null &&
+ comparator.compareRows(stopRow, 0, stopRow.length,
+ currentRow, 0, currentRow.length) <= 0) {
+ return false;
+ }
+ this.storeHeap.next(results);
while(true) {
kv = this.storeHeap.peek();
if (kv == null) {
return false;
}
byte [] row = kv.getRow();
- if (filterCurrentRow && Bytes.equals(currentRow, row)) {
- // filter all columns until row changes
- this.storeHeap.next(results);
- results.clear();
- continue;
- }
- // see if current row should be filtered based on row key
- if ((filter != null && filter.filterRowKey(row, 0, row.length)) ||
- (oldFilter != null && oldFilter.filterRowKey(row, 0, row.length)))
{
- this.storeHeap.next(results);
- results.clear();
- resetFilters();
- filterCurrentRow = true;
- currentRow = row;
- continue;
- }
if(!Bytes.equals(currentRow, row)) {
- // Continue on the next row:
- currentRow = row;
- filterCurrentRow = false;
- // See if we passed stopRow
- if(stopRow != null &&
- comparator.compareRows(stopRow, 0, stopRow.length,
- currentRow, 0, currentRow.length) <= 0) {
- return false;
- }
- // if there are _no_ results or current row should be filtered
- if (results.isEmpty() || filter != null && filter.filterRow()) {
- // make sure results is empty
- results.clear();
- resetFilters();
+ // Next row:
+
+ // what happens if there are _no_ results:
+ if (results.isEmpty()) {
+ // Continue on the next row:
+ currentRow = row;
+
+ // But did we pass the stop row?
+ if (stopRow != null &&
+ comparator.compareRows(stopRow, 0, stopRow.length,
+ currentRow, 0, currentRow.length) <= 0) {
+ return false;
+ }
continue;
}
return true;
Modified:
hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/QueryMatcher.java
URL:
http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/QueryMatcher.java?rev=798510&r1=798509&r2=798510&view=diff
==============================================================================
---
hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/QueryMatcher.java
(original)
+++
hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/QueryMatcher.java
Tue Jul 28 12:51:36 2009
@@ -325,6 +325,7 @@
public void reset() {
this.deletes.reset();
this.columns.reset();
+ if (this.filter != null) this.filter.reset();
}
/**
Modified:
hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java
URL:
http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java?rev=798510&r1=798509&r2=798510&view=diff
==============================================================================
---
hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java
(original)
+++
hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java
Tue Jul 28 12:51:36 2009
@@ -114,6 +114,16 @@
if (this.stickyNextRow)
return MatchCode.SEEK_NEXT_ROW;
+ // Give the row filter a chance to do it's job.
+ if (filter != null && filter.filterRowKey(bytes, offset, rowLength)) {
+ stickyNextRow = true; // optimize to keep from calling the filter too
much.
+ return MatchCode.SEEK_NEXT_ROW;
+ } else if (oldFilter != null && oldFilter.filterRowKey(bytes, offset,
rowLength)) {
+ stickyNextRow = true;
+ return MatchCode.SEEK_NEXT_ROW;
+ }
+
+
if (this.columns.done()) {
stickyNextRow = true;
return MatchCode.SEEK_NEXT_ROW;
@@ -190,6 +200,16 @@
}
/**
+ * If the row was otherwise going to be included, call this to last-minute
+ * check.
+ *
+ * @return <code>true</code> if the row should be filtered.
+ */
+ public boolean filterEntireRow() {
+ return filter == null? false: filter.filterRow();
+ }
+
+ /**
* Set current row
* @param row
*/
@@ -203,5 +223,7 @@
public void reset() {
super.reset();
stickyNextRow = false;
+ if (filter != null)
+ filter.reset();
}
}
\ No newline at end of file
Modified:
hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java
URL:
http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java?rev=798510&r1=798509&r2=798510&view=diff
==============================================================================
---
hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java
(original)
+++
hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java
Tue Jul 28 12:51:36 2009
@@ -162,12 +162,20 @@
continue;
case DONE:
+ if (matcher.filterEntireRow()) {
+ // nuke all results, and then return.
+ results.clear();
+ }
// copy jazz
outResult.addAll(results);
return true;
case DONE_SCAN:
+ if (matcher.filterEntireRow()) {
+ // nuke all results, and then return.
+ results.clear();
+ }
close();
// copy jazz
@@ -194,6 +202,11 @@
throw new RuntimeException("UNEXPECTED");
}
}
+
+ if (matcher.filterEntireRow()) {
+ // nuke all results, and then return.
+ results.clear();
+ }
if (!results.isEmpty()) {
// copy jazz
Modified:
hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/regionserver/TestScanner.java
URL:
http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/regionserver/TestScanner.java?rev=798510&r1=798509&r2=798510&view=diff
==============================================================================
---
hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/regionserver/TestScanner.java
(original)
+++
hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/regionserver/TestScanner.java
Tue Jul 28 12:51:36 2009
@@ -38,14 +38,6 @@
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.Scan;
-import org.apache.hadoop.hbase.filter.Filter;
-import org.apache.hadoop.hbase.filter.InclusiveStopFilter;
-import org.apache.hadoop.hbase.filter.InclusiveStopRowFilter;
-import org.apache.hadoop.hbase.filter.PrefixFilter;
-import org.apache.hadoop.hbase.filter.PrefixRowFilter;
-import org.apache.hadoop.hbase.filter.RowFilterInterface;
-import org.apache.hadoop.hbase.filter.WhileMatchFilter;
-import org.apache.hadoop.hbase.filter.WhileMatchRowFilter;
import org.apache.hadoop.hbase.io.hfile.Compression;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.Writables;
@@ -117,7 +109,7 @@
count++;
}
s.close();
- assertEquals(0, count);
+ assertEquals(1, count);
// Now do something a bit more imvolved.
scan = new Scan(startrow, stoprow);
scan.addFamily(HConstants.CATALOG_FAMILY);
@@ -144,69 +136,6 @@
shutdownDfs(this.cluster);
}
}
-
- void rowPrefixFilter(Scan scan) throws IOException {
- List<KeyValue> results = new ArrayList<KeyValue>();
- scan.addFamily(HConstants.CATALOG_FAMILY);
- InternalScanner s = r.getScanner(scan);
- boolean hasMore = true;
- while (hasMore) {
- hasMore = s.next(results);
- for (KeyValue kv : results) {
- assertEquals((byte)'a', kv.getRow()[0]);
- assertEquals((byte)'b', kv.getRow()[1]);
- }
- results.clear();
- }
- s.close();
- }
-
- void rowInclusiveStopFilter(Scan scan, byte[] stopRow) throws IOException {
- List<KeyValue> results = new ArrayList<KeyValue>();
- scan.addFamily(HConstants.CATALOG_FAMILY);
- InternalScanner s = r.getScanner(scan);
- boolean hasMore = true;
- while (hasMore) {
- hasMore = s.next(results);
- for (KeyValue kv : results) {
- assertTrue(Bytes.compareTo(kv.getRow(), stopRow) <= 0);
- }
- results.clear();
- }
- s.close();
- }
-
- public void testFilters() throws IOException {
- try {
- this.r = createNewHRegion(REGION_INFO.getTableDesc(), null, null);
- addContent(this.r, HConstants.CATALOG_FAMILY);
- Filter newFilter = new PrefixFilter(Bytes.toBytes("ab"));
- Scan scan = new Scan();
- scan.setFilter(newFilter);
- rowPrefixFilter(scan);
- RowFilterInterface oldFilter = new PrefixRowFilter(Bytes.toBytes("ab"));
- scan = new Scan();
- scan.setOldFilter(oldFilter);
- rowPrefixFilter(scan);
-
- byte[] stopRow = Bytes.toBytes("bbc");
- newFilter = new WhileMatchFilter(new InclusiveStopFilter(stopRow));
- scan = new Scan();
- scan.setFilter(newFilter);
- rowInclusiveStopFilter(scan, stopRow);
-
- oldFilter = new WhileMatchRowFilter(
- new InclusiveStopRowFilter(stopRow));
- scan = new Scan();
- scan.setOldFilter(oldFilter);
- rowInclusiveStopFilter(scan, stopRow);
-
- } finally {
- this.r.close();
- this.r.getLog().closeAndDelete();
- shutdownDfs(this.cluster);
- }
- }
/** The test!
* @throws IOException
@@ -387,6 +316,7 @@
String server = Bytes.toString(val);
assertEquals(0, server.compareTo(serverName));
}
+ results.clear();
}
} finally {
InternalScanner s = scanner;
Modified:
hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/regionserver/TestStoreScanner.java
URL:
http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/regionserver/TestStoreScanner.java?rev=798510&r1=798509&r2=798510&view=diff
==============================================================================
---
hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/regionserver/TestStoreScanner.java
(original)
+++
hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/regionserver/TestStoreScanner.java
Tue Jul 28 12:51:36 2009
@@ -20,23 +20,25 @@
package org.apache.hadoop.hbase.regionserver;
+import junit.framework.TestCase;
+import org.apache.hadoop.hbase.KeyValue;
+import org.apache.hadoop.hbase.KeyValueTestUtil;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.filter.WhileMatchFilter;
+import org.apache.hadoop.hbase.filter.*;
+import org.apache.hadoop.hbase.util.Bytes;
+
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.NavigableSet;
import java.util.TreeSet;
-import junit.framework.TestCase;
-
-import org.apache.hadoop.hbase.KeyValue;
-import org.apache.hadoop.hbase.KeyValueTestUtil;
-import org.apache.hadoop.hbase.client.Scan;
-import org.apache.hadoop.hbase.util.Bytes;
public class TestStoreScanner extends TestCase {
final byte [] CF = Bytes.toBytes("cf");
-
+
/**
* Test utility for building a NavigableSet for scanners.
* @param strCols
@@ -65,9 +67,9 @@
Scan scanSpec = new Scan(Bytes.toBytes("R1"));
// this only uses maxVersions (default=1) and TimeRange (default=all)
StoreScanner scan =
- new StoreScanner(scanSpec, CF, Long.MAX_VALUE,
- KeyValue.COMPARATOR, getCols("a"),
- scanners);
+ new StoreScanner(scanSpec, CF, Long.MAX_VALUE,
+ KeyValue.COMPARATOR, getCols("a"),
+ scanners);
List<KeyValue> results = new ArrayList<KeyValue>();
assertEquals(true, scan.next(results));
@@ -96,9 +98,9 @@
Scan scanSpec = new Scan(Bytes.toBytes("R1"));
// this only uses maxVersions (default=1) and TimeRange (default=all)
StoreScanner scan =
- new StoreScanner(scanSpec, CF, Long.MAX_VALUE,
- KeyValue.COMPARATOR, getCols("a"),
- scanners);
+ new StoreScanner(scanSpec, CF, Long.MAX_VALUE,
+ KeyValue.COMPARATOR, getCols("a"),
+ scanners);
List<KeyValue> results = new ArrayList<KeyValue>();
scan.next(results);
@@ -128,8 +130,8 @@
};
Scan scanSpec = new Scan(Bytes.toBytes("R1"));
StoreScanner scan =
- new StoreScanner(scanSpec, CF, Long.MAX_VALUE, KeyValue.COMPARATOR,
- getCols("a"), scanners);
+ new StoreScanner(scanSpec, CF, Long.MAX_VALUE, KeyValue.COMPARATOR,
+ getCols("a"), scanners);
List<KeyValue> results = new ArrayList<KeyValue>();
assertFalse(scan.next(results));
@@ -151,9 +153,9 @@
};
Scan scanSpec = new Scan(Bytes.toBytes("R1"));
StoreScanner scan =
- new StoreScanner(scanSpec, CF, Long.MAX_VALUE, KeyValue.COMPARATOR,
- getCols("a"), scanners);
-
+ new StoreScanner(scanSpec, CF, Long.MAX_VALUE, KeyValue.COMPARATOR,
+ getCols("a"), scanners);
+
List<KeyValue> results = new ArrayList<KeyValue>();
assertEquals(true, scan.next(results));
assertEquals(0, results.size());
@@ -181,8 +183,8 @@
new KeyValueScanFixture(KeyValue.COMPARATOR, kvs2)
};
StoreScanner scan =
- new StoreScanner(new Scan(Bytes.toBytes("R1")), CF, Long.MAX_VALUE,
KeyValue.COMPARATOR,
- getCols("a"), scanners);
+ new StoreScanner(new Scan(Bytes.toBytes("R1")), CF, Long.MAX_VALUE,
KeyValue.COMPARATOR,
+ getCols("a"), scanners);
List<KeyValue> results = new ArrayList<KeyValue>();
// the two put at ts=now will be masked by the 1 delete, and
// since the scan default returns 1 version we'll return the newest
@@ -209,8 +211,8 @@
};
Scan scanSpec = new Scan(Bytes.toBytes("R1")).setMaxVersions(2);
StoreScanner scan =
- new StoreScanner(scanSpec, CF, Long.MAX_VALUE, KeyValue.COMPARATOR,
- getCols("a"), scanners);
+ new StoreScanner(scanSpec, CF, Long.MAX_VALUE, KeyValue.COMPARATOR,
+ getCols("a"), scanners);
List<KeyValue> results = new ArrayList<KeyValue>();
assertEquals(true, scan.next(results));
assertEquals(2, results.size());
@@ -219,17 +221,17 @@
}
public void testWildCardOneVersionScan() throws IOException {
- KeyValue [] kvs = new KeyValue [] {
- KeyValueTestUtil.create("R1", "cf", "a", 2, KeyValue.Type.Put,
"dont-care"),
- KeyValueTestUtil.create("R1", "cf", "b", 1, KeyValue.Type.Put,
"dont-care"),
- KeyValueTestUtil.create("R1", "cf", "a", 1,
KeyValue.Type.DeleteColumn, "dont-care"),
- };
+ KeyValue [] kvs = new KeyValue [] {
+ KeyValueTestUtil.create("R1", "cf", "a", 2, KeyValue.Type.Put,
"dont-care"),
+ KeyValueTestUtil.create("R1", "cf", "b", 1, KeyValue.Type.Put,
"dont-care"),
+ KeyValueTestUtil.create("R1", "cf", "a", 1, KeyValue.Type.DeleteColumn,
"dont-care"),
+ };
KeyValueScanner [] scanners = new KeyValueScanner[] {
new KeyValueScanFixture(KeyValue.COMPARATOR, kvs)
};
StoreScanner scan =
- new StoreScanner(new Scan(Bytes.toBytes("R1")), CF, Long.MAX_VALUE,
KeyValue.COMPARATOR,
- null, scanners);
+ new StoreScanner(new Scan(Bytes.toBytes("R1")), CF, Long.MAX_VALUE,
KeyValue.COMPARATOR,
+ null, scanners);
List<KeyValue> results = new ArrayList<KeyValue>();
assertEquals(true, scan.next(results));
assertEquals(2, results.size());
@@ -259,8 +261,8 @@
new KeyValueScanFixture(KeyValue.COMPARATOR, kvs)
};
StoreScanner scan =
- new StoreScanner(new Scan().setMaxVersions(2), CF, Long.MAX_VALUE,
KeyValue.COMPARATOR,
- null, scanners);
+ new StoreScanner(new Scan().setMaxVersions(2), CF, Long.MAX_VALUE,
KeyValue.COMPARATOR,
+ null, scanners);
List<KeyValue> results = new ArrayList<KeyValue>();
assertEquals(true, scan.next(results));
assertEquals(5, results.size());
@@ -289,8 +291,8 @@
new KeyValueScanFixture(KeyValue.COMPARATOR, kvs)
};
StoreScanner scan =
- new StoreScanner(new Scan().setMaxVersions(Integer.MAX_VALUE), CF,
Long.MAX_VALUE, KeyValue.COMPARATOR,
- null, scanners);
+ new StoreScanner(new Scan().setMaxVersions(Integer.MAX_VALUE), CF,
Long.MAX_VALUE, KeyValue.COMPARATOR,
+ null, scanners);
List<KeyValue> results = new ArrayList<KeyValue>();
assertEquals(true, scan.next(results));
assertEquals(0, results.size());
@@ -312,8 +314,8 @@
new KeyValueScanFixture(KeyValue.COMPARATOR, kvs),
};
StoreScanner scan =
- new StoreScanner(new Scan(), CF, Long.MAX_VALUE, KeyValue.COMPARATOR,
- null, scanners);
+ new StoreScanner(new Scan(), CF, Long.MAX_VALUE, KeyValue.COMPARATOR,
+ null, scanners);
List<KeyValue> results = new ArrayList<KeyValue>();
assertEquals(true, scan.next(results));
assertEquals(1, results.size());
@@ -337,9 +339,9 @@
new KeyValueScanFixture(KeyValue.COMPARATOR, kvs)
};
StoreScanner scan =
- new StoreScanner(new Scan(), CF, Long.MAX_VALUE, KeyValue.COMPARATOR,
- getCols("a", "d"), scanners);
-
+ new StoreScanner(new Scan(), CF, Long.MAX_VALUE, KeyValue.COMPARATOR,
+ getCols("a", "d"), scanners);
+
List<KeyValue> results = new ArrayList<KeyValue>();
assertEquals(true, scan.next(results));
assertEquals(2, results.size());
@@ -350,8 +352,156 @@
assertEquals(true, scan.next(results));
assertEquals(1, results.size());
assertEquals(kvs[kvs.length-1], results.get(0));
-
+
results.clear();
assertEquals(false, scan.next(results));
}
+
+ KeyValue [] stdKvs = new KeyValue[] {
+ KeyValueTestUtil.create("R:1", "cf", "a", 11, KeyValue.Type.Put,
"dont-care"),
+ KeyValueTestUtil.create("R:1", "cf", "b", 11, KeyValue.Type.Put,
"dont-care"),
+ KeyValueTestUtil.create("R:1", "cf", "c", 11, KeyValue.Type.Put,
"dont-care"),
+ KeyValueTestUtil.create("R:1", "cf", "d", 11, KeyValue.Type.Put,
"dont-care"),
+ KeyValueTestUtil.create("R:1", "cf", "e", 11, KeyValue.Type.Put,
"dont-care"),
+ KeyValueTestUtil.create("R:1", "cf", "f", 11, KeyValue.Type.Put,
"dont-care"),
+ KeyValueTestUtil.create("R:1", "cf", "g", 11, KeyValue.Type.Put,
"dont-care"),
+ KeyValueTestUtil.create("R:1", "cf", "h", 11, KeyValue.Type.Put,
"dont-care"),
+ KeyValueTestUtil.create("R:1", "cf", "i", 11, KeyValue.Type.Put,
"dont-care"),
+
+ // 9...
+ KeyValueTestUtil.create("R:2", "cf", "a", 11, KeyValue.Type.Put,
"dont-care"),
+ KeyValueTestUtil.create("R:2", "cf", "c", 11, KeyValue.Type.Put,
"dont-care"),
+ KeyValueTestUtil.create("R:2", "cf", "c", 10, KeyValue.Type.Put,
"dont-care"),
+
+ // 12...
+ KeyValueTestUtil.create("R:3", "cf", "a", 11, KeyValue.Type.Put,
"dont-care"),
+ KeyValueTestUtil.create("R:3", "cf", "c", 11, KeyValue.Type.Put,
"dont-care"),
+ KeyValueTestUtil.create("R:3", "cf", "c", 10, KeyValue.Type.Put,
"dont-care"),
+
+ // 15 ...
+ KeyValueTestUtil.create("R:4", "cf", "a", 11, KeyValue.Type.Put,
"dont-care"),
+ KeyValueTestUtil.create("R:4", "cf", "c", 11, KeyValue.Type.Put,
"dont-care"),
+ KeyValueTestUtil.create("R:4", "cf", "c", 10, KeyValue.Type.Put,
"dont-care"),
+
+ // 18 ..
+ KeyValueTestUtil.create("R:5", "cf", "a", 11, KeyValue.Type.Put,
"dont-care"),
+ KeyValueTestUtil.create("R:5", "cf", "c", 11, KeyValue.Type.Put,
"dont-care"),
+
+ // 20...
+ KeyValueTestUtil.create("R:6", "cf", "a", 11, KeyValue.Type.Put,
"dont-care"),
+ KeyValueTestUtil.create("R:6", "cf", "c", 11, KeyValue.Type.Put,
"dont-care"),
+
+ // 22...
+ KeyValueTestUtil.create("R:7", "cf", "a", 11, KeyValue.Type.Put,
"dont-care"),
+ KeyValueTestUtil.create("R:7", "cf", "c", 11, KeyValue.Type.Put,
"dont-care"),
+
+ // 24...
+ KeyValueTestUtil.create("R:8", "cf", "a", 11, KeyValue.Type.Put,
"dont-care"),
+ KeyValueTestUtil.create("R:8", "cf", "c", 11, KeyValue.Type.Put,
"dont-care"),
+
+ // 26 ..
+ KeyValueTestUtil.create("RA:1", "cf", "a", 11, KeyValue.Type.Put,
"dont-care"),
+
+ // 27...
+ KeyValueTestUtil.create("RA:2", "cf", "a", 11, KeyValue.Type.Put,
"dont-care"),
+
+ // 28..
+ KeyValueTestUtil.create("RA:3", "cf", "a", 11, KeyValue.Type.Put,
"dont-care"),
+ };
+ private StoreScanner getTestScanner(Scan s, NavigableSet<byte[]> cols) {
+ KeyValueScanner [] scanners = new KeyValueScanner[] {
+ new KeyValueScanFixture(KeyValue.COMPARATOR, stdKvs)
+ };
+
+ return new StoreScanner(s, CF, Long.MAX_VALUE, KeyValue.COMPARATOR, cols,
+ scanners);
+ }
+
+
+ // Test new and old row prefix filters.
+ public void testNewRowPrefixFilter() throws IOException {
+ Filter f = new WhileMatchFilter(
+ new PrefixFilter(Bytes.toBytes("R:")));
+ Scan s = new Scan(Bytes.toBytes("R:7"));
+ s.setFilter(f);
+
+ rowPrefixFilter(s);
+ }
+
+ public void testOldRowPrefixFilter() throws IOException {
+ RowFilterInterface f = new WhileMatchRowFilter(
+ new PrefixRowFilter(Bytes.toBytes("R:")));
+ Scan s = new Scan(Bytes.toBytes("R:7"));
+ s.setOldFilter(f);
+
+ rowPrefixFilter(s);
+
+ }
+ public void rowPrefixFilter(Scan s) throws IOException {
+
+ StoreScanner scan = getTestScanner(s, null);
+
+ List<KeyValue> results = new ArrayList<KeyValue>();
+ assertTrue(scan.next(results));
+ assertEquals(2, results.size());
+ assertEquals(stdKvs[22], results.get(0));
+ assertEquals(stdKvs[23], results.get(1));
+ results.clear();
+
+ assertTrue(scan.next(results));
+ assertEquals(2, results.size());
+ assertEquals(stdKvs[24], results.get(0));
+ assertEquals(stdKvs[25], results.get(1));
+ results.clear();
+
+ assertFalse(scan.next(results));
+ assertEquals(0, results.size());
+ }
+
+ // Test new and old row-inclusive stop filter.
+ public void testNewRowInclusiveStopFilter() throws IOException {
+ Filter f = new WhileMatchFilter(new
InclusiveStopFilter(Bytes.toBytes("R:3")));
+ Scan scan = new Scan();
+ scan.setFilter(f);
+
+ rowInclusiveStopFilter(scan);
+ }
+
+ public void testOldRowInclusiveTopFilter() throws IOException {
+ RowFilterInterface f = new WhileMatchRowFilter(
+ new InclusiveStopRowFilter(Bytes.toBytes("R:3")));
+ Scan scan = new Scan();
+ scan.setOldFilter(f);
+
+ rowInclusiveStopFilter(scan);
+ }
+
+ public void rowInclusiveStopFilter(Scan scan) throws IOException {
+ StoreScanner s = getTestScanner(scan, getCols("a"));
+
+ // read crap.
+ List<KeyValue> results = new ArrayList<KeyValue>();
+ assertTrue(s.next(results));
+ assertEquals(1, results.size());
+ assertEquals(stdKvs[0], results.get(0));
+ results.clear();
+
+ assertTrue(s.next(results));
+ assertEquals(1, results.size());
+ assertEquals(stdKvs[9], results.get(0));
+ results.clear();
+
+ assertTrue(s.next(results));
+ assertEquals(1, results.size());
+ assertEquals(stdKvs[12], results.get(0));
+ results.clear();
+
+ // without aggressive peeking, the scanner doesnt know if the next row is
good or not
+ // under the affects of a filter.
+ assertFalse(s.next(results));
+ assertEquals(0, results.size());
+ }
+
+
+
}