Skip to content

Commit

Permalink
fix hbase/rocksdb shard bug (#1306)
Browse files Browse the repository at this point in the history
fixed: #1299 

Change-Id: Ifce3d450712104c067a57c361351c9e047bc0cfa
  • Loading branch information
zhoney authored Dec 25, 2020
1 parent f6c9850 commit 0f15c46
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ protected long maxKey() {

protected abstract long estimateNumKeys(Session session);

protected static class Range {
public static class Range {

private byte[] startKey;
private byte[] endKey;
Expand Down Expand Up @@ -247,15 +247,15 @@ public List<Shard> splitEven(int count) {
}

assert count > 1;
assert startChanged != endChanged;
byte[] each = align(new BigInteger(1, subtract(end, start))
.divide(BigInteger.valueOf(count))
.toByteArray(),
length);
byte[] offset = start;
byte[] last = offset;
boolean finished = false;
List<Shard> shards = new ArrayList<>(count);
while (Bytes.compare(offset, end) < 0) {
while (Bytes.compare(offset, end) < 0 && !finished) {
offset = add(offset, each);
if (offset.length > end.length ||
Bytes.compare(offset, end) > 0) {
Expand All @@ -267,6 +267,7 @@ public List<Shard> splitEven(int count) {
}
if (endChanged && Arrays.equals(offset, end)) {
offset = this.endKey;
finished = true;
}
shards.add(new Shard(startKey(last), endKey(offset), 0));
last = offset;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ private static Map<String, Double> regionSizes(Session session,
private static Map<String, Range> regionRanges(Session session,
String namespace,
String table) {
Map<String, Range> regionRanges = new HashMap<>();
Map<String, Range> regionRanges = InsertionOrderUtil.newMap();
TableName tableName = TableName.valueOf(namespace, table);
try (Admin admin = session.hbase().getAdmin()) {
for (RegionInfo regionInfo : admin.getRegions(tableName)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import com.baidu.hugegraph.unit.core.ExceptionTest;
import com.baidu.hugegraph.unit.core.LocksTableTest;
import com.baidu.hugegraph.unit.core.QueryTest;
import com.baidu.hugegraph.unit.core.RangeTest;
import com.baidu.hugegraph.unit.core.RolePermissionTest;
import com.baidu.hugegraph.unit.core.RowLockTest;
import com.baidu.hugegraph.unit.core.SecurityManagerTest;
Expand Down Expand Up @@ -91,6 +92,7 @@
ConditionTest.class,
ConditionQueryFlattenTest.class,
QueryTest.class,
RangeTest.class,
SecurityManagerTest.class,
RolePermissionTest.class,
ExceptionTest.class,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
/*
* Copyright 2017 HugeGraph Authors
*
* 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 com.baidu.hugegraph.unit.core;

import java.util.List;

import org.apache.logging.log4j.util.Strings;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.baidu.hugegraph.backend.store.BackendTable.ShardSpliter.Range;
import com.baidu.hugegraph.backend.store.Shard;
import com.baidu.hugegraph.testutil.Assert;

public class RangeTest {

private static final byte[] START = new byte[]{0x0};
private static final byte[] END = new byte[]{
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1
};

@Before
public void setup() {
// pass
}

@After
public void teardown() {
// pass
}

@Test
public void testRangeOfOnlyOneRegion() {
// The startKey and endKey is "", if it's the only region of table
Range range = new Range(START, END);

List<Shard> shards = range.splitEven(0);
Assert.assertEquals(1, shards.size());
Assert.assertEquals(Strings.EMPTY, shards.get(0).start());
Assert.assertEquals(Strings.EMPTY, shards.get(0).end());

shards = range.splitEven(1);
Assert.assertEquals(1, shards.size());
Assert.assertEquals(Strings.EMPTY, shards.get(0).start());
Assert.assertEquals(Strings.EMPTY, shards.get(0).end());

shards = range.splitEven(3);
Assert.assertEquals(3, shards.size());
Assert.assertEquals(Strings.EMPTY, shards.get(0).start());
Assert.assertEquals("VVVVVVVVVVVVVVVVVVVVVQ==", shards.get(0).end());
Assert.assertEquals("VVVVVVVVVVVVVVVVVVVVVQ==", shards.get(1).start());
Assert.assertEquals("qqqqqqqqqqqqqqqqqqqqqg==", shards.get(1).end());
Assert.assertEquals("qqqqqqqqqqqqqqqqqqqqqg==", shards.get(2).start());
Assert.assertEquals(Strings.EMPTY, shards.get(2).end());

for (int i = 4; i < 100; i++) {
range.splitEven(i);
}
}

@Test
public void testRangeOfRegionWithEndKey() {
byte[] end = new byte[]{-3, 0x31, 0x30, 0x30, 0x30, 0x77,
0x20, 0x09, 0x38, 0x31, 0x33, 0x32, 0x35};
Range range = new Range(START, end);

List<Shard> shards = range.splitEven(0);
Assert.assertEquals(1, shards.size());
Assert.assertEquals(Strings.EMPTY, shards.get(0).start());
Assert.assertEquals("/TEwMDB3IAk4MTMyNQ==", shards.get(0).end());

shards = range.splitEven(1);
Assert.assertEquals(1, shards.size());
Assert.assertEquals(Strings.EMPTY, shards.get(0).start());
Assert.assertEquals("/TEwMDB3IAk4MTMyNQ==", shards.get(0).end());

shards = range.splitEven(2);
Assert.assertEquals(3, shards.size());
Assert.assertEquals(Strings.EMPTY, shards.get(0).start());
Assert.assertEquals("fpiYGBg7kAScGJmZGg==", shards.get(0).end());
Assert.assertEquals("fpiYGBg7kAScGJmZGg==", shards.get(1).start());
Assert.assertEquals("/TEwMDB3IAk4MTMyNA==", shards.get(1).end());
Assert.assertEquals("/TEwMDB3IAk4MTMyNA==", shards.get(2).start());
Assert.assertEquals("/TEwMDB3IAk4MTMyNQ==", shards.get(2).end());

for (int i = 3; i < 100; i++) {
range.splitEven(i);
}
}

@Test
public void testRangeOfRegionWithStartKey() {
byte[] start = new byte[]{-3, 0x35, 0x30, 0x30,
0x30, 0x77, 0x4e, -37,
0x31, 0x31, 0x30, 0x30,
0x30, 0x37, 0x36, 0x33};
Range range = new Range(start, END);

List<Shard> shards = range.splitEven(0);
Assert.assertEquals(1, shards.size());
Assert.assertEquals("/TUwMDB3TtsxMTAwMDc2Mw==", shards.get(0).start());
Assert.assertEquals(Strings.EMPTY, shards.get(0).end());

shards = range.splitEven(1);
Assert.assertEquals(1, shards.size());
Assert.assertEquals("/TUwMDB3TtsxMTAwMDc2Mw==", shards.get(0).start());
Assert.assertEquals(Strings.EMPTY, shards.get(0).end());

shards = range.splitEven(2);
Assert.assertEquals(2, shards.size());
Assert.assertEquals("/TUwMDB3TtsxMTAwMDc2Mw==", shards.get(0).start());
Assert.assertEquals("/pqYGBg7p22YmJgYGBubGQ==", shards.get(0).end());
Assert.assertEquals("/pqYGBg7p22YmJgYGBubGQ==", shards.get(1).start());
Assert.assertEquals(Strings.EMPTY, shards.get(1).end());

for (int i = 3; i < 100; i++) {
range.splitEven(i);
}
}

@Test
public void testRangeOfRegionWithStartKeyAndEndKey() {
byte[] start = new byte[]{-3, 0x31, 0x30, 0x30, 0x30, 0x77,
0x20, 0x09, 0x38, 0x31, 0x33, 0x32, 0x35};
byte[] end = new byte[]{-3, 0x31, 0x33, 0x35, 0x33, 0x32,
0x37, 0x34, 0x31, 0x35, 0x32};

Range range = new Range(start, end);

List<Shard> shards = range.splitEven(0);
Assert.assertEquals(1, shards.size());
Assert.assertEquals("/TEwMDB3IAk4MTMyNQ==", shards.get(0).start());
Assert.assertEquals("/TEzNTMyNzQxNTI=", shards.get(0).end());

shards = range.splitEven(1);
Assert.assertEquals(1, shards.size());
Assert.assertEquals("/TEwMDB3IAk4MTMyNQ==", shards.get(0).start());
Assert.assertEquals("/TEzNTMyNzQxNTI=", shards.get(0).end());

shards = range.splitEven(2);
Assert.assertEquals(3, shards.size());
Assert.assertEquals("/TEwMDB3IAk4MTMyNQ==", shards.get(0).start());
Assert.assertEquals("/TExsrHUq560szKZGg==", shards.get(0).end());
Assert.assertEquals("/TExsrHUq560szKZGg==", shards.get(1).start());
Assert.assertEquals("/TEzNTMyNzQxNTH//w==", shards.get(1).end());
Assert.assertEquals("/TEzNTMyNzQxNTH//w==", shards.get(2).start());
Assert.assertEquals("/TEzNTMyNzQxNTI=", shards.get(2).end());

for (int i = 3; i < 100; i++) {
range.splitEven(i);
}
}
}

0 comments on commit 0f15c46

Please sign in to comment.