HBASE-12716 A bug in RegionSplitter.UniformSplit algorithm (Weichen Ye)

This commit is contained in:
tedyu 2014-12-28 07:49:12 -08:00
parent 826bcf1bb9
commit 882f4c9761
3 changed files with 19 additions and 4 deletions

View File

@ -1701,8 +1701,19 @@ public class Bytes {
diffBI = diffBI.add(BigInteger.ONE); diffBI = diffBI.add(BigInteger.ONE);
} }
final BigInteger splitsBI = BigInteger.valueOf(num + 1); final BigInteger splitsBI = BigInteger.valueOf(num + 1);
//when diffBI < splitBI, use an additional byte to increase diffBI
if(diffBI.compareTo(splitsBI) < 0) { if(diffBI.compareTo(splitsBI) < 0) {
return null; byte[] aPaddedAdditional = new byte[aPadded.length+1];
byte[] bPaddedAdditional = new byte[bPadded.length+1];
for (int i = 0; i < aPadded.length; i++){
aPaddedAdditional[i] = aPadded[i];
}
for (int j = 0; j < bPadded.length; j++){
bPaddedAdditional[j] = bPadded[j];
}
aPaddedAdditional[aPadded.length] = 0;
bPaddedAdditional[bPadded.length] = 0;
return iterateOnSplits(aPaddedAdditional, bPaddedAdditional, inclusive, num);
} }
final BigInteger intervalBI; final BigInteger intervalBI;
try { try {

View File

@ -101,9 +101,10 @@ public class TestBytes extends TestCase {
} }
assertTrue("Returned split should have 3 parts but has " + parts.length, parts.length == 3); assertTrue("Returned split should have 3 parts but has " + parts.length, parts.length == 3);
// If split more than once, this should fail // If split more than once, use additional byte to split
parts = Bytes.split(low, high, 2); parts = Bytes.split(low, high, 2);
assertTrue("Returned split but should have failed", parts == null); assertTrue("Split with an additional byte", parts != null);
assertEquals(parts.length, low.length + 1);
// Split 0 times should throw IAE // Split 0 times should throw IAE
try { try {

View File

@ -207,6 +207,9 @@ public class TestRegionSplitter {
xFF, xFF, xFF}, lastRow); xFF, xFF, xFF}, lastRow);
assertArrayEquals(splitPoint, assertArrayEquals(splitPoint,
new byte[] {(byte)0xef, xFF, xFF, xFF, xFF, xFF, xFF, xFF}); new byte[] {(byte)0xef, xFF, xFF, xFF, xFF, xFF, xFF, xFF});
splitPoint = splitter.split(new byte[] {'a', 'a', 'a'}, new byte[] {'a', 'a', 'b'});
assertArrayEquals(splitPoint, new byte[] {'a', 'a', 'a', (byte)0x80 });
} }
@Test @Test
@ -227,7 +230,7 @@ public class TestRegionSplitter {
assertTrue(splitFailsPrecondition(algo, "\\xAA", "\\xAA")); // range error assertTrue(splitFailsPrecondition(algo, "\\xAA", "\\xAA")); // range error
assertFalse(splitFailsPrecondition(algo, "\\x00", "\\x02", 3)); // should be fine assertFalse(splitFailsPrecondition(algo, "\\x00", "\\x02", 3)); // should be fine
assertFalse(splitFailsPrecondition(algo, "\\x00", "\\x0A", 11)); // should be fine assertFalse(splitFailsPrecondition(algo, "\\x00", "\\x0A", 11)); // should be fine
assertTrue(splitFailsPrecondition(algo, "\\x00", "\\x0A", 12)); // too granular assertFalse(splitFailsPrecondition(algo, "\\x00", "\\x0A", 12)); // should be fine
} }
private boolean splitFailsPrecondition(SplitAlgorithm algo) { private boolean splitFailsPrecondition(SplitAlgorithm algo) {