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:
parent
e8b37422c3
commit
9343ef438f
|
@ -87,7 +87,7 @@ public class FuzzyRowFilter extends FilterBase {
|
||||||
.getSecond()));
|
.getSecond()));
|
||||||
throw new IllegalArgumentException("Fuzzy pair lengths do not match: " + readable);
|
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()));
|
p.setSecond(preprocessMask(p.getSecond()));
|
||||||
preprocessSearchKey(p);
|
preprocessSearchKey(p);
|
||||||
}
|
}
|
||||||
|
@ -104,12 +104,14 @@ public class FuzzyRowFilter extends FilterBase {
|
||||||
byte[] mask = p.getSecond();
|
byte[] mask = p.getSecond();
|
||||||
for (int i = 0; i < mask.length; i++) {
|
for (int i = 0; i < mask.length; i++) {
|
||||||
// set non-fixed part of a search key to 0.
|
// 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
|
* fixed positions
|
||||||
* @param mask
|
* @param mask
|
||||||
* @return mask array
|
* @return mask array
|
||||||
|
@ -124,7 +126,7 @@ public class FuzzyRowFilter extends FilterBase {
|
||||||
if (mask[i] == 0) {
|
if (mask[i] == 0) {
|
||||||
mask[i] = -1; // 0 -> -1
|
mask[i] = -1; // 0 -> -1
|
||||||
} else if (mask[i] == 1) {
|
} else if (mask[i] == 1) {
|
||||||
mask[i] = 0;// 1 -> 0
|
mask[i] = 2;// 1 -> 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mask;
|
return mask;
|
||||||
|
@ -132,7 +134,7 @@ public class FuzzyRowFilter extends FilterBase {
|
||||||
|
|
||||||
private boolean isPreprocessedMask(byte[] mask) {
|
private boolean isPreprocessedMask(byte[] mask) {
|
||||||
for (int i = 0; i < mask.length; i++) {
|
for (int i = 0; i < mask.length; i++) {
|
||||||
if (mask[i] != -1 && mask[i] != 0) {
|
if (mask[i] != -1 && mask[i] != 2) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -146,6 +148,10 @@ public class FuzzyRowFilter extends FilterBase {
|
||||||
for (int i = startIndex; i < size + startIndex; i++) {
|
for (int i = startIndex; i < size + startIndex; i++) {
|
||||||
final int index = i % size;
|
final int index = i % size;
|
||||||
Pair<byte[], byte[]> fuzzyData = fuzzyKeysData.get(index);
|
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 =
|
SatisfiesCode satisfiesCode =
|
||||||
satisfies(isReversed(), c.getRowArray(), c.getRowOffset(), c.getRowLength(),
|
satisfies(isReversed(), c.getRowArray(), c.getRowOffset(), c.getRowLength(),
|
||||||
fuzzyData.getFirst(), fuzzyData.getSecond());
|
fuzzyData.getFirst(), fuzzyData.getSecond());
|
||||||
|
|
|
@ -110,6 +110,47 @@ public class TestFuzzyRowFilterEndToEnd {
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
@Test
|
||||||
public void testHBASE14782() throws IOException
|
public void testHBASE14782() throws IOException
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue