/**
* Copyright 2010 Sematext International
*
* Licensed 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.navercorp.pinpoint.common.hbase.distributor;
import com.navercorp.pinpoint.common.util.MathUtils;
import com.sematext.hbase.wd.RowKeyDistributorByHashPrefix;
import java.util.Arrays;
/**
* Provides handy methods to distribute
*
* pinpoint copy and modify : https://github.com/sematext/HBaseWD/blob/master/src/main/java/com/sematext/hbase/wd/RowKeyDistributorByHashPrefix.java
* @author Alex Baranau
* @author emeroad
*/
public class RangeOneByteSimpleHash implements RowKeyDistributorByHashPrefix.Hasher {
protected final int start;
protected final int end;
private int mod;
// Used to minimize # of created object instances
// Should not be changed. TODO: secure that
private static final byte[][] PREFIXES;
static {
PREFIXES = new byte[256][];
for (int i = 0; i < 256; i++) {
PREFIXES[i] = new byte[] {(byte) i};
}
}
public RangeOneByteSimpleHash(int start, int end, int maxBuckets) {
if (maxBuckets < 1 || maxBuckets > 256) {
throw new IllegalArgumentException("maxBuckets should be in 1..256 range");
}
this.start = start;
this.end = end;
// i.e. "real" maxBuckets value = maxBuckets or maxBuckets-1
this.mod = maxBuckets;
}
@Override
public byte[] getHashPrefix(byte[] originalKey) {
long hash = MathUtils.fastAbs(hashBytes(originalKey));
return new byte[] {(byte) (hash % mod)};
}
/** Compute hash for binary data. */
private int hashBytes(byte[] bytes) {
int min = Math.min(bytes.length, end);
int hash = 1;
for (int i = start; i < min; i++)
hash = (31 * hash) + (int) bytes[i];
return hash;
}
@Override
public byte[][] getAllPossiblePrefixes() {
return Arrays.copyOfRange(PREFIXES, 0, mod);
}
@Override
public int getPrefixLength(byte[] adjustedKey) {
return 1;
}
@Override
public String getParamsToStore() {
return String.valueOf(mod);
}
@Override
public void init(String storedParams) {
this.mod = Integer.parseInt(storedParams);
}
protected final int getMod() {
return this.mod;
}
}