001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.regionserver; 019 020import java.util.Arrays; 021import org.apache.hadoop.hbase.util.Bytes; 022import org.apache.yetus.audience.InterfaceAudience; 023import org.slf4j.Logger; 024import org.slf4j.LoggerFactory; 025 026/** 027 * A custom RegionSplitPolicy implementing a SplitPolicy that groups rows by a prefix of the row-key 028 * with a delimiter. Only the first delimiter for the row key will define the prefix of the row key 029 * that is used for grouping. This ensures that a region is not split "inside" a prefix of a row 030 * key. I.e. rows can be co-located in a region by their prefix. As an example, if you have row keys 031 * delimited with <code>_</code>, like <code>userid_eventtype_eventid</code>, and use prefix 032 * delimiter _, this split policy ensures that all rows starting with the same userid, belongs to 033 * the same region. 034 * @see KeyPrefixRegionSplitPolicy 035 * @deprecated since 3.0.0 and will be removed in 4.0.0. Use {@link RegionSplitRestriction}, 036 * instead. 037 */ 038@Deprecated 039@InterfaceAudience.Private 040public class DelimitedKeyPrefixRegionSplitPolicy extends IncreasingToUpperBoundRegionSplitPolicy { 041 042 private static final Logger LOG = 043 LoggerFactory.getLogger(DelimitedKeyPrefixRegionSplitPolicy.class); 044 public static final String DELIMITER_KEY = "DelimitedKeyPrefixRegionSplitPolicy.delimiter"; 045 046 private byte[] delimiter = null; 047 048 @Override 049 public String toString() { 050 return "DelimitedKeyPrefixRegionSplitPolicy{" + "delimiter=" + Bytes.toStringBinary(delimiter) 051 + ", " + super.toString() + '}'; 052 } 053 054 @Override 055 protected void configureForRegion(HRegion region) { 056 super.configureForRegion(region); 057 // read the prefix length from the table descriptor 058 String delimiterString = region.getTableDescriptor().getValue(DELIMITER_KEY); 059 if (delimiterString == null || delimiterString.length() == 0) { 060 LOG.error(DELIMITER_KEY + " not specified for table " 061 + region.getTableDescriptor().getTableName() + ". Using default RegionSplitPolicy"); 062 return; 063 } 064 delimiter = Bytes.toBytes(delimiterString); 065 } 066 067 @Override 068 protected byte[] getSplitPoint() { 069 byte[] splitPoint = super.getSplitPoint(); 070 if (splitPoint != null && delimiter != null) { 071 072 // find the first occurrence of delimiter in split point 073 int index = org.apache.hbase.thirdparty.com.google.common.primitives.Bytes.indexOf(splitPoint, 074 delimiter); 075 if (index < 0) { 076 LOG.warn("Delimiter " + Bytes.toString(delimiter) + " not found for split key " 077 + Bytes.toString(splitPoint)); 078 return splitPoint; 079 } 080 081 // group split keys by a prefix 082 return Arrays.copyOf(splitPoint, Math.min(index, splitPoint.length)); 083 } else { 084 return splitPoint; 085 } 086 } 087}