HBASE-15676 FuzzyRowFilter fails and matches all the rows in the table if the mask consists of all 0s (Matt Warhaftig)

This commit is contained in:
tedyu 2016-04-27 21:03:34 -07:00
parent 5f5cdaae9a
commit 4f2d8dc328
2 changed files with 53 additions and 6 deletions

View File

@ -86,7 +86,7 @@ public class FuzzyRowFilter extends FilterBase {
.getSecond()));
throw new IllegalArgumentException("Fuzzy pair lengths do not match: " + readable);
}
// update mask ( 0 -> -1 (0xff), 1 -> 0)
// update mask ( 0 -> -1 (0xff), 1 -> 2)
p.setSecond(preprocessMask(p.getSecond()));
preprocessSearchKey(p);
}
@ -102,12 +102,14 @@ public class FuzzyRowFilter extends FilterBase {
byte[] mask = p.getSecond();
for (int i = 0; i < mask.length; i++) {
// set non-fixed part of a search key to 0.
if (mask[i] == 0) key[i] = 0;
if (mask[i] == 2) {
key[i] = 0;
}
}
}
/**
* We need to preprocess mask array, as since we treat 0's as unfixed positions and -1 (0xff) as
* We need to preprocess mask array, as since we treat 2's as unfixed positions and -1 (0xff) as
* fixed positions
* @param mask
* @return mask array
@ -121,7 +123,7 @@ public class FuzzyRowFilter extends FilterBase {
if (mask[i] == 0) {
mask[i] = -1; // 0 -> -1
} else if (mask[i] == 1) {
mask[i] = 0;// 1 -> 0
mask[i] = 2;// 1 -> 2
}
}
return mask;
@ -129,7 +131,7 @@ public class FuzzyRowFilter extends FilterBase {
private boolean isPreprocessedMask(byte[] mask) {
for (int i = 0; i < mask.length; i++) {
if (mask[i] != -1 && mask[i] != 0) {
if (mask[i] != -1 && mask[i] != 2) {
return false;
}
}
@ -143,6 +145,10 @@ public class FuzzyRowFilter extends FilterBase {
for (int i = startIndex; i < size + startIndex; i++) {
final int index = i % size;
Pair<byte[], byte[]> fuzzyData = fuzzyKeysData.get(index);
// This shift is idempotent - always end up with 0 and -1 as mask values.
for (int j = 0; j < fuzzyData.getSecond().length; j++) {
fuzzyData.getSecond()[j] >>= 2;
}
SatisfiesCode satisfiesCode =
satisfies(isReversed(), c.getRowArray(), c.getRowOffset(), c.getRowLength(),
fuzzyData.getFirst(), fuzzyData.getSecond());

View File

@ -110,7 +110,48 @@ public class TestFuzzyRowFilterEndToEnd {
// Nothing to do.
}
@Test
// HBASE-15676 Test that fuzzy info of all fixed bits (0s) finds matching row.
@Test
public void testAllFixedBits() throws IOException {
String cf = "f";
String cq = "q";
String table = "testAllFixedBits";
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",
"\\x9B\\x00\\x044e\\x9B\\x02\\xBB", "\\x9C\\x00\\x044\\x00\\x00\\x01\\x00",
"\\x9C\\x00\\x044\\x00\\x01\\x00\\x01", "\\x9B\\x00\\x044e\\xBB\\xB2\\xBB", };
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);
}
TEST_UTIL.flush();
List<Pair<byte[], byte[]>> data = new ArrayList<Pair<byte[], byte[]>>();
byte[] fuzzyKey = Bytes.toBytesBinary("\\x9B\\x00\\x044e");
byte[] mask = new byte[] { 0, 0, 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(2, total);
TEST_UTIL.deleteTable(TableName.valueOf(table));
}
@Test
public void testHBASE14782() throws IOException
{
String cf = "f";