/*
* Copyright 2014-2015 the original author or authors
*
* 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.
*/
// Created on 2014骞�鏈�2鏃�
// $Id$
package com.wplatform.ddal.dispatch.rule;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* @author <a href="mailto:jorgie.mail@gmail.com">jorgie li</a>
*/
public class KetamaHash {
private static final int NUM0 = 0;
private static final int NUM1 = 1;
private static final int NUM2 = 2;
private static final int NUM3 = 3;
private static final int NUM4 = 4;
private static final int NUM8 = 8;
private static final int NUM16 = 16;
private static final int NUM24 = 24;
private static final int NUM_0XFF = 0xFF;
private static byte[] computeMd5(String k) {
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.reset();
md5.update(k.getBytes("UTF-8"));
return md5.digest();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("MD5 not supported", e);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Unknown string :" + k, e);
}
}
public long calculate(Object paramObj) {
String paramValue = paramObj == null ? "null" : paramObj.toString();
long hashCode = HashAlgorithm.KETAMA_HASH.hash(computeMd5(paramValue), 0);
return hashCode;
}
private enum HashAlgorithm {
/**
* MD5-based hash algorithm used by ketama.
*/
KETAMA_HASH;
public long hash(byte[] digest, int nTime) {
long rv = ((long) (digest[NUM3 + nTime * NUM4] & NUM_0XFF) << NUM24)
| ((long) (digest[NUM2 + nTime * NUM4] & NUM_0XFF) << NUM16)
| ((long) (digest[NUM1 + nTime * NUM4] & NUM_0XFF) << NUM8)
| (digest[NUM0 + nTime * NUM4] & NUM_0XFF);
return rv & 0xffffffffL; /* Truncate to 32-bits */
}
}
}