HBASE-14782 FuzzyRowFilter skips valid rows (Vladimir Rodionov)

This commit is contained in:
chenheng 2015-11-19 10:56:18 +08:00
parent 3aa3fae138
commit ebe5801e00
3 changed files with 81 additions and 5 deletions

View File

@ -154,6 +154,7 @@ public class FuzzyRowFilter extends FilterBase {
}
// NOT FOUND -> seek next using hint
lastFoundIndex = -1;
return ReturnCode.SEEK_NEXT_USING_HINT;
}
@ -572,7 +573,31 @@ public class FuzzyRowFilter extends FilterBase {
}
}
return result;
return reverse? result: trimTrailingZeroes(result, fuzzyKeyMeta, toInc);
}
/**
* For forward scanner, next cell hint should not contain any trailing zeroes
* unless they are part of fuzzyKeyMeta
* hint = '\x01\x01\x01\x00\x00'
* will skip valid row '\x01\x01\x01'
*
* @param result
* @param fuzzyKeyMeta
* @param toInc - position of incremented byte
* @return trimmed version of result
*/
private static byte[] trimTrailingZeroes(byte[] result, byte[] fuzzyKeyMeta, int toInc) {
int off = fuzzyKeyMeta.length >= result.length? result.length -1:
fuzzyKeyMeta.length -1;
for( ; off >= 0; off--){
if(fuzzyKeyMeta[off] != 0) break;
}
if (off < toInc) off = toInc;
byte[] retValue = new byte[off+1];
System.arraycopy(result, 0, retValue, 0, retValue.length);
return retValue;
}
/**

View File

@ -231,7 +231,7 @@ public class TestFuzzyRowFilter {
new byte[]{0, 1, 2}, // fuzzy row
new byte[]{0, -1, -1}, // mask
new byte[]{1, 2, 1, 0, 1}, // current
new byte[]{2, 1, 2, 0, 0}); // expected next
new byte[]{2, 1, 2}); // expected next
assertNext(false,
new byte[]{0, 1, 2}, // fuzzy row
@ -243,13 +243,13 @@ public class TestFuzzyRowFilter {
new byte[]{0, 1, 0, 2, 0}, // fuzzy row
new byte[]{0, -1, 0, -1, 0}, // mask
new byte[]{1, 0, 2, 0, 1}, // current
new byte[]{1, 1, 0, 2, 0}); // expected next
new byte[]{1, 1, 0, 2}); // expected next
assertNext(false,
new byte[]{1, 0, 1},
new byte[]{-1, 0, -1},
new byte[]{1, (byte) 128, 2, 0, 1},
new byte[]{1, (byte) 129, 1, 0, 0});
new byte[]{1, (byte) 129, 1});
assertNext(false,
new byte[]{0, 1, 0, 1},
@ -315,7 +315,7 @@ public class TestFuzzyRowFilter {
new byte[]{1, 1, 0, 0},
new byte[]{-1, -1, 0, 0},
new byte[]{0, 1, 3, 2},
new byte[]{1, 1, 0, 0});
new byte[]{1, 1});
// No next for this one
Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule(

View File

@ -110,6 +110,57 @@ public class TestFuzzyRowFilterEndToEnd {
// Nothing to do.
}
@Test
public void testHBASE14782() throws IOException
{
String cf = "f";
String cq = "q";
String table = "HBASE14872";
Table ht =
TEST_UTIL.createTable(TableName.valueOf(table), Bytes.toBytes(cf), Integer.MAX_VALUE);
// Load data
String[] rows = new String[]{
"\\x9C\\x00\\x044\\x00\\x00\\x00\\x00",
"\\x9C\\x00\\x044\\x01\\x00\\x00\\x00",
"\\x9C\\x00\\x044\\x00\\x01\\x00\\x00",
"\\x9C\\x00\\x044\\x00\\x00\\x01\\x00",
"\\x9C\\x00\\x044\\x00\\x01\\x00\\x01",
"\\x9B\\x00\\x044e\\xBB\\xB2\\xBB",
};
String badRow = "\\x9C\\x00\\x03\\xE9e\\xBB{X\\x1Fwts\\x1F\\x15vRX";
for(int i=0; i < rows.length; i++){
Put p = new Put(Bytes.toBytesBinary(rows[i]));
p.addColumn(cf.getBytes(), cq.getBytes(), "value".getBytes());
ht.put(p);
}
Put p = new Put(Bytes.toBytesBinary(badRow));
p.addColumn(cf.getBytes(), cq.getBytes(), "value".getBytes());
ht.put(p);
TEST_UTIL.flush();
List<Pair<byte[], byte[]>> data = new ArrayList<Pair<byte[], byte[]>>();
byte[] fuzzyKey = Bytes.toBytesBinary("\\x00\\x00\\x044");
byte[] mask = new byte[] { 1,0,0,0};
data.add(new Pair<byte[], byte[]>(fuzzyKey, mask));
FuzzyRowFilter filter = new FuzzyRowFilter(data);
Scan scan = new Scan();
scan.setFilter(filter);
ResultScanner scanner = ht.getScanner(scan);
int total = 0;
while(scanner.next() != null){
total++;
}
assertEquals(rows.length, total);
TEST_UTIL.deleteTable(TableName.valueOf(table));
}
@Test
public void testEndToEnd() throws Exception {
String cf = "f";