HBASE-24734 RegionInfo#containsRange should support check meta table (#3496) (#3517)

Signed-off-by: zhangduo <zhangduo@apache.org>
This commit is contained in:
meiyi 2021-07-22 18:04:24 +08:00 committed by GitHub
parent 8bc180c773
commit 729da5a6d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 93 additions and 5 deletions

View File

@ -17,6 +17,8 @@
*/ */
package org.apache.hadoop.hbase.client; package org.apache.hadoop.hbase.client;
import java.util.Arrays; import java.util.Arrays;
import org.apache.hadoop.hbase.CellComparator;
import org.apache.hadoop.hbase.CellComparatorImpl;
import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Bytes;
@ -206,15 +208,16 @@ class MutableRegionInfo implements RegionInfo {
*/ */
@Override @Override
public boolean containsRange(byte[] rangeStartKey, byte[] rangeEndKey) { public boolean containsRange(byte[] rangeStartKey, byte[] rangeEndKey) {
if (Bytes.compareTo(rangeStartKey, rangeEndKey) > 0) { CellComparator cellComparator = CellComparatorImpl.getCellComparator(tableName);
if (cellComparator.compareRows(rangeStartKey, rangeEndKey) > 0) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Invalid range: " + Bytes.toStringBinary(rangeStartKey) + "Invalid range: " + Bytes.toStringBinary(rangeStartKey) +
" > " + Bytes.toStringBinary(rangeEndKey)); " > " + Bytes.toStringBinary(rangeEndKey));
} }
boolean firstKeyInRange = Bytes.compareTo(rangeStartKey, startKey) >= 0; boolean firstKeyInRange = cellComparator.compareRows(rangeStartKey, startKey) >= 0;
boolean lastKeyInRange = boolean lastKeyInRange =
Bytes.compareTo(rangeEndKey, endKey) < 0 || cellComparator.compareRows(rangeEndKey, endKey) < 0 ||
Bytes.equals(endKey, HConstants.EMPTY_BYTE_ARRAY); Bytes.equals(endKey, HConstants.EMPTY_BYTE_ARRAY);
return firstKeyInRange && lastKeyInRange; return firstKeyInRange && lastKeyInRange;
} }
@ -224,8 +227,9 @@ class MutableRegionInfo implements RegionInfo {
*/ */
@Override @Override
public boolean containsRow(byte[] row) { public boolean containsRow(byte[] row) {
return Bytes.compareTo(row, startKey) >= 0 && CellComparator cellComparator = CellComparatorImpl.getCellComparator(tableName);
(Bytes.compareTo(row, endKey) < 0 || return cellComparator.compareRows(row, startKey) >= 0 &&
(cellComparator.compareRows(row, endKey) < 0 ||
Bytes.equals(endKey, HConstants.EMPTY_BYTE_ARRAY)); Bytes.equals(endKey, HConstants.EMPTY_BYTE_ARRAY));
} }

View File

@ -26,6 +26,7 @@ import static org.junit.Assert.fail;
import java.io.IOException; import java.io.IOException;
import org.apache.hadoop.hbase.HBaseClassTestRule; import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.TableNameTestRule; import org.apache.hadoop.hbase.TableNameTestRule;
import org.apache.hadoop.hbase.exceptions.DeserializationException; import org.apache.hadoop.hbase.exceptions.DeserializationException;
@ -137,6 +138,39 @@ public class TestRegionInfoBuilder {
} }
} }
@Test
public void testContainsRangeForMetaTable() {
TableDescriptor tableDesc =
TableDescriptorBuilder.newBuilder(TableName.META_TABLE_NAME).build();
RegionInfo hri = RegionInfoBuilder.newBuilder(tableDesc.getTableName()).build();
byte[] startRow = HConstants.EMPTY_START_ROW;
byte[] row1 = Bytes.toBytes("a,a,0");
byte[] row2 = Bytes.toBytes("aaaaa,,1");
byte[] row3 = Bytes.toBytes("aaaaa,\u0000\u0000,2");
byte[] row4 = Bytes.toBytes("aaaaa,\u0001,3");
byte[] row5 = Bytes.toBytes("aaaaa,a,4");
byte[] row6 = Bytes.toBytes("aaaaa,\u1000,5");
// Single row range at start of region
assertTrue(hri.containsRange(startRow, startRow));
// Fully contained range
assertTrue(hri.containsRange(row1, row2));
assertTrue(hri.containsRange(row2, row3));
assertTrue(hri.containsRange(row3, row4));
assertTrue(hri.containsRange(row4, row5));
assertTrue(hri.containsRange(row5, row6));
// Range overlapping start of region
assertTrue(hri.containsRange(startRow, row2));
// Fully contained single-row range
assertTrue(hri.containsRange(row1, row1));
// Degenerate range
try {
hri.containsRange(row3, row2);
fail("Invalid range did not throw IAE");
} catch (IllegalArgumentException iae) {
}
}
@Test @Test
public void testLastRegionCompare() { public void testLastRegionCompare() {
TableDescriptor tableDesc = TableDescriptorBuilder.newBuilder(name.getTableName()).build(); TableDescriptor tableDesc = TableDescriptorBuilder.newBuilder(name.getTableName()).build();

View File

@ -20,6 +20,7 @@ package org.apache.hadoop.hbase;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.Comparator; import java.util.Comparator;
import org.apache.hadoop.hbase.util.ByteBufferUtils; import org.apache.hadoop.hbase.util.ByteBufferUtils;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.yetus.audience.InterfaceAudience; import org.apache.yetus.audience.InterfaceAudience;
import org.apache.yetus.audience.InterfaceStability; import org.apache.yetus.audience.InterfaceStability;
@ -82,6 +83,17 @@ public interface CellComparator extends Comparator<Cell> {
*/ */
int compareRows(Cell cell, byte[] bytes, int offset, int length); int compareRows(Cell cell, byte[] bytes, int offset, int length);
/**
* Compares two row bytes
* @param leftRow the byte array of the left row
* @param rightRow the byte array of the right row
* @return greater than 0 if leftRow is bigger, less than 0 if rightRow is bigger, 0 if both
* rows are equal
*/
default int compareRows(byte[] leftRow, byte[] rightRow) {
return Bytes.compareTo(leftRow, rightRow);
}
/** /**
* @param row ByteBuffer that wraps a row; will read from current position and will reading all * @param row ByteBuffer that wraps a row; will read from current position and will reading all
* remaining; will not disturb the ByteBuffer internal state. * remaining; will not disturb the ByteBuffer internal state.

View File

@ -55,6 +55,11 @@ public class MetaCellComparator extends CellComparatorImpl {
rlength); rlength);
} }
@Override
public int compareRows(byte[] leftRow, byte[] rightRow) {
return compareRows(leftRow, 0, leftRow.length, rightRow, 0, rightRow.length);
}
@Override @Override
public int compare(final Cell a, final Cell b, boolean ignoreSequenceid) { public int compare(final Cell a, final Cell b, boolean ignoreSequenceid) {
int diff = compareRows(a, b); int diff = compareRows(a, b);

View File

@ -30,6 +30,7 @@ import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HRegionInfo; import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.RegionInfo; import org.apache.hadoop.hbase.client.RegionInfo;
import org.apache.hadoop.hbase.client.RegionInfoBuilder; import org.apache.hadoop.hbase.client.RegionInfoBuilder;
@ -251,6 +252,38 @@ public class TestHRegionInfo {
} }
} }
@Test
public void testContainsRangeForMetaTable() {
HTableDescriptor tableDesc = new HTableDescriptor(TableName.META_TABLE_NAME);
RegionInfo hri = RegionInfoBuilder.newBuilder(tableDesc.getTableName()).build();
byte[] startRow = HConstants.EMPTY_START_ROW;
byte[] row1 = Bytes.toBytes("a,a,0");
byte[] row2 = Bytes.toBytes("aaaaa,,1");
byte[] row3 = Bytes.toBytes("aaaaa,\u0000\u0000,2");
byte[] row4 = Bytes.toBytes("aaaaa,\u0001,3");
byte[] row5 = Bytes.toBytes("aaaaa,a,4");
byte[] row6 = Bytes.toBytes("aaaaa,\u1000,5");
// Single row range at start of region
assertTrue(hri.containsRange(startRow, startRow));
// Fully contained range
assertTrue(hri.containsRange(row1, row2));
assertTrue(hri.containsRange(row2, row3));
assertTrue(hri.containsRange(row3, row4));
assertTrue(hri.containsRange(row4, row5));
assertTrue(hri.containsRange(row5, row6));
// Range overlapping start of region
assertTrue(hri.containsRange(startRow, row2));
// Fully contained single-row range
assertTrue(hri.containsRange(row1, row1));
// Degenerate range
try {
hri.containsRange(row3, row2);
fail("Invalid range did not throw IAE");
} catch (IllegalArgumentException iae) {
}
}
@Test @Test
public void testLastRegionCompare() { public void testLastRegionCompare() {
HTableDescriptor tableDesc = new HTableDescriptor(TableName.valueOf(name.getMethodName())); HTableDescriptor tableDesc = new HTableDescriptor(TableName.valueOf(name.getMethodName()));