diff --git hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FuzzyRowFilter.java hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FuzzyRowFilter.java index 895ffc8c99..575478a32b 100644 --- hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FuzzyRowFilter.java +++ hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FuzzyRowFilter.java @@ -59,8 +59,21 @@ import com.google.common.annotations.VisibleForTesting; */ @InterfaceAudience.Public public class FuzzyRowFilter extends FilterBase { - private static final boolean UNSAFE_UNALIGNED = UnsafeAvailChecker.unaligned(); - private List> fuzzyKeysData; + @VisibleForTesting + static final boolean UNSAFE_UNALIGNED = UnsafeAvailChecker.unaligned(); + /** + * for compatibility. We convert the 0 to -1 internally. + */ + public static final byte FIXED_BYTE = 0; + /** + * for compatibility. We convert the 1 to 0 internally. + */ + public static final byte NON_FIXED_BYTE = 1; + @VisibleForTesting + static final byte FIXED_BYTE_INNER = -1; + @VisibleForTesting + static final byte NON_FIXED_BYTE_INNER = 0; + private final List> fuzzyKeysData; private boolean done = false; /** @@ -73,39 +86,44 @@ public class FuzzyRowFilter extends FilterBase { /** * Row tracker (keeps all next rows after SEEK_NEXT_USING_HINT was returned) */ - private RowTracker tracker; + private final RowTracker tracker; public FuzzyRowFilter(List> fuzzyKeysData) { - Pair p; - for (int i = 0; i < fuzzyKeysData.size(); i++) { - p = fuzzyKeysData.get(i); - if (p.getFirst().length != p.getSecond().length) { + this(fuzzyKeysData, true); + } + + private FuzzyRowFilter(List> fuzzyKeysData, boolean needPreprocess) { + this.fuzzyKeysData = new ArrayList<>(fuzzyKeysData.size()); + if (needPreprocess) { + for (Pair p : fuzzyKeysData) { + if (p.getFirst().length != p.getSecond().length) { Pair readable = new Pair<>(Bytes.toStringBinary(p.getFirst()), Bytes.toStringBinary(p .getSecond())); - throw new IllegalArgumentException("Fuzzy pair lengths do not match: " + readable); + throw new IllegalArgumentException("Fuzzy pair lengths do not match: " + readable); + } + byte[] mask = preprocessMask(p.getSecond()); + byte[] key = preprocessSearchKey(p.getFirst(), mask); + this.fuzzyKeysData.add(new Pair<>(key, mask)); } - // update mask ( 0 -> -1 (0xff), 1 -> 2) - p.setSecond(preprocessMask(p.getSecond())); - preprocessSearchKey(p); + } else { + // used by FuzzyRowFilter#parseFrom, so there is no check and copy. + this.fuzzyKeysData.addAll(fuzzyKeysData); } - this.fuzzyKeysData = fuzzyKeysData; this.tracker = new RowTracker(); } - private void preprocessSearchKey(Pair p) { - if (!UNSAFE_UNALIGNED) { - // do nothing - return; - } - byte[] key = p.getFirst(); - byte[] mask = p.getSecond(); - for (int i = 0; i < mask.length; i++) { + private byte[] preprocessSearchKey(byte[] key, byte[] mask) { + byte[] copy = Arrays.copyOf(key, key.length); + for (int i = 0; i < key.length; i++) { // set non-fixed part of a search key to 0. - if (mask[i] == 2) { - key[i] = 0; + if (mask[i] == NON_FIXED_BYTE_INNER) { + copy[i] = 0; + } else { + copy[i] = key[i]; } } + return copy; } /** @@ -115,28 +133,15 @@ public class FuzzyRowFilter extends FilterBase { * @return mask array */ private byte[] preprocessMask(byte[] mask) { - if (!UNSAFE_UNALIGNED) { - // do nothing - return mask; - } - if (isPreprocessedMask(mask)) return mask; - for (int i = 0; i < mask.length; i++) { - if (mask[i] == 0) { - mask[i] = -1; // 0 -> -1 - } else if (mask[i] == 1) { - mask[i] = 2;// 1 -> 2 - } - } - return mask; - } - - private boolean isPreprocessedMask(byte[] mask) { + byte[] copy = Arrays.copyOf(mask, mask.length); for (int i = 0; i < mask.length; i++) { - if (mask[i] != -1 && mask[i] != 2) { - return false; + if (mask[i] == FIXED_BYTE) { + copy[i] = FIXED_BYTE_INNER; + } else { + copy[i] = NON_FIXED_BYTE_INNER; } } - return true; + return copy; } @Override @@ -146,10 +151,6 @@ public class FuzzyRowFilter extends FilterBase { for (int i = startIndex; i < size + startIndex; i++) { final int index = i % size; Pair 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()); @@ -282,7 +283,7 @@ public class FuzzyRowFilter extends FilterBase { byte[] keyMeta = current.getSecond().toByteArray(); fuzzyKeysData.add(new Pair<>(keyBytes, keyMeta)); } - return new FuzzyRowFilter(fuzzyKeysData); + return new FuzzyRowFilter(fuzzyKeysData, false); } @Override @@ -309,24 +310,18 @@ public class FuzzyRowFilter extends FilterBase { NO_NEXT } - @VisibleForTesting - static SatisfiesCode satisfies(byte[] row, byte[] fuzzyKeyBytes, byte[] fuzzyKeyMeta) { - return satisfies(false, row, 0, row.length, fuzzyKeyBytes, fuzzyKeyMeta); - } - - @VisibleForTesting - static SatisfiesCode satisfies(boolean reverse, byte[] row, byte[] fuzzyKeyBytes, - byte[] fuzzyKeyMeta) { - return satisfies(reverse, row, 0, row.length, fuzzyKeyBytes, fuzzyKeyMeta); - } - - static SatisfiesCode satisfies(boolean reverse, byte[] row, int offset, int length, + private static SatisfiesCode satisfies(boolean reverse, byte[] row, int offset, int length, byte[] fuzzyKeyBytes, byte[] fuzzyKeyMeta) { - - if (!UNSAFE_UNALIGNED) { + if (UNSAFE_UNALIGNED) { + return satisfiesUnsafe(reverse, row, offset, length, fuzzyKeyBytes, fuzzyKeyMeta); + } else { return satisfiesNoUnsafe(reverse, row, offset, length, fuzzyKeyBytes, fuzzyKeyMeta); } + } + @VisibleForTesting + static SatisfiesCode satisfiesUnsafe(boolean reverse, byte[] row, int offset, int length, + byte[] fuzzyKeyBytes, byte[] fuzzyKeyMeta) { if (row == null) { // do nothing, let scan to proceed return SatisfiesCode.YES; @@ -384,6 +379,7 @@ public class FuzzyRowFilter extends FilterBase { return SatisfiesCode.YES; } + @VisibleForTesting static SatisfiesCode satisfiesNoUnsafe(boolean reverse, byte[] row, int offset, int length, byte[] fuzzyKeyBytes, byte[] fuzzyKeyMeta) { if (row == null) { @@ -396,7 +392,7 @@ public class FuzzyRowFilter extends FilterBase { for (int i = 0; i < fuzzyKeyMeta.length && i < length; i++) { // First, checking if this position is fixed and not equals the given one - boolean byteAtPositionFixed = fuzzyKeyMeta[i] == 0; + boolean byteAtPositionFixed = fuzzyKeyMeta[i] == FIXED_BYTE_INNER; boolean fixedByteIncorrect = byteAtPositionFixed && fuzzyKeyBytes[i] != row[i + offset]; if (fixedByteIncorrect) { // in this case there's another row that satisfies fuzzy rule and bigger than this row @@ -423,24 +419,13 @@ public class FuzzyRowFilter extends FilterBase { // (see the code of getNextForFuzzyRule below) by one. // Note: if non-fixed byte is already at biggest value, this doesn't allow us to say there's // bigger one that satisfies the rule as it can't be increased. - if (fuzzyKeyMeta[i] == 1 && !order.isMax(fuzzyKeyBytes[i])) { + if (fuzzyKeyMeta[i] == NON_FIXED_BYTE_INNER && !order.isMax(fuzzyKeyBytes[i])) { nextRowKeyCandidateExists = true; } } return SatisfiesCode.YES; } - @VisibleForTesting - static byte[] getNextForFuzzyRule(byte[] row, byte[] fuzzyKeyBytes, byte[] fuzzyKeyMeta) { - return getNextForFuzzyRule(false, row, 0, row.length, fuzzyKeyBytes, fuzzyKeyMeta); - } - - @VisibleForTesting - static byte[] getNextForFuzzyRule(boolean reverse, byte[] row, byte[] fuzzyKeyBytes, - byte[] fuzzyKeyMeta) { - return getNextForFuzzyRule(reverse, row, 0, row.length, fuzzyKeyBytes, fuzzyKeyMeta); - } - /** Abstracts directional comparisons based on scan direction. */ private enum Order { ASC { @@ -536,13 +521,13 @@ public class FuzzyRowFilter extends FilterBase { boolean increased = false; for (int i = 0; i < result.length; i++) { - if (i >= fuzzyKeyMeta.length || fuzzyKeyMeta[i] == 0 /* non-fixed */) { + if (i >= fuzzyKeyMeta.length || fuzzyKeyMeta[i] == NON_FIXED_BYTE_INNER /* non-fixed */) { result[i] = row[offset + i]; if (!order.isMax(row[offset + i])) { // this is "non-fixed" position and is not at max value, hence we can increase it toInc = i; } - } else if (i < fuzzyKeyMeta.length && fuzzyKeyMeta[i] == -1 /* fixed */) { + } else if (i < fuzzyKeyMeta.length && fuzzyKeyMeta[i] == FIXED_BYTE_INNER /* fixed */) { if (order.lt((row[i + offset] & 0xFF), (fuzzyKeyBytes[i] & 0xFF))) { // if setting value for any fixed position increased the original array, // we are OK @@ -568,7 +553,7 @@ public class FuzzyRowFilter extends FilterBase { // Setting all "non-fixed" positions to zeroes to the right of the one we increased so // that found "next" row key is the smallest possible for (int i = toInc + 1; i < result.length; i++) { - if (i >= fuzzyKeyMeta.length || fuzzyKeyMeta[i] == 0 /* non-fixed */) { + if (i >= fuzzyKeyMeta.length || fuzzyKeyMeta[i] == NON_FIXED_BYTE_INNER /* non-fixed */) { result[i] = order.min(); } } diff --git hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestFuzzyRowAndColumnRangeFilterWoUnsafe.java hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestFuzzyRowAndColumnRangeFilterWoUnsafe.java new file mode 100644 index 0000000000..276a134b69 --- /dev/null +++ hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestFuzzyRowAndColumnRangeFilterWoUnsafe.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.hadoop.hbase.filter; + +import org.apache.hadoop.hbase.testclassification.FilterTests; +import org.apache.hadoop.hbase.testclassification.MediumTests; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +@Category({FilterTests.class, MediumTests.class}) +public class TestFuzzyRowAndColumnRangeFilterWoUnsafe extends TestFuzzyRowAndColumnRangeFilter { + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + TestFuzzyRowFilter.disableUnsafe(); + TestFuzzyRowAndColumnRangeFilter.setUpBeforeClass(); + } + + @AfterClass + public static void tearDownAfterClass() throws Exception { + TestFuzzyRowAndColumnRangeFilter.tearDownAfterClass(); + TestFuzzyRowFilter.detectAvailabilityOfUnsafe(); + } + +} diff --git hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestFuzzyRowFilter.java hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestFuzzyRowFilter.java index 0d480885e3..e1bb83cec1 100644 --- hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestFuzzyRowFilter.java +++ hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestFuzzyRowFilter.java @@ -17,154 +17,227 @@ */ package org.apache.hadoop.hbase.filter; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.KeyValueUtil; +import static org.apache.hadoop.hbase.filter.FuzzyRowFilter.FIXED_BYTE_INNER; +import static org.apache.hadoop.hbase.filter.FuzzyRowFilter.NON_FIXED_BYTE_INNER; import org.apache.hadoop.hbase.testclassification.FilterTests; import org.apache.hadoop.hbase.testclassification.SmallTests; import org.apache.hadoop.hbase.util.Bytes; +import org.apache.hadoop.hbase.util.UnsafeAvailChecker; import org.junit.Assert; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import org.junit.Test; import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; @Category({FilterTests.class, SmallTests.class}) +@RunWith(Parameterized.class) public class TestFuzzyRowFilter { + private static final String UNSAFE_AVAIL_NAME = "UNSAFE_UNALIGNED"; + + @Parameterized.Parameters + public static Collection parameters() { + List paramList = new ArrayList<>(2); + { + paramList.add(new Object[] { false }); + paramList.add(new Object[] { true }); + } + return paramList; + } + + public TestFuzzyRowFilter(boolean useUnsafeIfPossible) throws Exception { + if (useUnsafeIfPossible) { + detectAvailabilityOfUnsafe(); + } else { + disableUnsafe(); + } + } + + private static void setUnsafe(String fieldName, boolean value) throws Exception { + Field field = FuzzyRowFilter.class.getDeclaredField(fieldName); + field.setAccessible(true); + Field modifiersField = Field.class.getDeclaredField("modifiers"); + modifiersField.setAccessible(true); + int oldModifiers = field.getModifiers(); + modifiersField.setInt(field, oldModifiers & ~Modifier.FINAL); + try { + field.set(null, value); + } finally { + modifiersField.setInt(field, oldModifiers); + } + } + + static void disableUnsafe() throws Exception { + if (FuzzyRowFilter.UNSAFE_UNALIGNED) { + setUnsafe(UNSAFE_AVAIL_NAME, false); + } + assertFalse(FuzzyRowFilter.UNSAFE_UNALIGNED); + } + + static void detectAvailabilityOfUnsafe() throws Exception { + if (FuzzyRowFilter.UNSAFE_UNALIGNED != UnsafeAvailChecker.unaligned()) { + setUnsafe(UNSAFE_AVAIL_NAME, UnsafeAvailChecker.unaligned()); + } + assertEquals(FuzzyRowFilter.UNSAFE_UNALIGNED, UnsafeAvailChecker.unaligned()); + } + @Test public void testSatisfiesNoUnsafeForward() { Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES, - FuzzyRowFilter.satisfiesNoUnsafe(false, - new byte[]{1, (byte) -128, 1, 0, 1}, - 0, 5, - new byte[]{1, 0, 1}, - new byte[]{0, 1, 0})); + FuzzyRowFilter.satisfiesNoUnsafe( + false, + new byte[]{1, (byte) -128, 1, 0, 1}, + 0, 5, + new byte[]{1, 0, 1}, + new byte[]{FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS, - FuzzyRowFilter.satisfiesNoUnsafe(false, - new byte[]{1, (byte) -128, 2, 0, 1}, - 0, 5, - new byte[]{1, 0, 1}, - new byte[]{0, 1, 0})); - + FuzzyRowFilter.satisfiesNoUnsafe(false, + new byte[]{1, (byte) -128, 2, 0, 1}, + 0, 5, + new byte[]{1, 0, 1}, + new byte[]{FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES, - FuzzyRowFilter.satisfiesNoUnsafe(false, - new byte[]{1, 2, 1, 3, 3}, - 0, 5, - new byte[]{1, 2, 0, 3}, - new byte[]{0, 0, 1, 0})); + FuzzyRowFilter.satisfiesNoUnsafe(false, + new byte[]{1, 2, 1, 3, 3}, + 0, 5, + new byte[]{1, 2, 0, 3}, + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS, - FuzzyRowFilter.satisfiesNoUnsafe(false, - new byte[]{1, 1, 1, 3, 0}, // row to check - 0, 5, - new byte[]{1, 2, 0, 3}, // fuzzy row - new byte[]{0, 0, 1, 0})); // mask + FuzzyRowFilter.satisfiesNoUnsafe(false, + new byte[]{1, 1, 1, 3, 0}, // row to check + 0, 5, + new byte[]{1, 2, 0, 3}, // fuzzy row + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); // mask Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS, - FuzzyRowFilter.satisfiesNoUnsafe(false, - new byte[]{1, 1, 1, 3, 0}, - 0, 5, - new byte[]{1, (byte) 245, 0, 3}, - new byte[]{0, 0, 1, 0})); + FuzzyRowFilter.satisfiesNoUnsafe(false, + new byte[]{1, 1, 1, 3, 0}, + 0, 5, + new byte[]{1, (byte) 245, 0, 3}, + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); // mask Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS, - FuzzyRowFilter.satisfiesNoUnsafe(false, - new byte[]{1, 2, 1, 0, 1}, - 0, 5, - new byte[]{0, 1, 2}, - new byte[]{1, 0, 0})); + FuzzyRowFilter.satisfiesNoUnsafe(false, + new byte[]{1, 2, 1, 0, 1}, + 0, 5, + new byte[]{0, 1, 2}, + new byte[]{NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER, FIXED_BYTE_INNER})); } @Test - public void testSatisfiesForward() { + public void testSatisfiesUnsafeForward() { + // This will be a NOOP test when no unsafe. + // There is a nounsafe counterpart test here when there is no Unsafe. + // see testSatisfiesNoUnsafeForward. + if (!FuzzyRowFilter.UNSAFE_UNALIGNED) { + return; + } Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES, - FuzzyRowFilter.satisfies(false, - new byte[]{1, (byte) -128, 1, 0, 1}, - new byte[]{1, 0, 1}, - new byte[]{-1, 0, -1})); + FuzzyRowFilter.satisfiesUnsafe(false, + new byte[]{1, (byte) -128, 1, 0, 1}, 0, 5, + new byte[]{1, 0, 1}, + new byte[]{FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS, - FuzzyRowFilter.satisfies(false, - new byte[]{1, (byte) -128, 2, 0, 1}, - new byte[]{1, 0, 1}, - new byte[]{-1, 0, -1})); - + FuzzyRowFilter.satisfiesUnsafe(false, + new byte[]{1, (byte) -128, 2, 0, 1}, 0, 5, + new byte[]{1, 0, 1}, + new byte[]{FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES, - FuzzyRowFilter.satisfies(false, - new byte[]{1, 2, 1, 3, 3}, - new byte[]{1, 2, 0, 3}, - new byte[]{-1, -1, 0, -1})); + FuzzyRowFilter.satisfiesUnsafe(false, + new byte[]{1, 2, 1, 3, 3}, 0, 5, + new byte[]{1, 2, 0, 3}, + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS, - FuzzyRowFilter.satisfies(false, - new byte[]{1, 1, 1, 3, 0}, // row to check - new byte[]{1, 2, 0, 3}, // fuzzy row - new byte[]{-1, -1, 0, -1})); // mask + FuzzyRowFilter.satisfiesUnsafe(false, + new byte[]{1, 1, 1, 3, 0}, 0, 5, // row to check + new byte[]{1, 2, 0, 3}, // fuzzy row + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); // mask Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS, - FuzzyRowFilter.satisfies(false, - new byte[]{1, 1, 1, 3, 0}, - new byte[]{1, (byte) 245, 0, 3}, - new byte[]{-1, -1, 0, -1})); + FuzzyRowFilter.satisfiesUnsafe(false, + new byte[]{1, 1, 1, 3, 0}, 0, 5, + new byte[]{1, (byte) 245, 0, 3}, + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS, - FuzzyRowFilter.satisfies(false, - new byte[]{1, 2, 1, 0, 1}, - new byte[]{0, 1, 2}, - new byte[]{0, -1, -1})); + FuzzyRowFilter.satisfiesUnsafe(false, + new byte[]{1, 2, 1, 0, 1}, 0, 5, + new byte[]{0, 1, 2}, + new byte[]{NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER, FIXED_BYTE_INNER})); } @Test - public void testSatisfiesReverse() { + public void testSatisfiesUnsafeReverse() { + // This will be a NOOP test when no unsafe. + // There is a nounsafe counterpart test here when there is no Unsafe. + // see testSatisfiesNoUnsafeReverse. + if (!FuzzyRowFilter.UNSAFE_UNALIGNED) { + return; + } + Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES, - FuzzyRowFilter.satisfies(true, - new byte[]{1, (byte) -128, 1, 0, 1}, + FuzzyRowFilter.satisfiesUnsafe(true, + new byte[]{1, (byte) -128, 1, 0, 1}, 0, 5, new byte[]{1, 0, 1}, - new byte[]{-1, 0, -1})); + new byte[]{FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS, - FuzzyRowFilter.satisfies(true, - new byte[]{1, (byte) -128, 2, 0, 1}, + FuzzyRowFilter.satisfiesUnsafe(true, + new byte[]{1, (byte) -128, 2, 0, 1}, 0, 5, new byte[]{1, 0, 1}, - new byte[]{-1, 0, -1})); + new byte[]{FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS, - FuzzyRowFilter.satisfies(true, - new byte[]{2, 3, 1, 1, 1}, + FuzzyRowFilter.satisfiesUnsafe(true, + new byte[]{2, 3, 1, 1, 1}, 0, 5, new byte[]{1, 0, 1}, - new byte[]{-1, 0, -1})); + new byte[]{FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES, - FuzzyRowFilter.satisfies(true, - new byte[]{1, 2, 1, 3, 3}, + FuzzyRowFilter.satisfiesUnsafe(true, + new byte[]{1, 2, 1, 3, 3}, 0, 5, new byte[]{1, 2, 0, 3}, - new byte[]{-1, -1, 0, -1})); + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS, - FuzzyRowFilter.satisfies(true, - new byte[]{1, (byte) 245, 1, 3, 0}, + FuzzyRowFilter.satisfiesUnsafe(true, + new byte[]{1, (byte) 245, 1, 3, 0}, 0, 5, new byte[]{1, 1, 0, 3}, - new byte[]{-1, -1, 0, -1})); + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS, - FuzzyRowFilter.satisfies(true, - new byte[]{1, 3, 1, 3, 0}, + FuzzyRowFilter.satisfiesUnsafe(true, + new byte[]{1, 3, 1, 3, 0}, 0, 5, new byte[]{1, 2, 0, 3}, - new byte[]{-1, -1, 0, -1})); + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS, - FuzzyRowFilter.satisfies(true, - new byte[]{2, 1, 1, 1, 0}, + FuzzyRowFilter.satisfiesUnsafe(true, + new byte[]{2, 1, 1, 1, 0}, 0, 5, new byte[]{1, 2, 0, 3}, - new byte[]{-1, -1, 0, -1})); + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS, - FuzzyRowFilter.satisfies(true, - new byte[]{1, 2, 1, 0, 1}, + FuzzyRowFilter.satisfiesUnsafe(true, + new byte[]{1, 2, 1, 0, 1}, 0, 5, new byte[]{0, 1, 2}, - new byte[]{0, -1, -1})); + new byte[]{NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER, FIXED_BYTE_INNER})); } @Test @@ -174,247 +247,271 @@ public class TestFuzzyRowFilter { new byte[]{1, (byte) -128, 1, 0, 1}, 0, 5, new byte[]{1, 0, 1}, - new byte[]{0, 1, 0})); + new byte[]{FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS, FuzzyRowFilter.satisfiesNoUnsafe(true, new byte[]{1, (byte) -128, 2, 0, 1}, 0, 5, new byte[]{1, 0, 1}, - new byte[]{0, 1, 0})); + new byte[]{FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS, FuzzyRowFilter.satisfiesNoUnsafe(true, new byte[]{2, 3, 1, 1, 1}, 0, 5, new byte[]{1, 0, 1}, - new byte[]{0, 1, 0})); + new byte[]{FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.YES, FuzzyRowFilter.satisfiesNoUnsafe(true, new byte[]{1, 2, 1, 3, 3}, 0, 5, new byte[]{1, 2, 0, 3}, - new byte[]{0, 0, 1, 0})); + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS, FuzzyRowFilter.satisfiesNoUnsafe(true, new byte[]{1, (byte) 245, 1, 3, 0}, 0, 5, new byte[]{1, 1, 0, 3}, - new byte[]{0, 0, 1, 0})); + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS, FuzzyRowFilter.satisfiesNoUnsafe(true, new byte[]{1, 3, 1, 3, 0}, 0, 5, new byte[]{1, 2, 0, 3}, - new byte[]{0, 0, 1, 0})); + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS, FuzzyRowFilter.satisfiesNoUnsafe(true, new byte[]{2, 1, 1, 1, 0}, 0, 5, new byte[]{1, 2, 0, 3}, - new byte[]{0, 0, 1, 0})); + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); Assert.assertEquals(FuzzyRowFilter.SatisfiesCode.NEXT_EXISTS, FuzzyRowFilter.satisfiesNoUnsafe(true, new byte[]{1, 2, 1, 0, 1}, 0, 5, new byte[]{0, 1, 2}, - new byte[]{1, 0, 0})); - } + new byte[]{NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER, FIXED_BYTE_INNER})); + } + @Test public void testGetNextForFuzzyRuleForward() { assertNext(false, new byte[]{0, 1, 2}, // fuzzy row - new byte[]{0, -1, -1}, // mask + new byte[]{NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER, FIXED_BYTE_INNER}, // mask new byte[]{1, 2, 1, 0, 1}, // current new byte[]{2, 1, 2}); // expected next assertNext(false, new byte[]{0, 1, 2}, // fuzzy row - new byte[]{0, -1, -1}, // mask + new byte[]{NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER, FIXED_BYTE_INNER}, // mask new byte[]{1, 1, 2, 0, 1}, // current new byte[]{1, 1, 2, 0, 2}); // expected next assertNext(false, new byte[]{0, 1, 0, 2, 0}, // fuzzy row - new byte[]{0, -1, 0, -1, 0}, // mask + new byte[]{NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, + FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER}, // mask new byte[]{1, 0, 2, 0, 1}, // current new byte[]{1, 1, 0, 2}); // expected next assertNext(false, new byte[]{1, 0, 1}, - new byte[]{-1, 0, -1}, + new byte[]{FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER}, new byte[]{1, (byte) 128, 2, 0, 1}, new byte[]{1, (byte) 129, 1}); assertNext(false, new byte[]{0, 1, 0, 1}, - new byte[]{0, -1, 0, -1}, + new byte[]{NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER}, // mask new byte[]{5, 1, 0, 1}, new byte[]{5, 1, 1, 1}); assertNext(false, new byte[]{0, 1, 0, 1}, - new byte[]{0, -1, 0, -1}, + new byte[]{NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER}, // mask new byte[]{5, 1, 0, 1, 1}, new byte[]{5, 1, 0, 1, 2}); assertNext(false, new byte[]{0, 1, 0, 0}, // fuzzy row - new byte[]{0, -1, 0, 0}, // mask + new byte[]{NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER}, // mask new byte[]{5, 1, (byte) 255, 1}, // current new byte[]{5, 1, (byte) 255, 2}); // expected next assertNext(false, new byte[]{0, 1, 0, 1}, // fuzzy row - new byte[]{0, -1, 0, -1}, // mask + new byte[]{NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER}, // mask new byte[]{5, 1, (byte) 255, 1}, // current new byte[]{6, 1, 0, 1}); // expected next assertNext(false, new byte[]{0, 1, 0, 1}, // fuzzy row - new byte[]{0, -1, 0, -1}, // mask + new byte[]{NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER}, // mask new byte[]{5, 1, (byte) 255, 0}, // current new byte[]{5, 1, (byte) 255, 1}); // expected next assertNext(false, new byte[]{5, 1, 1, 0}, - new byte[]{-1, -1, 0, 0}, + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER}, // mask new byte[]{5, 1, (byte) 255, 1}, new byte[]{5, 1, (byte) 255, 2}); assertNext(false, new byte[]{1, 1, 1, 1}, - new byte[]{-1, -1, 0, 0}, + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER}, // mask new byte[]{1, 1, 2, 2}, new byte[]{1, 1, 2, 3}); assertNext(false, new byte[]{1, 1, 1, 1}, - new byte[]{-1, -1, 0, 0}, + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER}, // mask new byte[]{1, 1, 3, 2}, new byte[]{1, 1, 3, 3}); assertNext(false, new byte[]{1, 1, 1, 1}, - new byte[]{0, 0, 0, 0}, + new byte[]{NON_FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER}, // mask new byte[]{1, 1, 2, 3}, new byte[]{1, 1, 2, 4}); assertNext(false, new byte[]{1, 1, 1, 1}, - new byte[]{0, 0, 0, 0}, + new byte[]{NON_FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER}, // mask new byte[]{1, 1, 3, 2}, new byte[]{1, 1, 3, 3}); assertNext(false, new byte[]{1, 1, 0, 0}, - new byte[]{-1, -1, 0, 0}, + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER}, // mask new byte[]{0, 1, 3, 2}, new byte[]{1, 1}); // No next for this one - Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule( - new byte[]{2, 3, 1, 1, 1}, // row to check + Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule(false, + new byte[]{2, 3, 1, 1, 1}, 0, 5,// row to check new byte[]{1, 0, 1}, // fuzzy row - new byte[]{-1, 0, -1})); // mask - Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule( - new byte[]{1, (byte) 245, 1, 3, 0}, + new byte[]{FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); // mask + Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule(false, + new byte[]{1, (byte) 245, 1, 3, 0}, 0, 5, new byte[]{1, 1, 0, 3}, - new byte[]{-1, -1, 0, -1})); - Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule( - new byte[]{1, 3, 1, 3, 0}, + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); + Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule(false, + new byte[]{1, 3, 1, 3, 0}, 0, 5, new byte[]{1, 2, 0, 3}, - new byte[]{-1, -1, 0, -1})); - Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule( - new byte[]{2, 1, 1, 1, 0}, + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); + Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule(false, + new byte[]{2, 1, 1, 1, 0}, 0, 5, new byte[]{1, 2, 0, 3}, - new byte[]{-1, -1, 0, -1})); + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); } @Test public void testGetNextForFuzzyRuleReverse() { assertNext(true, new byte[]{0, 1, 2}, // fuzzy row - new byte[]{0, -1, -1}, // mask + new byte[]{NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER, FIXED_BYTE_INNER}, // mask new byte[]{1, 2, 1, 0, 1}, // current // TODO: should be {1, 1, 3} ? new byte[]{1, 1, 2, (byte) 0xFF, (byte) 0xFF}); // expected next assertNext(true, new byte[]{0, 1, 0, 2, 0}, // fuzzy row - new byte[]{0, -1, 0, -1, 0}, // mask + new byte[]{NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, + FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER}, // mask new byte[]{1, 2, 1, 3, 1}, // current // TODO: should be {1, 1, 1, 3} ? new byte[]{1, 1, 0, 2, 0}); // expected next assertNext(true, new byte[]{1, 0, 1}, - new byte[]{-1, 0, -1}, + new byte[]{FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER}, new byte[]{1, (byte) 128, 2, 0, 1}, // TODO: should be {1, (byte) 128, 2} ? new byte[]{1, (byte) 128, 1, (byte) 0xFF, (byte) 0xFF}); assertNext(true, new byte[]{0, 1, 0, 1}, - new byte[]{0, -1, 0, -1}, + new byte[]{NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER}, new byte[]{5, 1, 0, 2, 1}, // TODO: should be {5, 1, 0, 2} ? new byte[]{5, 1, 0, 1, (byte) 0xFF}); assertNext(true, new byte[]{0, 1, 0, 0}, // fuzzy row - new byte[]{0, -1, 0, 0}, // mask + new byte[]{NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER}, // mask new byte[]{5, 1, (byte) 255, 1}, // current new byte[]{5, 1, (byte) 255, 0}); // expected next assertNext(true, new byte[]{0, 1, 0, 1}, // fuzzy row - new byte[]{0, -1, 0, -1}, // mask + new byte[]{NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER}, // mask new byte[]{5, 1, 0, 1}, // current new byte[]{4, 1, (byte) 255, 1}); // expected next assertNext(true, new byte[]{0, 1, 0, 1}, // fuzzy row - new byte[]{0, -1, 0, -1}, // mask + new byte[]{NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER}, // mask new byte[]{5, 1, (byte) 255, 0}, // current new byte[]{5, 1, (byte) 254, 1}); // expected next assertNext(true, new byte[]{1, 1, 0, 0}, - new byte[]{-1, -1, 0, 0}, + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER}, // mask new byte[]{2, 1, 3, 2}, // TODO: should be {1, 0} ? new byte[]{1, 1, 0, 0}); assertNext(true, new byte[]{1, 0, 1}, // fuzzy row - new byte[]{-1, 0, -1}, // mask + new byte[]{FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER}, // mask new byte[]{2, 3, 1, 1, 1}, // row to check // TODO: should be {1, (byte) 0xFF, 2} ? new byte[]{1, 0, 1, (byte) 0xFF, (byte) 0xFF}); assertNext(true, new byte[]{1, 1, 0, 3}, - new byte[]{-1, -1, 0, -1}, + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER}, // mask new byte[]{1, (byte) 245, 1, 3, 0}, // TODO: should be {1, 1, (byte) 255, 4} ? new byte[]{1, 1, 0, 3, (byte) 0xFF}); assertNext(true, new byte[]{1, 2, 0, 3}, - new byte[]{-1, -1, 0, -1}, + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER}, // mask new byte[]{1, 3, 1, 3, 0}, // TODO: should be 1, 2, (byte) 255, 4 ? new byte[]{1, 2, 0, 3, (byte) 0xFF}); assertNext(true, new byte[]{1, 2, 0, 3}, - new byte[]{-1, -1, 0, -1}, + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER}, // mask new byte[]{2, 1, 1, 1, 0}, // TODO: should be {1, 2, (byte) 255, 4} ? new byte[]{1, 2, 0, 3, (byte) 0xFF}); @@ -422,42 +519,47 @@ public class TestFuzzyRowFilter { assertNext(true, // TODO: should be null? new byte[]{1, 0, 1}, - new byte[]{-1, 0, -1}, + new byte[]{FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER}, // mask new byte[]{1, (byte) 128, 2}, new byte[]{1, (byte) 128, 1}); assertNext(true, // TODO: should be null? new byte[]{0, 1, 0, 1}, - new byte[]{0, -1, 0, -1}, + new byte[]{NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER}, // mask new byte[]{5, 1, 0, 2}, new byte[]{5, 1, 0, 1}); assertNext(true, // TODO: should be null? new byte[]{5, 1, 1, 0}, - new byte[]{-1, -1, 0, 0}, + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER}, // mask new byte[]{5, 1, (byte) 0xFF, 1}, new byte[]{5, 1, (byte) 0xFF, 0}); assertNext(true, // TODO: should be null? new byte[]{1, 1, 1, 1}, - new byte[]{-1, -1, 0, 0}, + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER}, // mask new byte[]{1, 1, 2, 2}, new byte[]{1, 1, 2, 1}); assertNext(true, // TODO: should be null? new byte[]{1, 1, 1, 1}, - new byte[]{0, 0, 0, 0}, + new byte[]{NON_FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, NON_FIXED_BYTE_INNER}, // mask new byte[]{1, 1, 2, 3}, new byte[]{1, 1, 2, 2}); Assert.assertNull(FuzzyRowFilter.getNextForFuzzyRule(true, - new byte[]{1, 1, 1, 3, 0}, + new byte[]{1, 1, 1, 3, 0}, 0, 5, new byte[]{1, 2, 0, 3}, - new byte[]{-1, -1, 0, -1})); + new byte[]{FIXED_BYTE_INNER, FIXED_BYTE_INNER, + NON_FIXED_BYTE_INNER, FIXED_BYTE_INNER})); } private static void assertNext(boolean reverse, byte[] fuzzyRow, byte[] mask, byte[] current, diff --git hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestFuzzyRowFilterEndToEndWoUnsafe.java hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestFuzzyRowFilterEndToEndWoUnsafe.java new file mode 100644 index 0000000000..bd925b83af --- /dev/null +++ hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestFuzzyRowFilterEndToEndWoUnsafe.java @@ -0,0 +1,40 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.hbase.filter; + +import org.apache.hadoop.hbase.testclassification.FilterTests; +import org.apache.hadoop.hbase.testclassification.MediumTests; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +@Category({ FilterTests.class, MediumTests.class }) +public class TestFuzzyRowFilterEndToEndWoUnsafe extends TestFuzzyRowFilterEndToEnd { + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + TestFuzzyRowFilter.disableUnsafe(); + TestFuzzyRowFilterEndToEnd.setUpBeforeClass(); + } + + @AfterClass + public static void tearDownAfterClass() throws Exception { + TestFuzzyRowFilterEndToEnd.tearDownAfterClass(); + TestFuzzyRowFilter.detectAvailabilityOfUnsafe(); + } +}