1 /** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 package org.apache.hadoop.hbase.util; 21 22 import org.apache.hadoop.hbase.classification.InterfaceAudience; 23 import org.apache.hadoop.hbase.classification.InterfaceStability; 24 import org.apache.hadoop.conf.Configuration; 25 26 /** 27 * This class represents a common API for hashing functions. 28 */ 29 @InterfaceAudience.Private 30 @InterfaceStability.Stable 31 public abstract class Hash { 32 /** Constant to denote invalid hash type. */ 33 public static final int INVALID_HASH = -1; 34 /** Constant to denote {@link JenkinsHash}. */ 35 public static final int JENKINS_HASH = 0; 36 /** Constant to denote {@link MurmurHash}. */ 37 public static final int MURMUR_HASH = 1; 38 /** Constant to denote {@link MurmurHash3}. */ 39 public static final int MURMUR_HASH3 = 2; 40 41 /** 42 * This utility method converts String representation of hash function name 43 * to a symbolic constant. Currently three function types are supported, 44 * "jenkins", "murmur" and "murmur3". 45 * @param name hash function name 46 * @return one of the predefined constants 47 */ 48 public static int parseHashType(String name) { 49 if ("jenkins".equalsIgnoreCase(name)) { 50 return JENKINS_HASH; 51 } else if ("murmur".equalsIgnoreCase(name)) { 52 return MURMUR_HASH; 53 } else if ("murmur3".equalsIgnoreCase(name)) { 54 return MURMUR_HASH3; 55 } else { 56 return INVALID_HASH; 57 } 58 } 59 60 /** 61 * This utility method converts the name of the configured 62 * hash type to a symbolic constant. 63 * @param conf configuration 64 * @return one of the predefined constants 65 */ 66 public static int getHashType(Configuration conf) { 67 String name = conf.get("hbase.hash.type", "murmur"); 68 return parseHashType(name); 69 } 70 71 /** 72 * Get a singleton instance of hash function of a given type. 73 * @param type predefined hash type 74 * @return hash function instance, or null if type is invalid 75 */ 76 public static Hash getInstance(int type) { 77 switch(type) { 78 case JENKINS_HASH: 79 return JenkinsHash.getInstance(); 80 case MURMUR_HASH: 81 return MurmurHash.getInstance(); 82 case MURMUR_HASH3: 83 return MurmurHash3.getInstance(); 84 default: 85 return null; 86 } 87 } 88 89 /** 90 * Get a singleton instance of hash function of a type 91 * defined in the configuration. 92 * @param conf current configuration 93 * @return defined hash type, or null if type is invalid 94 */ 95 public static Hash getInstance(Configuration conf) { 96 int type = getHashType(conf); 97 return getInstance(type); 98 } 99 100 /** 101 * Calculate a hash using all bytes from the input argument, and 102 * a seed of -1. 103 * @param bytes input bytes 104 * @return hash value 105 */ 106 public int hash(byte[] bytes) { 107 return hash(bytes, bytes.length, -1); 108 } 109 110 /** 111 * Calculate a hash using all bytes from the input argument, 112 * and a provided seed value. 113 * @param bytes input bytes 114 * @param initval seed value 115 * @return hash value 116 */ 117 public int hash(byte[] bytes, int initval) { 118 return hash(bytes, 0, bytes.length, initval); 119 } 120 121 /** 122 * Calculate a hash using bytes from 0 to <code>length</code>, and 123 * the provided seed value 124 * @param bytes input bytes 125 * @param length length of the valid bytes after offset to consider 126 * @param initval seed value 127 * @return hash value 128 */ 129 public int hash(byte[] bytes, int length, int initval) { 130 return hash(bytes, 0, length, initval); 131 } 132 133 /** 134 * Calculate a hash using bytes from <code>offset</code> to <code>offset + 135 * length</code>, and the provided seed value. 136 * @param bytes input bytes 137 * @param offset the offset into the array to start consideration 138 * @param length length of the valid bytes after offset to consider 139 * @param initval seed value 140 * @return hash value 141 */ 142 public abstract int hash(byte[] bytes, int offset, int length, int initval); 143 }