View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.regionserver;
19  
20  import java.util.Arrays;
21  
22  import org.apache.commons.logging.Log;
23  import org.apache.commons.logging.LogFactory;
24  import org.apache.hadoop.classification.InterfaceAudience;
25  
26  /**
27   * A custom RegionSplitPolicy implementing a SplitPolicy that groups
28   * rows by a prefix of the row-key
29   *
30   * This ensures that a region is not split "inside" a prefix of a row key.
31   * I.e. rows can be co-located in a region by their prefix.
32   */
33  @InterfaceAudience.Private
34  public class KeyPrefixRegionSplitPolicy extends IncreasingToUpperBoundRegionSplitPolicy {
35    private static final Log LOG = LogFactory
36        .getLog(KeyPrefixRegionSplitPolicy.class);
37    @Deprecated
38    public static final String PREFIX_LENGTH_KEY_DEPRECATED = "prefix_split_key_policy.prefix_length";
39    public static final String PREFIX_LENGTH_KEY = "KeyPrefixRegionSplitPolicy.prefix_length";
40  
41    private int prefixLength = 0;
42  
43    @Override
44    protected void configureForRegion(HRegion region) {
45      super.configureForRegion(region);
46      if (region != null) {
47        prefixLength = 0;
48  
49        // read the prefix length from the table descriptor
50        String prefixLengthString = region.getTableDesc().getValue(
51            PREFIX_LENGTH_KEY);
52        if (prefixLengthString == null) {
53          //read the deprecated value
54          prefixLengthString = region.getTableDesc().getValue(PREFIX_LENGTH_KEY_DEPRECATED);
55          if (prefixLengthString == null) {
56            LOG.error(PREFIX_LENGTH_KEY + " not specified for table "
57                + region.getTableDesc().getTableName()
58                + ". Using default RegionSplitPolicy");
59            return;
60          }
61        }
62        try {
63          prefixLength = Integer.parseInt(prefixLengthString);
64        } catch (NumberFormatException nfe) {
65          // ignore
66        }
67        if (prefixLength <= 0) {
68          LOG.error("Invalid value for " + PREFIX_LENGTH_KEY + " for table "
69              + region.getTableDesc().getTableName() + ":"
70              + prefixLengthString + ". Using default RegionSplitPolicy");
71        }
72      }
73    }
74  
75    @Override
76    protected byte[] getSplitPoint() {
77      byte[] splitPoint = super.getSplitPoint();
78      if (prefixLength > 0 && splitPoint != null && splitPoint.length > 0) {
79        // group split keys by a prefix
80        return Arrays.copyOf(splitPoint,
81            Math.min(prefixLength, splitPoint.length));
82      } else {
83        return splitPoint;
84      }
85    }
86  }