diff --git a/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPolicy.java b/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPolicy.java new file mode 100644 index 00000000000..5366a15c476 --- /dev/null +++ b/src/main/java/org/apache/hadoop/hbase/regionserver/KeyPrefixRegionSplitPolicy.java @@ -0,0 +1,78 @@ +/** + * 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.regionserver; + +import java.util.Arrays; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * A custom RegionSplitPolicy implementing a SplitPolicy that groups + * rows by a prefix of the row-key + * + * This ensures that a region is not split "inside" a prefix of a row key. + * I.e. rows can be co-located in a regionb by their prefix. + */ +public class KeyPrefixRegionSplitPolicy extends ConstantSizeRegionSplitPolicy { + private static final Log LOG = LogFactory + .getLog(KeyPrefixRegionSplitPolicy.class); + public static String PREFIX_LENGTH_KEY = "prefix_split_key_policy.prefix_length"; + + private int prefixLength = 0; + + @Override + protected void configureForRegion(HRegion region) { + super.configureForRegion(region); + if (region != null) { + prefixLength = 0; + + // read the prefix length from the table descriptor + String prefixLengthString = region.getTableDesc().getValue( + PREFIX_LENGTH_KEY); + if (prefixLengthString == null) { + LOG.error(PREFIX_LENGTH_KEY + " not specified for table " + + region.getTableDesc().getNameAsString() + + ". Using default RegionSplitPolicy"); + return; + } + try { + prefixLength = Integer.parseInt(prefixLengthString); + } catch (NumberFormatException nfe) { + // ignore + } + if (prefixLength <= 0) { + LOG.error("Invalid value for " + PREFIX_LENGTH_KEY + " for table " + + region.getTableDesc().getNameAsString() + ":" + + prefixLengthString + ". Using default RegionSplitPolicy"); + } + } + } + + @Override + protected byte[] getSplitPoint() { + byte[] splitPoint = super.getSplitPoint(); + if (prefixLength > 0 && splitPoint != null && splitPoint.length > 0) { + // group split keys by a prefix + return Arrays.copyOf(splitPoint, + Math.min(prefixLength, splitPoint.length)); + } else { + return splitPoint; + } + } +} diff --git a/src/test/java/org/apache/hadoop/hbase/regionserver/PrefixSplitKeyPolicy.java b/src/test/java/org/apache/hadoop/hbase/regionserver/PrefixSplitKeyPolicy.java deleted file mode 100644 index 6b90bd637d1..00000000000 --- a/src/test/java/org/apache/hadoop/hbase/regionserver/PrefixSplitKeyPolicy.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * 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.regionserver; - -import java.util.Arrays; - -/** - * A custom RegionSplitPolicy for testing. - * This class also demonstrates how to implement a SplitPolicy that groups - * rows by a prefix of the row-key - * - * This ensures that a region is not split "inside" - * a prefix of a row key. I.e. rows can be co-located by - * their prefix. - */ -public class PrefixSplitKeyPolicy extends ConstantSizeRegionSplitPolicy { - public static String PREFIX_LENGTH_KEY = "prefix_split_key_policy.prefix_length"; - - private int prefix_length; - - @Override - protected void configureForRegion(HRegion region) { - super.configureForRegion(region); - - if (region != null) { - // this demonstrates how a RegionSplitPolicy can be configured - // through HTableDescriptor values - prefix_length = Integer.parseInt(region.getTableDesc().getValue( - PREFIX_LENGTH_KEY)); - } - } - - @Override - protected byte[] getSplitPoint() { - byte[] splitPoint = super.getSplitPoint(); - if (splitPoint != null && splitPoint.length > 0) { - // group split keys by a prefix - return Arrays.copyOf(splitPoint, - Math.min(prefix_length, splitPoint.length)); - } else { - return splitPoint; - } - } -} diff --git a/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionSplitPolicy.java b/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionSplitPolicy.java index 332791f8464..9f57b7c72c0 100644 --- a/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionSplitPolicy.java +++ b/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionSplitPolicy.java @@ -79,8 +79,8 @@ public class TestRegionSplitPolicy { public void testCustomPolicy() throws IOException { HTableDescriptor myHtd = new HTableDescriptor(); myHtd.setValue(HTableDescriptor.SPLIT_POLICY, - PrefixSplitKeyPolicy.class.getName()); - myHtd.setValue(PrefixSplitKeyPolicy.PREFIX_LENGTH_KEY, String.valueOf(2)); + KeyPrefixRegionSplitPolicy.class.getName()); + myHtd.setValue(KeyPrefixRegionSplitPolicy.PREFIX_LENGTH_KEY, String.valueOf(2)); HRegion myMockRegion = Mockito.mock(HRegion.class); Mockito.doReturn(myHtd).when(myMockRegion).getTableDesc(); @@ -92,7 +92,7 @@ public class TestRegionSplitPolicy { Mockito.doReturn(Bytes.toBytes("abcd")).when(mockStore).getSplitPoint(); stores.put(new byte[] { 1 }, mockStore); - PrefixSplitKeyPolicy policy = (PrefixSplitKeyPolicy) RegionSplitPolicy + KeyPrefixRegionSplitPolicy policy = (KeyPrefixRegionSplitPolicy) RegionSplitPolicy .create(myMockRegion, conf); assertEquals("ab", Bytes.toString(policy.getSplitPoint())); @@ -101,7 +101,7 @@ public class TestRegionSplitPolicy { Mockito.doReturn(Bytes.toBytes("efgh")).when(myMockRegion) .getExplicitSplitPoint(); - policy = (PrefixSplitKeyPolicy) RegionSplitPolicy + policy = (KeyPrefixRegionSplitPolicy) RegionSplitPolicy .create(myMockRegion, conf); assertEquals("ef", Bytes.toString(policy.getSplitPoint()));